c++类的初始化(汇编分析)

 今有c++程序:

class CA
{
public:
 CA(int n1=0):_n1(n1){}
 virtual void vf1(){}
private:
 int _n1;
};

class CAsub:CA
{
public:
 CAsub(int n1=0,int n2=1):CA(n1),_n2(n2){}
 virtual void vf1(){}
 virtual void vf2(){}
private:
 int _n2;
};

int main(int argc, char* argv[])
{
 CAsub casub;//此处设断点跟入, goto 分析1:
 casub->vf1();//此处设断点跟入, goto 分析2:
 CAsub *pcasub=new CAsub;
 pcasub->vf1();//此处设断点跟入, goto 分析3
 pcasub->vf2();//此处设断点跟入, goto 分析3
 return 0;
}
vc6.0反汇编如下(各种编译器细节可能不一样,但方法应该都是类似的):

==================================================分析1:(构造函数分析)
...//main函数
00401068   push        1  ;从右到左压入参数,传说中的__stdcall方式?
0040106A   push        0 
0040106C   lea         ecx,[ebp-0Ch] ;传说中的this指针
0040106F   call        @ILT+10(CAsub::CAsub) (0040100f) ;调用构造函数
...
...//CAsub的构造函数
004010A0   push        ebp
004010A1   mov         ebp,esp
004010A3   sub         esp,44h
004010A6   push        ebx
004010A7   push        esi
004010A8   push        edi
004010A9   push        ecx
004010AA   lea         edi,[ebp-44h]
004010AD   mov         ecx,11h
004010B2   mov         eax,0CCCCCCCCh
004010B7   rep stos    dword ptr [edi]
//以上部分的分析见前一篇文章

004010B9   pop         ecx
004010BA   mov         dword ptr [ebp-4],ecx ;this指针被存放到栈内临时区的第一个位置

004010BD   mov         eax,dword ptr [ebp+8] ;取参数n1,注意在ebp与n1间还有一个四字节返回地址
004010C0   push        eax
004010C1   mov         ecx,dword ptr [ebp-4]
004010C4   call        @ILT+25(CA::CA) (0040101e) ;n1再次压入堆栈,调用基类CA的构造函数(this指针相同)


004010C9   mov         ecx,dword ptr [ebp-4]
004010CC   mov         edx,dword ptr [ebp+0Ch] ;取参数n2
004010CF   mov         dword ptr [ecx+8],edx ;初始化casub的n2参数(因为虚函数表指针占用了开头的4字节,所以是this+8)

004010D2   mov         eax,dword ptr [ebp-4]
004010D5   mov         dword ptr [eax],offset CAsub::`vftable' (0041f01c) ;初始话虚函数表指针

//以下部分没有分析价值
004010DB   mov         eax,dword ptr [ebp-4]
004010DE   pop         edi
004010DF   pop         esi
004010E0   pop         ebx
004010E1   add         esp,44h
004010E4   cmp         ebp,esp
004010E6   call        __chkesp (004011f0)
004010EB   mov         esp,ebp
004010ED   pop         ebp
004010EE   ret         8
...

==================================================分析2:(类对象如何调用虚拟函数)
;       casub.vf1();
00401089   lea         ecx,[ebp-18h]
0040108C   call        @ILT+15(CAsub::vf1) (00401014)
//由上面的汇编代码看出,并没有什么动态绑定,编译器直接调用了类CAsub的vf1函数地址


==================================================分析3:(类指针对象如何调用虚拟函数)
;       pcasub->vf1();
004010D6   mov         edx,dword ptr [ebp-1Ch] ;pacsub入edx
004010D9   mov         eax,dword ptr [edx] ;pacsub的虚函数表指针入eaxp[也即虚拟表的入口地址]
004010DB   mov         esi,esp   ;
004010DD   mov         ecx,dword ptr [ebp-1Ch] ;this指针(pacsub)
004010E0   call        dword ptr [eax]  ;此处解释为[eax+0],因为vf1在表中的第1项
...
;       pcasub->vf2();
004010D6   mov         edx,dword ptr [ebp-1Ch]
004010D9   mov         eax,dword ptr [edx]
004010DB   mov         esi,esp
004010DD   mov         ecx,dword ptr [ebp-1Ch]
004010E0   call        dword ptr [eax+4] ;vf2在表中的第2项 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值