一些隐藏的临时对象
I 当类对象传参时//////////////////////////////////////////////////////////////////////////
//源码
//////////////////////////////////////////////////////////////////////////
class Test
{
public:
int m_nData;
int m_test;
public:
Test(int nData):m_nData(nData){}
~Test(){;}
public:
void SetData(Test ttp)
{
m_nData = ttp.m_nData;
}
};
void SetData(Test ttp)
{
;
}
int main(int argc, char* argv[])
{
// printf("Hello World!\n");
Test tt(10);
tt.SetData(20);
return 0;
}
//////////////////////////////////////////////////////////////////////////
//简单分析
//////////////////////////////////////////////////////////////////////////
29: Test tt(10);
004010DD push 0Ah
004010DF lea ecx,
004010E2 call @ILT+0(Test::Test) (00401005)
004010E7 mov dword ptr ,0
30: tt.SetData(20);
004010EE sub esp,8 // 申请空间
004010F1 mov ecx,esp
004010F3 mov dword ptr ,esp
004010F6 push 14h
004010F8 call @ILT+0(Test::Test) (00401005) // 在这里 retn 4 只是弹出 push 14
004010FD mov dword ptr ,eax
00401100 lea ecx,
00401103 call @ILT+5(Test::SetData) (0040100a) // 所以该函数中 ebp+8 就是tempobj的this指针
31: return 0;
00401108 mov dword ptr ,0
0040110F mov dword ptr ,0FFFFFFFFh
00401116 lea ecx,
00401119 call @ILT+10(Test::~Test) (0040100f)
0040111E mov eax,dword ptr
32: }
15: void SetData(Test ttp)
16: {
004011BA mov dword ptr ,ecx
17: m_nData = ttp.m_nData;
004011BD mov eax,dword ptr
004011C0 mov ecx,dword ptr // 临时对象地址
004011C3 mov dword ptr ,ecx
18: }
004011C5 lea ecx,
004011C8 call @ILT+10(Test::~Test) (0040100f)// 给与析构
}
当参数为对象时,先 sub esp,sizeof(obj) 申请出空间,然后进行构造再调用函数。
构造退出时,ESP既是对象的this指针,函数内ESP+8即可对临时变量进行寻址。
临时对象出函数作用域时进行析构。 38: tt = GetData(30);
0040E9E8 push 1Eh
0040E9EA lea eax, // 把返回对象的地址压入堆栈
0040E9ED push eax
0040E9EE call @ILT+30(GetData) (00401023) //
0040E9F3 add esp,8
0040E9F6 mov dword ptr ,eax // 返回的临时对象
0040E9F9 mov ecx,dword ptr // 开始按位COPY
0040E9FC mov edx,dword ptr
0040E9FE mov eax,dword ptr
0040EA01 mov dword ptr ,edx
0040EA04 mov dword ptr ,eax // Copy 函数结束
0040EA07 lea ecx,
0040EA0A call @ILT+10(Test::~Test) (0040100f)
// 编译器的编译原则(申请空间)
// 把函数当返回值来看待 以决定该变量所需要的空间
// 若返回值为对象 则压入的参数个数 + 1
call @ILT+30(GetData) (00401023)
{
29: Test temp(nData);
004010E4 mov eax,dword ptr
004010E7 push eax
004010E8 lea ecx, // 局部变量的空间
004010EB call @ILT+0(Test::Test) (00401005)
30: return temp;
004010F0 mov ecx,dword ptr // 参数
004010F3 mov edx,dword ptr // 赋值(续表)
004010F6 mov dword ptr ,edx // 赋值(m_nData)
004010F8 mov eax,dword ptr
004010FB mov dword ptr ,eax
004010FE mov ecx,dword ptr
00401101 or ecx,1
00401104 mov dword ptr ,ecx
00401107 lea ecx,
0040110A call @ILT+10(Test::~Test) (0040100f) // 赋值OVER后 析构掉函数内部的局部对象)
0040110F mov eax,dword ptr
31: }
页:
[1]