设为首页 加入收藏

TOP

C++类机制的实现细节(三)
2013-04-10 11:54:10 来源: 作者: 【 】 浏览:733
Tags:机制 实现 细节

 

  0040107D  lea     ecx,[ebp-10h] file://这是用来保存aTest的this指针,因为是局部变量所以是保存在[ebp-10h]中

  00401080  call    @ILT+30(CTest::CTest) (00401023) file://调用aTest的构造函数,由编译器自动产生的CALL

  00401085  mov     dword ptr [ebp-4],0

  10:    aTest.a(1,2);

  0040108C  push    2

  0040108E  push    1

  00401090  lea     ecx,[ebp-10h] file://把aTest的this指针用ecx进行传递

  00401093  call    @ILT+5(CTest::a) (0040100a)

  11:    return 0;

  00401098  mov     dword ptr [ebp-14h],0

  0040109F  mov     dword ptr [ebp-4],0FFFFFFFFh

  004010A6  lea     ecx,[ebp-10h] file://同样是this指针

  004010A9  call    @ILT+25(CTest::~CTest) (0040101e) file://aTest的生存周期到了,自动调用析构函数,同样是由编译器分析之后自加上去

  004010AE  mov     eax,dword ptr [ebp-14h]

  12:  }

  004010B1  mov     ecx,dword ptr [ebp-0Ch]

  004010B4  mov     dword ptr fs:[0],ecx

  004010BB  pop     edi

  004010BC  pop     esi

  004010BD  pop     ebx

  004010BE  add     esp,54h

  004010C1  cmp     ebp,esp

  004010C3  call    __chkesp (00401670)

  004010C8  mov     esp,ebp

  004010CA  pop     ebp

  004010CB  ret

  下面再来分析一下VC中对函数的调用:

  可以看到上面有对三个函数的调用分别为:

  00401080  call    @ILT+30(CTest::CTest) (00401023)

  00401093  call    @ILT+5(CTest::a) (0040100a)

  004010A9  call    @ILT+25(CTest::~CTest) (0040101e)

  可以看到他们都跳到了以@ILT为基的一个地址去了,那么跳过去之后可以看到:

  @ILT+0( _GCTest@@UAEPAXI@Z):

  00401005  jmp     CTest::`scalar deleting destructor (00401130)

  @ILT+5( a@CTest@@QAEXHH@Z):

  0040100A  jmp     CTest::a (00401230)

  @ILT+10(_main):

  0040100F  jmp     main (00401050)

  @ILT+15( b@CTest@@QAEXXZ):

  00401014  jmp     CTest::b (004011e0)

  @ILT+20( _GCTest@@UAEPAXI@Z):

  00401019  jmp     CTest::`scalar deleting destructor (00401130)

  @ILT+25( 1CTest@@UAE@XZ):

  0040101E  jmp     CTest::~CTest (004011a0)

  @ILT+30( 0CTest@@QAE@XZ):

  00401023  jmp     CTest::CTest (004010f0)

  这个@ILT其实就是一个静态的表,它记录了一些函数的入口然后跳过去,每个跳转jmp占一个字节,然后就是一个四字节的内存地址,所以加起为五个字节,这样就实现了类的机制。

  下面再来分析一下,类的成员函数调用另一成员函数的情况:

  27:  void CTest::a(int one,int two)

  28:  {

  00401230  push    ebp

  00401231  mov     ebp,esp

  00401233  sub     esp,44h

  00401236  push    ebx

  00401237  push    esi

  00401238  push    edi

  00401239  push    ecx

  0040123A  lea     edi,[ebp-44h]

  0040123D  mov     ecx,11h

  00401242  mov     eax,0CCCCCCCCh

  00401247  rep stos  dword ptr [edi]

  00401249  pop     ecx

  0040124A  mov     dword ptr [ebp-4],ecx

  29:    printf("call b");

  0040124D  push    offset string "call b" (00422038)

  00401252  call    printf (00401830)

  00401257  add     esp,4

  30:    b();

  0040125A  mov     ecx,dword ptr [ebp-4] file://不要想这里的[ebp-4]肯定是this指针,

  0040125D  call    @ILT+15(CTest::b) (00401014) // 又是@ILT静态表格

  31:  }

  00401262  pop     edi

  00401263  pop     esi

  00401264  pop     ebx

  00401265  add     esp,44h

  00401268  cmp     ebp,esp

  0040126A  call    __chkesp (00401670)

  0040126F  mov     esp,ebp

  00401271  pop     ebp

  00401272  ret     8   file://由于是STDCALLR所以栈是由程序自己来平衡的

      

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇求字符串的长度并返回 下一篇逆向角度看C++的析构函数

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: