函数返回值如何传递

来源:互联网 发布:Pusic大数据工程师 编辑:程序博客网 时间:2024/05/19 19:44

一般情况下,函数返回值是通过eax进行传递的,但是eax只能存储4个字节的信息,对于那些返回值大于4个字节的函数,返回值是如何传递的呢?

假设返回值大小为M字节

1. M <= 4字节,放入eax返回

2. 4 < M <=8,把eax,edx联合起来,其中,edx存储高位,eax存储低位

3. M > 8,如何传递呢?

 

测试代码:

//test.cpp

 

如上,test()函数的返回值大小为64字节,那它是如何将这个大小的返回值传递给函数调用者的呢?

 

g++ -S test.cpp

 

查看汇编代码,如下:

 

其中:符号_Z4testv,用c++filt查看可知为test()。

先看看main函数的汇编代码:

pushl   %ecx         //将ecx的值压栈

subl    $68, %esp  //栈中分配68字节的空间,可以将这个空间看成两部分,一部分64字节是为变量n分配的空间,另一部分暂不考虑

 

此时main函数栈的情况如下:

leal    -68(%ebp), %eax        //将%ebp - 68字节处的值传到eax中,也就是4(%esp)处,也就是变量n的起始地址

movl    %eax, (%esp)            //将eax值,也就是变量n的起始地址,放入栈的%esp处,也就是上面分配的68字节空间的第二部分

call    _Z4testv                   //调用函数 test()

 

看看函数test的汇编代码:

subl    $64, %esp           //为变量big分配64字节的空间

movl    8(%ebp), %eax        //将%ebp + 8 字节处的值,也就是main函数中分配的68字节的第二部分的值,

                                                 也就是main中变量n的起始地址的值,存入eax中

movb    $99, 1(%eax)          //将99也就是'c'的ascii值放入%eax + 1字节处,而刚才说了eax中的值是变量n的其实地址,

                                                  所以这一步就相当于直接改变了变量n的值,从而实现了函数test的返回值到调用函数的传递。

 

 

如果将代码test.cpp中的:

big_thing n = test();

改成:

test();

汇编代码有什么变化,在main函数的栈中还会为test函数的返回值准备空间吗,但是现在main函数现在并不想接受test的返回值呀~

 

比较一下汇编代码你就知道啦,呵呵

(汇编代码没有任何变化,编译器还是在main的栈中为其分配了空间)

原创粉丝点击