好久没来了,准备毕业、毕业答辩、毕业、找工作、现在终于稳定下来。突然想到一个问题,随便测试下写写,不要拍砖哈
编译器:VC2005 Release模式,代码不优化
调试器: OllyDBG 1.10
程序如下:
class A
{
public:
A();
~A();
int a;
long b;
};
class B
{
public:
B();
~B();
int a;
long b;
};
A::A() : a(0)
,b(-1)
{
}
A::~A()
{
}
B::B()
{
a = 1;
b = -2;
}
B::~B()
{
}
int main()
{
__asm
{
push eax //加些标记,方便辨认
add esp,4
}
A a;
__asm
{
push ebx //加些标记,方便辨认
push ebx
add esp,8
}
B b;
return 0;
}
对应的汇编及分析如下:
对应的汇编及分析如下:
对应的汇编及分析如下:
//类A的构造函数
00401000 /$ 55 push ebp //将当前栈基址压栈保存
00401001 |. 8BEC mov ebp, esp //将当前栈指针作为栈基址
00401003 |. 51 push ecx //this指针压栈
00401004 |. 894D FC mov dword ptr [ebp-4], ecx //保存this指针
00401007 |. 8B45 FC mov eax, dword ptr [ebp-4] //this指针放入eax
0040100A |. C700 00000000 mov dword ptr [eax], 0 //this指针指向的地址存入0,也就是变量a,对应语句*(int*)this=0;
00401010 |. 8B4D FC mov ecx, dword ptr [ebp-4] //this指针放入ecx(多余的一步)
00401013 |. C741 04 FFFFF>mov dword ptr [ecx+4], -1 //this指针指向的地址存入-1,也就是变量b,对应语句*(int*)(this+4)=-1;
0040101A |. 8B45 FC mov eax, dword ptr [ebp-4] //返回值放入eax
0040101D |. 8BE5 mov esp, ebp //还原先前的esp、ebp
0040101F |. 5D pop ebp
00401020 \. C3 retn
//中间代码省略
//类B的构造函数,和a的一模一样
00401030 /$ 55 push ebp
00401031 |. 8BEC mov ebp, esp
00401033 |. 51 push ecx
00401034 |. 894D FC mov dword ptr [ebp-4], ecx
00401037 |. 8B45 FC mov eax, dword ptr [ebp-4]
0040103A |. C700 01000000 mov dword ptr [eax], 1
00401040 |. 8B4D FC mov ecx, dword ptr [ebp-4]
00401043 |. C741 04 FEFFF>mov dword ptr [ecx+4], -2
0040104A |. 8B45 FC mov eax, dword ptr [ebp-4]
0040104D |. 8BE5 mov esp, ebp
0040104F |. 5D pop ebp
00401050 \. C3 retn
//中间代码省略
//2个类公用一个析构函数
00401060 /$ 55 push ebp
00401061 |. 8BEC mov ebp, esp
00401063 |. 51 push ecx
00401064 |. 894D FC mov dword ptr [ebp-4], ecx
00401067 |. 8BE5 mov esp, ebp
00401069 |. 5D pop ebp
0040106A \. C3 retn
//中间代码省略
//main()函数
00401070 /$ 55 push ebp
00401071 |. 8BEC mov ebp, esp
00401073 |. 83EC 14 sub esp, 14 //给变量分配20字节空间
00401076 |. 50 push eax //刚才的代码标记
00401077 |. 83C4 04 add esp, 4 //刚才的代码标记
0040107A |. 8D4D F8 lea ecx, dword ptr [ebp-8] //thiscall调用约定,this指针通过ecx传递
0040107D |. E8 7EFFFFFF call 00401000 //调用A构造函数
00401082 |. 53 push ebx //刚才的代码标记
00401083 |. 53 push ebx //刚才的代码标记
00401084 |. 83C4 08 add esp, 8 //刚才的代码标记
00401087 |. 8D4D F0 lea ecx, dword ptr [ebp-10] //thiscall调用约定,this指针通过ecx传递
0040108A |. E8 A1FFFFFF call 00401030 //调用B构造函数
0040108F |. C745 EC 00000>mov dword ptr [ebp-14], 0 //函数返回值预先存储好
00401096 |. 8D4D F0 lea ecx, dword ptr [ebp-10]
00401099 |. E8 C2FFFFFF call 00401060 //调用B析构函数
0040109E |. 8D4D F8 lea ecx, dword ptr [ebp-8]
004010A1 |. E8 BAFFFFFF call 00401060 //调用A析构函数
004010A6 |. 8B45 EC mov eax, dword ptr [ebp-14] //返回值最后放入eax
004010A9 |. 8BE5 mov esp, ebp
004010AB |. 5D pop ebp
004010AC \. C3 retn
由此可见,成员变量放在初始化列表和构造函数体内,汇编代码是一样的,也就是不管放在那里,是没有差别的
posted on 2008-08-07 16:09
greatws 阅读(2700)
评论(12) 编辑 收藏 引用