c++虛擬函式表彙編及記憶體佈局分析(四)
阿新 • • 發佈:2021-10-14
#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) 直接呼叫函式地址