1. 程式人生 > 其它 >c++虛擬函式表彙編及記憶體佈局分析(四)

c++虛擬函式表彙編及記憶體佈局分析(四)

#include <iostream>

class Base
{
public:
    virtual int ShowFunc(int param)
    {
        std::cout << "Base ShowFunc: " << param << std::endl;
        return param;
    }
    int b;
};

class Derive: public Base
{
public:
    int ShowFunc(int param)
    {
        std::cout 
<< "Derive ShowFunc: " << param << std::endl; return param; } int d; }; int main() { Base b1; 變數地址008bf88c b1.ShowFunc(1); Base* b2 = new Derive(); b2變數地址0086f880,儲存內容(指標指向)00e51f90 b2->ShowFunc(2); Derive d1; d1.ShowFunc(3); std::cout << sizeof
(Base) << " " << sizeof(Derive) << std::endl; // 1個int和1個虛擬函式表 2個int和1個虛擬函式表 } /* class Derive size(12): +--- 0 | +--- (base class Base) 0 | | {vfptr} 虛擬函式表,地址為 4 | | b | +--- 8 | d +--- Derive::$vftable@: | &Derive_meta | 0 0 | &Derive::ShowFunc 虛擬函式表中儲存的是子類函式
*/
Base b1;
009E281F  lea         ecx,[b1]  
009E2822  call        Base::Base (09E1307h)  
    b1.ShowFunc(1);
009E2827  push        1  
009E2829  lea         ecx,[b1]  
009E282C  call        Base::ShowFunc (09E14F1h)  直接呼叫函式地址
    Base* b2 = new Derive();
009E2831  push        0Ch  
009E2833  call        operator new (09E1140h)  
009E2838  add         esp,4  
009E283B  mov         dword ptr [ebp-0FCh],eax  
009E2841  cmp         dword ptr [ebp-0FCh],0  
009E2848  je          __$EncStackInitStart+71h (09E286Dh)  
009E284A  xor         eax,eax  
009E284C  mov         ecx,dword ptr [ebp-0FCh]  
009E2852  mov         dword ptr [ecx],eax  
009E2854  mov         dword ptr [ecx+4],eax  
009E2857  mov         dword ptr [ecx+8],eax  
009E285A  mov         ecx,dword ptr [ebp-0FCh]  
009E2860  call        Derive::Derive (09E1221h)  
009E2865  mov         dword ptr [ebp-104h],eax  
009E286B  jmp         __$EncStackInitStart+7Bh (09E2877h)  
009E286D  mov         dword ptr [ebp-104h],0  
009E2877  mov         edx,dword ptr [ebp-104h]  
009E287D  mov         dword ptr [b2],edx  
    b2->ShowFunc(2);
009E2880  mov         esi,esp  
009E2882  push        2  
009E2884  mov         eax,dword ptr [b2]   eax變為00e51f90,b2變數內容(指標值)
009E2887  mov         edx,dword ptr [eax]  edx變為009e9c70(虛擬函式表儲存地址),即eax指向內容的第一個位元組(00e51f90指向內容第一個位元組)
009E2889  mov         ecx,dword ptr [b2]  
009E288C  mov         eax,dword ptr [edx]  edx(虛擬函式表儲存地址)指向內容的第一個位元組,即子類函式showFunc
009E288E  call        eax   呼叫虛擬函式showFunc
009E2890  cmp         esi,esp  
009E2892  call        __RTC_CheckEsp (09E12F3h)  
    Derive d1;
009E2897  lea         ecx,[d1]  
009E289A  call        Derive::Derive (09E1221h)  
    d1.ShowFunc(3);
009E289F  push        3  
009E28A1  lea         ecx,[d1]  
009E28A4  call        Derive::ShowFunc (09E14E7h)  直接呼叫函式地址