return语句的理解
来源:优易学  2011-12-9 10:26:57   【优易学:中国教育考试门户网】   资料下载   IT书店
  如果返回的是一个struct对象,return 语句会如何做呢?下面是测试代码
  #include <iostream>
  using namespace std;
  struct Big
  {
  char buf[100];
  int i;
  long d;
  }B,B2;
  Big bigfun(Big b)
  {
  b.i=100;
  return b;
  }
  int main()
  {
  B2=bigfun(B);
  return 0;
  }
  在main开头和结尾设断点
  8: int main()
  19: {
  004012A0 push ebp
  004012A1 mov ebp,esp
  004012A3 sub esp,118h
  //一开始对这迷惑不解,分析了好久
  //原来(118h-40h)剩下的内存块存放了两个Big的变量
  //低地址放Bigfun()函数返回值的临时变量
  //高地址放B2.operator=(Big &) 的参数
  004012A9 push ebx
  004012AA push esi
  004012AB push edi
  004012AC lea edi,[ebp-118h]
  004012B2 mov ecx,46h
  004012B7 mov eax,0CCCCCCCCh
  004012BC rep stos dword ptr [edi]
  20: B2=bigfun(B);
  004012BE sub esp,6Ch//b参数入栈
  004012C1 mov ecx,1Bh
  004012C6 mov esi,offset B (00438490)//B的首地址
  004012CB mov edi,esp
  004012CD rep movs dword ptr [edi],dword ptr [esi]//上面这些指令完成对b的初始化工作
  004012CF lea eax,[ebp-0D8h]//eax存放Big类型一个返回值临时变量的首地址
  004012D5 push eax//注意一般栈调用没有这条指令
  004012D6 call @ILT+0(bigfun) (00401005)
  /*
  004012DB add esp,70h
  004012DE mov esi,eax
  004012E0 mov ecx,1Bh
  004012E5 lea edi,[ebp-6Ch]
  004012E8 rep movs dword ptr [edi],dword ptr [esi]
  004012EA mov ecx,1Bh
  004012EF lea esi,[ebp-6Ch]
  004012F2 mov edi,offset B2 (00438500)
  004012F7 rep movs dword ptr [edi],dword ptr [esi]
  21:
  22: return 0;
  004012F9 xor eax,eax
  23:
  24: }
  004012FB pop edi
  004012FC pop esi
  004012FD pop ebx
  004012FE add esp,118h
  00401304 cmp ebp,esp
  00401306 call __chkesp (004081e0)
  0040130B mov esp,ebp
  0040130D pop ebp
  0040130E ret
  */
  @ILT+0(?bigfun@@YA?AUBig@@U1@@Z):
  00401005 jmp bigfun (00401250)
  11: Big bigfun(Big b)
  12: {
  00401250 push ebp
  00401251 mov ebp,esp
  00401253 sub esp,40h
  00401256 push ebx
  00401257 push esi
  00401258 push edi
  00401259 lea edi,[ebp-40h]
  0040125C mov ecx,10h
  00401261 mov eax,0CCCCCCCCh
  00401266 rep stos dword ptr [edi]
  13: b.i=100;
  00401268 mov dword ptr [ebp+70h],64h
  /*
  0012FE50 00 00 00 00 64 00 00 00 00 00 00 00
  */
  14: return b;
  0040126F mov ecx,1Bh
  00401274 lea esi,[ebp+0Ch]//esi=b的首地址
  00401277 mov edi,dword ptr [ebp+8]//edi=返回值临时变量的首地址
  0040127A rep movs dword ptr [edi],dword ptr [esi]
  0040127C mov eax,dword ptr [ebp+8]
  15: }
  0040127F pop edi
  00401280 pop esi
  00401281 pop ebx
  00401282 mov esp,ebp
  00401284 pop ebp
  00401285 ret
  返回到main函数
  004012DB add esp,70h//销毁局部参数
  004012DE mov esi,eax//bigfunction()返会值临时变量的首地址
  004012E0 mov ecx,1Bh
  004012E5 lea edi,[ebp-6Ch]//B2.operator=(Big &)参数的首地址
  004012E8 rep movs dword ptr [edi],dword ptr [esi]
  004012EA mov ecx,1Bh
  004012EF lea esi,[ebp-6Ch]
  004012F2 mov edi,offset B2 (00438500)//B2的首地址
  004012F7 rep movs dword ptr [edi],dword ptr [esi]
  21:
  22: return 0;
  004012F9 xor eax,eax
  23:
  24: }
  004012FB pop edi
  004012FC pop esi
  004012FD pop ebx
  004012FE add esp,118h
  00401304 cmp ebp,esp
  00401306 call __chkesp (004081e0)
  0040130B mov esp,ebp
  0040130D pop ebp
  0040130E ret
  总结:
  1.一般function frame的结构是
  函数内局部变量
  ebp
  eip
  函数参数
  如果返回值是一个struct对象function frame
  函数内局部变量
  ebp
  eip
  返回值临时变量的首地址//特别注意这个
  函数参数
  (由于寄存器太小,不可能放一块struct内存,所以保存了临时变量的首地址).
  2.struct对象的临时变量是在栈上的,而不是在堆上.

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训