读书人

C++基础解析三十五

发布时间: 2008-12-17 16:46:07 作者: liuhuituzi

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

  #include

  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对象的临时变量是在栈上的,而不是在堆上.

3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/

读书人网 >复习指导

热点推荐