C语言如何处理函数的返回值

描述

当你在函数的最后写上 return 0 的时候,它是如何返回给调用函数的?

比如 test 函数,为了待会更好的看懂汇编代码,我写成了 return 1234。

处理函数的返回值,是不是像我们理解的那样,直接把 1234 赋值给了变量 ret?

搞懂这个问题不难,只要看下汇编代码就行。

把代码编译一下,只编译不链接,得到的就是C对应的汇编代码。

这块是 test 函数,不用管上面这些代码,如果一行一行去分析,没有汇编基础的话确实会头疼。

看下这行代码,很明显,1234 就是我刚才写的返回值。所以 return 1234,其实就是把 1234 放到了寄存器 EAX 中。

EAX 是 X86 架构下的 32 位寄存器,在这个地方用于保存函数的返回值。

在回到主函数,通过 call 指令调用了 test 函数,紧接这就把 EAX 寄存器的值放到了 RBP 寄存器减 4 个字节的地址处,这个地址就是局部变量 ret 的地址。

所以这个过程非常简单,test 函数把返回值 1234 放到寄存器 EAX 中,主函数再从 EAX 把数据读到 ret 中。

把代码修改下,如果返回的是指针,指针占 8 个字节,汇编代码中也只是把 EAX 寄存器换成了 RAX 寄存器,这是一个 64 位的寄存器,刚好可以存放 8 个字节的指针。

不管函数返回什么类型,char short int long 或者指针,都可以通过这两个寄存器来完成。

于是又有了新的问题,如果返回结构体怎么办?结构体的大小可能远远超过 8 个字节。

之前我们也讲过这个问题,不同的编译器处理方法可能不一样。

比如我用的环境,调用函数之前,把局部变量 ret 的地址作为参数传给了 test 函数,实际上,我们在写代码的时候,test并没有参数。最终返回结构体,其实通过传进来的指针,把结构体的内容复制到了变量 ret 里面。
 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分