<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    注銷

    注銷

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      112 隨筆 :: 7 文章 :: 18 評論 :: 0 Trackbacks

    為了搞清楚VC中類的實現專門寫了一個最簡單的類,用來觀察它的實現過程,代碼如下:
    // test.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "CTest.h"

    int main(int argc, char* argv[])
    {
    CTest aTest;
    aTest.a(1,2);
    return 0;
    }

    // CTest.h: interface for the CTest class.
    //
    //////////////////////////////////////////////////////////////////////

    #if !defined(AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_)
    #define AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    class CTest 
    {
    public:
    CTest();
    virtual ~CTest();

    public:
    void b();
    void a(int one,int two);
    };

    #endif // !defined(AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_)


    // CTest.cpp: implementation of the CTest class.
    //
    //////////////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #include "CTest.h"

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    CTest::CTest()
    {

    }

    CTest::~CTest()
    {

    }

    void CTest::b()
    {
    printf("b is be called by a");
    }

    void CTest::a(int one,int two)
    {
    printf("call b");
    b();
    }




    下面是相應的反匯編代碼:
    --- D:\myown\test\test.cpp -----------------------------------------------------------------------------------------------
    1:  // test.cpp : Defines the entry point for the console application.
    2:  //
    3:
    4:  #include "stdafx.h"
    5:  #include "CTest.h"
    6:
    7:  int main(int argc, char* argv[])
    8:  {
    00401050  push    ebp
    00401051  mov     ebp,esp
    00401053  push    0FFh
    00401055  push    offset __ehhandler$_main (00410c89)
    0040105A  mov     eax,fs:[00000000]
    00401060  push    eax
    00401061  mov     dword ptr fs:[0],esp
    00401068  sub     esp,48h
    0040106B  push    ebx
    0040106C  push    esi
    0040106D  push    edi
    0040106E  lea     edi,[ebp-54h]
    00401071  mov     ecx,12h
    00401076  mov     eax,0CCCCCCCCh
    0040107B  rep stos  dword ptr [edi]

    9:    CTest aTest;
    0040107D  lea     ecx,[ebp-10h] //這是用來保存aTest的this指針,因為是局部變量所以是保存在[ebp-10h]中
    00401080  call    @ILT+30(CTest::CTest) (00401023) //調用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] //把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] //同樣是this指針
    004010A9  call    @ILT+25(CTest::~CTest) (0040101e) //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] //不要想這里的[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   //由于是STDCALLR所以棧是由程序自己來平衡的

    posted on 2006-11-19 10:14 注銷..... 閱讀(318) 評論(0)  編輯  收藏 所屬分類: c++
    主站蜘蛛池模板: 亚洲国产中文v高清在线观看| 午夜dj免费在线观看| 亚洲人成色777777在线观看| 一级毛片在线播放免费| 久久久久无码专区亚洲av| 色老头综合免费视频| 亚洲一区二区视频在线观看 | 亚洲AV无码乱码在线观看| 午夜亚洲国产精品福利| 亚洲黄片毛片在线观看| 国产无限免费观看黄网站| 在线观看亚洲成人| 免费精品一区二区三区第35| 亚洲成在人天堂在线| 国产2021精品视频免费播放| 国产精品亚洲午夜一区二区三区 | 亚洲熟女乱综合一区二区| 国产特黄特色的大片观看免费视频 | 精品久久亚洲一级α| 国产在线不卡免费播放| 国产精品极品美女自在线观看免费| 日韩成全视频观看免费观看高清| 美女裸体无遮挡免费视频网站| 亚洲熟女乱综合一区二区| 久久国产精品免费网站| 亚洲六月丁香六月婷婷蜜芽| 日韩免费一级毛片| 国产精品美女免费视频观看| 亚洲影院在线观看| 国产又大又黑又粗免费视频 | 91香蕉在线观看免费高清| 欧洲 亚洲 国产图片综合| 亚洲国产综合精品中文字幕| 免费毛片a线观看| 色老板亚洲视频免在线观| 亚洲国产精品一区二区九九 | 亚洲精品日韩中文字幕久久久| 成人片黄网站色大片免费| 国产精品一区二区三区免费| 亚洲最新中文字幕| 亚洲黄片手机免费观看|