函数返回值与栈

函数在定义时,必有其返回类型,返回类型可以为数值型(指针是表示地址的数值),void类型。函数只能返回一个值,数值形式可以是4字节的整型,浮点,8字节大小的long long,还可以返回结构体类型。虽然返回的都是数值,但是其中的返回机制不同。

函数的局部变量定义在栈中,栈的特点后进先出(LIFO)。局部变量所在的栈的高地址在下,低地址在上。从main开始,申请变量时栈顶指针向上移动,进入局部变量,局部变量的申请同在main函数中一样,一旦子函数执行完毕,则栈顶指针下移到进入局部变量时的位置,子函数所申请的局部变量空间都被回收。所以如果函数需要子函数中的一些值时,可以通过返回该数据来获得(用指针间接访问变量无需返回)。

1)讨论整型,浮点型,指针等4字节大小的数值。

以下一个函数来举例说明:

int add(int x,int y)

{

      int z=x+y;

      return z;

}

int main()

{

       int sum=add(3,4);

       return 0;

}

该函数返回部分的汇编代码:

return z;

001813F7 8B 45 F8             mov         eax,dword ptr [z] 

    return这一段中,可以看到z中计算好的数据移到eax寄存器中,由eax寄存器将值带给调用该函数的函数变量。

在返回这些类型时,系统将该函数所要返回的值移到寄存器中,栈顶指针下移,栈中的局部变量都死亡,寄存器中的数据再返回给调用该函数的函数所要接收的变量。

2)讨论longlong等8字节大小的数值。

    在32bit的编译环境中,eax寄存器一次性只能接受传递4字节大小的数据,而8字节的大小显然靠它一次性是不能完全拿到的。

代码为将上述的int改为long long类型。

函数返回部分的汇编代码:

return z;

000C1400 8B 45 F4             mov         eax,dword ptr [z]  

000C1403 8B 55 F8             mov         edx,dword ptr [ebp-8]  

    该函数的返回机制与4字节的相似,只是由两个寄存器来返回该值,其中将long long字节分为两部分移到eax和edx两个寄存器,通过这两个寄存器将函数值返回。

3)返回结构体类型的数据

    一个结构体变量中可以包含多个不同数据变量,其大小很容易超过8字节,如果靠多个寄存器来实现将值带回到调用函数中,很不现实。

函数举例:

typedef struct 

{

     ​int num;

     char name[19];

     char sex;

     float score;

}student;

student test()

{

      student stu;

      strcpy(stu.name,"xiaoming");

      stu.num=1001;

      stu.score=99.9;

      stu.sex='M';

      return stu;

}

int main()

{

    student su;

    su=test();

    return 0;

}

该函数的返回类型为student结构体类型,该类型的大小为28字节。

函数返回部分的汇编代码:

   return stu;

00DD3B81 B9 07 00 00 00       mov         ecx,7  

00DD3B86 8D 75 DC             lea         esi,[stu]  

00DD3B89 8B 7D 08             mov         edi,dword ptr [ebp+8]  

00DD3B8C F3 A5                rep movs    dword ptr es:[edi],dword ptr [esi]  

return stu;

00DD3B8E 8B 45 08             mov         eax,dword ptr [ebp+8]

在进入该子函数之前,系统在栈中为该函数留下一段内存,在函数返回该类型数据时,先是寄存器将其中的数据移到该段空间,子函数中的数据死亡,再由该段空间将值返回到调用函数的变量中。该方式的代价比较大,消耗了空间,并且在复制移值中也占用了cpu及寄存器等资源,所以指针间接访问来提高代码的效率。

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值