我对return 语句的理解----3

如果返回的是一个struct对象,return 语句会如何做呢?下面是测试代码

  1. #include <iostream>
  2. using namespace std;
  3. struct Big
  4. {
  5.     char buf[100];
  6.     int  i;
  7.     long d;
  8. }B,B2;
  9. Big bigfun(Big b)
  10. {
  11.     b.i=100;
  12.     return b;
  13. }
  14. int main()
  15. {   
  16.    B2=bigfun(B);
  17.     return 0;
  18.     
  19. }

在main开头和结尾设断点

  1. 8:   int main()
  2. 19:   {
  3. 004012A0   push        ebp
  4. 004012A1   mov         ebp,esp
  5. 004012A3   sub         esp,118h
  6. //一开始对这迷惑不解,分析了好久
  7. //原来(118h-40h)剩下的内存块存放了两个Big的变量
  8. //低地址放Bigfun()函数返回值的临时变量
  9. //高地址放B2.operator=(Big &) 的参数
  10. 004012A9   push        ebx
  11. 004012AA   push        esi
  12. 004012AB   push        edi
  13. 004012AC   lea         edi,[ebp-118h]
  14. 004012B2   mov         ecx,46h
  15. 004012B7   mov         eax,0CCCCCCCCh
  16. 004012BC   rep stos    dword ptr [edi]
  17. 20:      B2=bigfun(B);
  18. 004012BE   sub         esp,6Ch//b参数入栈
  19. 004012C1   mov         ecx,1Bh
  20. 004012C6   mov         esi,offset B (00438490)//B的首地址
  21. 004012CB   mov         edi,esp
  22. 004012CD   rep movs    dword ptr [edi],dword ptr [esi]//上面这些指令完成对b的初始化工作
  23. 004012CF   lea         eax,[ebp-0D8h]//eax存放Big类型一个返回值临时变量的首地址
  24. 004012D5   push        eax//注意一般栈调用没有这条指令
  25. 004012D6   call        @ILT+0(bigfun) (00401005)
  26. /*
  27. 004012DB   add         esp,70h
  28. 004012DE   mov         esi,eax
  29. 004012E0   mov         ecx,1Bh
  30. 004012E5   lea         edi,[ebp-6Ch]
  31. 004012E8   rep movs    dword ptr [edi],dword ptr [esi]
  32. 004012EA   mov         ecx,1Bh
  33. 004012EF   lea         esi,[ebp-6Ch]
  34. 004012F2   mov         edi,offset B2 (00438500)
  35. 004012F7   rep movs    dword ptr [edi],dword ptr [esi]
  36. 21:
  37. 22:       return 0;
  38. 004012F9   xor         eax,eax
  39. 23:
  40. 24:   }
  41. 004012FB   pop         edi
  42. 004012FC   pop         esi
  43. 004012FD   pop         ebx
  44. 004012FE   add         esp,118h
  45. 00401304   cmp         ebp,esp
  46. 00401306   call        __chkesp (004081e0)
  47. 0040130B   mov         esp,ebp
  48. 0040130D   pop         ebp
  49. 0040130E   ret
  50. */
  51. @ILT+0(?bigfun@@YA?AUBig@@U1 @@Z):
  52. 00401005   jmp         bigfun (00401250)
  53. 11:   Big bigfun(Big b)
  54. 12:   {
  55. 00401250   push        ebp
  56. 00401251   mov         ebp,esp
  57. 00401253   sub         esp,40h
  58. 00401256   push        ebx
  59. 00401257   push        esi
  60. 00401258   push        edi
  61. 00401259   lea         edi,[ebp-40h]
  62. 0040125C   mov         ecx,10h
  63. 00401261   mov         eax,0CCCCCCCCh
  64. 00401266   rep stos    dword ptr [edi]
  65. 13:       b.i=100;
  66. 00401268   mov         dword ptr [ebp+70h],64h
  67. /*
  68. 0012FE50  00 00 00 00 64 00 00 00 00 00 00 00 
  69. */
  70. 14:       return b;
  71. 0040126F   mov         ecx,1Bh
  72. 00401274   lea         esi,[ebp+0Ch]//esi=b的首地址
  73. 00401277   mov         edi,dword ptr [ebp+8]//edi=返回值临时变量的首地址
  74. 0040127A   rep movs    dword ptr [edi],dword ptr [esi]
  75. 0040127C   mov         eax,dword ptr [ebp+8]
  76. 15:   }
  77. 0040127F   pop         edi
  78. 00401280   pop         esi
  79. 00401281   pop         ebx
  80. 00401282   mov         esp,ebp
  81. 00401284   pop         ebp
  82. 00401285   ret
  83. 返回到main函数
  84. 004012DB   add         esp,70h//销毁局部参数
  85. 004012DE   mov         esi,eax//bigfunction()返会值临时变量的首地址
  86. 004012E0   mov         ecx,1Bh
  87. 004012E5   lea         edi,[ebp-6Ch]//B2.operator=(Big &)参数的首地址
  88. 004012E8   rep movs    dword ptr [edi],dword ptr [esi]
  89. 004012EA   mov         ecx,1Bh
  90. 004012EF   lea         esi,[ebp-6Ch]
  91. 004012F2   mov         edi,offset B2 (00438500)//B2的首地址
  92. 004012F7   rep movs    dword ptr [edi],dword ptr [esi]
  93. 21:
  94. 22:       return 0;
  95. 004012F9   xor         eax,eax
  96. 23:
  97. 24:   }
  98. 004012FB   pop         edi
  99. 004012FC   pop         esi
  100. 004012FD   pop         ebx
  101. 004012FE   add         esp,118h
  102. 00401304   cmp         ebp,esp
  103. 00401306   call        __chkesp (004081e0)
  104. 0040130B   mov         esp,ebp
  105. 0040130D   pop         ebp
  106. 0040130E   ret

 

总结:

1.一般function frame的结构是

                                                                  

                                                            函数内局部变量

                                                            ebp

                                                             eip

                                                           函数参数

 

如果返回值是一个struct对象function frame

                                                            

                                                              函数内局部变量

                                                              ebp

                                                              eip

                                                              返回值临时变量的首地址//特别注意这个

                                                              函数参数

(由于寄存器太小,不可能放一块struct内存,所以保存了临时变量的首地址).

 

2.struct对象的临时变量是在栈上的,而不是在堆上.

 

 

 

 

 

 

转载于:https://my.oschina.net/Draymond/blog/1017888

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值