go语言函数调用方式和栈分配
根据前面C语言函数的调用惯例,可知道参数较少时,函数使用寄存器传参,函数的返回值通过EAX寄存器返回(返回值较小时)。
而go语言不是这样的,go使用栈来进行参数传递和函数返回。在函数调用前,调用者已经分配好返回值和函数参数的内存空间,在函数执行过程中,最后的返回结果根据基准指针写入到返回值栈空间中,因此函数可以返回多个值。
C 语言和 Go 语言在设计函数的调用惯例时选择了不同的实现。C 语言同时使用寄存器和栈传递参数,使用 eax 寄存器传递返回值;而 Go 语言使用栈传递参数和返回值。我们可以对比一下这两种设计的优点和缺点:
- C 语言的方式能够极大地减少函数调用的额外开销,但是也增加了实现的复杂度;
(1) CPU 访问栈的开销比访问寄存器高几十倍3;
(2) 需要单独处理函数参数过多的情况; - Go 语言的方式能够降低实现的复杂度并支持多返回值,但是牺牲了函数调用的性能;
(1) 不需要考虑超过寄存器数量的参数应该如何传递;
(2) 不需要考虑不同架构上的寄存器差异;
(3) 函数入参和出参的内存空间需要在栈上进行分配;
go参数传递
go传递参数使用值传递,接收方收到参数时会对这些参数进行复制;了解到这一点之后,在传递数组或者内存占用非常大的结构体时,我们应该尽量使用指针作为参数类型来避免发生数据拷贝进而影响性能。
详细分析了 Go 语言的调用惯例,包括传递参数和返回值的过程和原理。Go 通过栈传递函数的参数和返回值,在调用函数之前会在栈上为返回值分配合适的内存空间,随后将入参从右到左按顺序压栈并拷贝参数,返回值会被存储到调用方预留好的栈空间上,我们可以简单总结出以下几条规则:
- 通过堆栈传递参数,入栈的顺序是从右到左,而参数的计算是从左到右;
- 函数返回值通过堆栈传递并由调用者预先分配内存空间;
- 调用函数时都是传值,接收方会对入参进行复制再计算;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术