c++ - Is vftable[0] stores the first virtual function or RTTI Complete Object Locator? -
it's known c++ use vftable dynamicly decide virtual function should called. , want find out mechanism behind when call virtual function. have compiled following code assembly.
using namespace std; class animal { int age; public: virtual void speak() {} virtual void wash() {} }; class cat : public animal { public: virtual void speak() {} virtual void wash() {} }; void main() { animal* animal = new cat; animal->speak(); animal->wash(); }
the assembly code massive. don't quite understand following part.
const segment ??_7cat@@6b@ dd flat:??_r4cat@@6b@ ; cat::`vftable' dd flat:?speak@cat@@uaexxz dd flat:?wash@cat@@uaexxz const ends
this part defines vftable of cat. have 3 entries. first entry rtti complete object locator. second cat::speak. third cat::wash. think vftable[0] should imply rtti complete object locator. when checking assembly code in main proc , cat::cat proc, invoke animal->speak()
implemented calling vftable[0], , invoke animal->wash()
implemented calling vftable[4]. why not vftable[4] , vftable[8]?
the assembly code of proc main , cat::cat shows below.
_text segment tv75 = -12 ; size = 4 $t1 = -8 ; size = 4 _animal$ = -4 ; size = 4 _main proc ; 23 : { push ebp mov ebp, esp sub esp, 12 ; 0000000ch ; 24 : animal* animal = new cat; push 8 call ??2@yapaxi@z ; operator new add esp, 4 mov dword ptr $t1[ebp], eax cmp dword ptr $t1[ebp], 0 je short $ln3@main mov ecx, dword ptr $t1[ebp] call ??0cat@@qae@xz mov dword ptr tv75[ebp], eax jmp short $ln4@main $ln3@main: mov dword ptr tv75[ebp], 0 $ln4@main: mov eax, dword ptr tv75[ebp] mov dword ptr _animal$[ebp], eax ; 25 : animal->speak(); mov ecx, dword ptr _animal$[ebp] mov edx, dword ptr [ecx] mov ecx, dword ptr _animal$[ebp] mov eax, dword ptr [edx] call eax ; 26 : animal->wash(); mov ecx, dword ptr _animal$[ebp] mov edx, dword ptr [ecx] mov ecx, dword ptr _animal$[ebp] mov eax, dword ptr [edx+4] call eax ; 27 : } xor eax, eax mov esp, ebp pop ebp ret 0 _main endp _text ends ; function compile flags: /odtp ; comdat ??0cat@@qae@xz _text segment _this$ = -4 ; size = 4 ??0cat@@qae@xz proc ; cat::cat, comdat ; _this$ = ecx push ebp mov ebp, esp push ecx mov dword ptr _this$[ebp], ecx mov ecx, dword ptr _this$[ebp] call ??0animal@@qae@xz mov eax, dword ptr _this$[ebp] mov dword ptr [eax], offset ??_7cat@@6b@ mov eax, dword ptr _this$[ebp] mov esp, ebp pop ebp ret 0 ??0cat@@qae@xz endp ; cat::cat _text ends
supplement: msvc compiler x86 19.00.23026
the layout of vtables implementation dependent. in particular case, when compiling example code, microsoft c++ compiler generates vtable cat
speak
virtual function @ offset 0, , wash
function @ offset 4. rtti information located before these functions @ offset -4.
the problem here microsoft's assembly output lying. generated assembly code puts rtti information @ offset 0 , speak
, wash
functions @ offset 4 , 8. not how it's laid out in object file compiler generates. disassembling object file reveals layout:
.new_section .rdata, "dr2" 0000 00 00 00 00 .long ??_r4cat@@6b@ 0004 ??_7cat@@6b@: 0004 00 00 00 00 .long ?speak@cat@@uaexxz 0008 00 00 00 00 .long ?wash@cat@@uaexxz
unfortunately assembly output of microsoft's c/c++ compiler meant informational. it's not accurate , complete representation of actual code compiler generates. in particular can't reliably assembled working object file.
Comments
Post a Comment