The Calling principle of member functions in C ++ and the transfer method of this pointer
Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie
Test source code:
1 # include
2 # include
3
4ClassCtestthispointer
5 {
6Public:
7 ctestthispointer (IntAI): MI (AI ){}
8IntAdd (IntAI)
9 {
10 MI + = AI;
11ReturnMi;
12}
13
14Private:
15IntMi;
16 };
17
18
19IntMain ()
20 {
21 ctestthispointer lotest (10 );
22
23 printf ("% d", lotest. Add (5 ));
24Return0;
25}
26
Disassembly:
. Text: 00401000; int _ cdecl main (INT argc, const char ** argv, const char * envp)
. Text: 00401000 _ main proc near; Code xref: _ maincrtstartup + AFP
. Text: 00401000
. Text: 00401000 this = byte PTR-4
. Text: 00401000 argc = dword ptr 8
. Text: 00401000 argv = dword ptr 0ch
. Text: 00401000 envp = dword ptr 10 h
. Text: 00401000
. Text: 00401000 push EBP; by default, we finally see an orthodox push EBP;
. Text: 00401000; MoV EBP, esp protection stack and EBP Process
. Text: 00401001 mov EBP, ESP
. Text: 00401003 push ECx
. Text: 00401004 push 0ah; the unique parameter of the constructor except this by default, 10
. Text: 00401006 Lea ECx, [EBP + This]; this pointer is passed through the ECX register.
. Text: 00401009 call ctestthispointer _ ctestthispointer
. Text: 0040100e Push 5; The add function is unique except the default this parameter, 5
. Text: 00401010 Lea ECx, [EBP + This]; this pointer
. Text: 00401013 call ctestthispointer _ add
. Text: 00401018 push eax; Add the return value of add to stack, call printf
. Text: 00401019 push offset ad; "% d"
. Text: 0040101e call _ printf
. Text: 00401023 add ESP, 8; Variable Length Parameter Function, can only be through _ cdecl call Convention Luo, by main
. Text: 00401023; function to maintain stack balance
. Text: 00401026 XOR eax, eax
. Text: 00401028 mov ESP, EBP
. Text: 0040102a pop EBP
. Text: 0040102b retn
. Text: 0040102b _ main endp
Constructor:
. Text: 00401030 ctestthispointer _ ctestthispointer proc near; Code xref: _ main + 9 p
. Text: 00401030
. Text: 00401030 var_4 = dword ptr-4
. Text: 00401030 arg_0 = dword ptr 8
. Text: 00401030
. Text: 00401030 push EBP
. Text: 00401031 mov EBP, ESP
. Text: 00401033 push ECx; save this pointer into the stack
. Text: 00401034 mov [EBP + var_4], ECx
. Text: 00401037 mov eax, [EBP + var_4]; pass the value of this to eax. By default, the optimized code is cumbersome. Next
. Text: 00401037; steps are all, in essence, nothing more than
. Text: 00401037; MoV [ECx], [EBP + arg_0] process, but because it cannot directly
. Text: 00401037; Memory mov to memory, so temporary variables are used in the middle,
. Text: 00401037; register as a temporary variable, so you must first save the register .....
. Text: 00401037; actually there are so many registers, why not? Because it is optimized by default
. Text: 0040103a mov ECx, [EBP + arg_0]
. Text: 0040103d mov [eax], ECx
. Text: 0040103f mov eax, [EBP + var_4]
. Text: 00401042 mov ESP, EBP
. Text: 00401044 pop EBP
. Text: 00401045 retn 4
. Text: 00401045 ctestthispointer _ ctestthispointer endp
Add function:
. Text: 00401050 ctestthispointer _ add proc near; Code xref: _ main + 13 p
. Text: 00401050
. Text: 00401050 var_4 = dword ptr-4
. Text: 00401050 arg_0 = dword ptr 8
. Text: 00401050
. Text: 00401050 push EBP
. Text: 00401051 mov EBP, ESP
. Text: 00401053 push ECx
. Text: 00401054 mov [EBP + var_4], ECx; the maximum fee for this temporary variable
. Text: 00401057 mov eax, [EBP + var_4]
. Text: 0040105a mov ECx, [eax]
. Text: 0040105c add ECx, [EBP + arg_0]; because the returned result is Mi, the following are honestly extracted from
. Text: 0040105c; Address to register, then retrieve the value in the form of mov re, [re]
. Text: 0040105c; BTW: I'm not used to seeing the code without optimization.
. Text: 0040105f mov edX, [EBP + var_4]
. Text: 00401062 mov [edX], ECx
. Text: 00401064 mov eax, [EBP + var_4]
. Text: 00401067 mov eax, [eax]
. Text: 00401069 mov ESP, EBP
. Text: 0040106b pop EBP
. Text: 004020.c retn 4
. Text: 00401_c ctestthispointer _ add endp
Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie