16,547
社区成员




class CReturn
{
public:
int m_nNumber;
};
CReturn GetReturn()
{
CReturn RetObj;
RetObj.m_nNumber = 0;
return RetObj;
}
int main(int argc, char* argv[])
{
CReturn objA;
objA = GetReturn();
return 0;
}
29: CReturn objA;
30: objA = GetReturn();
004010BE lea eax,[ebp-84h] // 返回对象的栈空间首地址
004010C4 push eax // 将返回对象的首地址压入栈中,用于保存返回对象的数据
004010C5 call @ILT+0(GetReturn) (00401005)
004010CA add esp,4
004010CD mov esi,eax // 取出返回对象首址
004010CF mov ecx,0Bh
004010D4 lea edi,[ebp-58h]
004010D7 rep movs dword ptr [edi],dword ptr [esi] // 将返回对象放入ebp-58h栈空间中
004010D9 mov ecx,0Bh
004010DE lea esi,[ebp-58h]
004010E1 lea edi,[ebp-2Ch] // ebp-2Ch即局变量objA的地址
004010E4 rep movs dword ptr [edi],dword ptr [esi]
31: return 0;
004010E6 xor eax,eax
16: CReturn RetObj;
17:
18: RetObj.m_nNumber = 0;
00401038 mov dword ptr [ebp-2Ch],0
19: for (int i = 0; i < 10; i++)
0040103F mov dword ptr [ebp-30h],0
00401046 jmp GetReturn+31h (00401051)
00401048 mov eax,dword ptr [ebp-30h]
0040104B add eax,1
0040104E mov dword ptr [ebp-30h],eax
00401051 cmp dword ptr [ebp-30h],0Ah
00401055 jge GetReturn+46h (00401066)
20: {
21: RetObj.m_nArray[i] = i + 1;
00401057 mov ecx,dword ptr [ebp-30h]
0040105A add ecx,1
0040105D mov edx,dword ptr [ebp-30h]
00401060 mov dword ptr [ebp+edx*4-28h],ecx
22: }
00401064 jmp GetReturn+28h (00401048)
23:
24: return RetObj;
00401066 mov ecx,0Bh
0040106B lea esi,[ebp-2Ch]
0040106E mov edi,dword ptr [ebp+8] // 这里的ebp+8即main函数中的ebp-84h
00401071 rep movs dword ptr [edi],dword ptr [esi]
00401073 mov eax,dword ptr [ebp+8] // 将返回对象首地址放入eax中
25: }
17: CReturn objA;
004011D3 lea ecx,[ebp-60h] // objA对象首地址
004011D6 call @ILT+0(CReturn::CReturn) (00401005) // 调用构造函数
004011DB mov dword ptr [ebp-4],0
18: objA = GetReturn();
004011E2 lea eax,[ebp-0B4h] // // 临时对象栈空间
004011E8 push eax
004011E9 call @ILT+5(GetReturn) (0040100a) // 调用GetReturn函数
004011EE add esp,4
004011F1 mov dword ptr [ebp-0BCh],eax // eax其实保存的就是临时对象首地址(ebp-0B4h)
004011F7 mov esi,dword ptr [ebp-0BCh] // 临时对象地址作为源
004011FD mov ecx,15h
00401202 lea edi,[ebp-60h] // objA对象地址作为目的地
00401205 rep movs dword ptr [edi],dword ptr [esi] // 拷贝即对象复制
00401207 lea ecx,[ebp-0B4h]
0040120D call @ILT+15(CReturn::~CReturn) (00401014) // 最后临时对象析构
49: __asm int 3
004010B8 int 3
50: CReturn objA;
51: objA = GetReturn();
004010B9 call @ILT+0(GetReturn) (00401005)
004010BE mov dword ptr [ebp-8],eax
004010C1 mov eax,dword ptr [ebp-8]
004010C4 mov dword ptr [ebp-4],eax
第6行到第8行,为什么搞得这么麻烦,把第6行到第8行换成mov dword ptr [ebp-4],eax(也就是去掉第6、7行)
不也可以么,干嘛要搞个ebp-8作为中转呢?class CReturn
{
public:
int m_nNumber;
};
CReturn GetReturn()
{
CReturn RetObj;
RetObj.m_nNumber = 0;
return RetObj;
}
int main(int argc, char* argv[])
{
__asm int 3
CReturn objA;
objA = GetReturn();
return 0;
}
编译为Release版,按F5,Alt+8,再看对应汇编。