In this article, I mainly explain the function calling principle in the class. The test code is as follows:
classCBase{public:voidHello(){}};int main(){CBasebase;base.Hello();}
Similarly, according to the methods described in the previous article, the main. ASM is compiled as follows:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLEE:\bossjue\main.cpp.686P.XMMinclude listing.inc.modelflatINCLUDELIB LIBCMTINCLUDELIB OLDNAMESPUBLIC?Hello@CBase@@QAEXXZ; CBase::HelloPUBLIC_main; Function compile flags: /Odtp_TEXTSEGMENT_base$ = -1; size = 1_mainPROC; File e:\bossjue\main.cpp; Line 7pushebpmovebp, esppushecx; Line 9leaecx, DWORD PTR _base$[ebp]call?Hello@CBase@@QAEXXZ; CBase::Hello; Line 10xoreax, eaxmovesp, ebppopebpret0_mainENDP; Function compile flags: /Odtp_TEXTENDS;COMDAT ?Hello@CBase@@QAEXXZ_TEXTSEGMENT_this$ = -4; size = 4?Hello@CBase@@QAEXXZ PROC; CBase::Hello, COMDAT; _this$ = ecx; Line 3pushebpmovebp, esppushecxmovDWORD PTR _this$[ebp], ecx; Line 4movesp, ebppopebpret0?Hello@CBase@@QAEXXZ ENDP; CBase::Hello_TEXTENDSEND
Compared with the non-class function calls in the Assembly above, you can see that there is only one more mov ECx, this operation (equivalent code ), it means to copy this to ECx and then call the function, so we can guess that, the C ++ class function call on vs uses ECx to pass the this pointer (which has no impact on the stack). We can write the following test code to see that the operation is successful:
#include <iostream>using namespace std;classCBase{public:CBase(int iValue):m_iValue(iValue){}public:voidHello(){cout<<m_iValue<<endl;}private:intm_iValue;};int main(){CBasebase(100);typedef void(CBase::*FunPtr)();FunPtrFunAddr=&CBase::Hello;__asm{leaecx, basecallFunAddr}}
However, if we remove Lea ECx and base, we will see a running error, indicating that vs uses ECx to pass this pointer. So, we can think that since vs uses ECx to pass this pointer, we can use the member functions of the class as the thread function, but make ECx equal to this at an appropriate time, right, the question is, when is this appropriate? How can we let ECx pass this? This is what we will talk about in the next section.