Implementation details of C ++ class mechanism

zhaozj2021-02-16  58

In order to understand the implementation of the Class of VC, it is specifically written to observe its implementation process, the code is as follows: // Test.cpp: Defines the entry point for the console application.//#include "stdafx. H "#include" ctest.h "int main (int Argc, char * argv []) {ctest is (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> 1000class 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! "/// castruction / destruction // ctest :: ctest () {} ctest :: ~ ctest () {} void ctest :: b () {Printf (" b is be caled by a ");} void ctest :: A (int one, int two) {printf ("call b"); b ();} The following is the corresponding disassembly code: --- 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 ebp00401051 mov ebp, esp00401053 push 0FFh00401055 push offset __ehhandler $ _main (00410c89) 0040105A mov eax, fs: [00000000] 00401060 push eax00401061 mov dword ptr fs: [0], esp00401068 sub esp, 48h0040106B push ebx0040106C push esi0040106D push edi0040106E lea edi, [ebp-54h] 00401071 mov ecx, 12h00401076 mov eax, 0CCCCCCCCh0040107B rep stos dword ptr [edi] 9: CTest aTest;

0040107D LEA ECX, [EBP-10H] // This is used to save the THIS pointer of the ATEST, because it is a local variable so it is saved in [EBP-10H] 00401080 Call @ ilt 30 (ctest :: ctest) (00401023) // Call the constructor of the ATEST, Call00401085 MOV DWORD PTR [EBP-4], 010: Ateest.a (1, 2); 0040108C Push 20040108E Push 100401090 Lea ECX, [EBP-10H] // Transfer of the THIS pointer of the ATEST 00401093 Call @ ilt 5 (ctest :: a) (0040100A) 11: Return 0; 00401098 MOV DWORD PTR [EBP-14H], 00040109F MOV DWORD PTR [EBP-4], 0FFFFFFFH004010A6 LEA ECX, [EBP-10H] // The same is this pointer 004010A9 Call @ ilt 25 (ctest :: ~ ctest) (0040101e) // ATEST survival period, automatic call destructor, etc., the same is analyzed by compiler after the self-coupled to 004010AE mov eax, dword ptr [ebp-14h] 12:} 004010B1 mov ecx, dword ptr [ebp-0Ch] 004010B4 mov dword ptr fs: [0], ecx004010BB pop edi004010BC pop esi004010BD pop ebx004010BE add esp, 54h004010C1 CMP EBP, ESP004010C3 CALL __CHKESP (00401670) 004010C8 MOV ESP, EBP004010CA POP EBP004010CB RET The following is then analyzes the call to the function in the VC: It can be seen that the call to the three functions is: 00401080 Call @ ilt 30 (CTest :: ctest) (0) 0401023) 00401093 Call @ ilt 5 (ctest :: a) 004010A9 Call @ ilt 25 (ctest :: ~ ctest) (0040101e) You can see that they have jumped to an address based on @ilt. After skipping, you can see: @ 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 @@ qte :: b (004011e0) @ ILT 20 (?? _ gctest @@ uaepaxi @ z): 00401019 JMP ctest :: `scalar deleting destructor '(00401130) @ ilt 25 (?? 1ctest @@

转载请注明原文地址:https://www.9cbs.com/read-23296.html

New Post(0)