//源代码
#include <cstdio>
#include <cstdlib>
class TA{
public:
void show()
{
printf("%d \r\n",m_id);
}
void callShow()
{
TA::show();
}
int m_id;
};
int main()
{
TA ta;
ta.m_id = 5;
ta.callShow();
ta.show();
system("pause");
return 0;
}
//反汇编后的代码
int main()
{
00411B10 push ebp
00411B11 mov ebp,esp
00411B13 sub esp,0CCh
00411B19 push ebx
00411B1A push esi
00411B1B push edi
00411B1C lea edi,[ebp-0CCh]
00411B22 mov ecx,33h
00411B27 mov eax,0CCCCCCCCh
00411B2C rep stos dword ptr es:[edi]
TA ta;
ta.m_id = 5;
00411B2E mov dword ptr [ta],5
ta.callShow();
00411B35 lea ecx,[ta]
00411B38 call TA::callShow (411019h)
ta.show();
00411B3D lea ecx,[ta]
00411B40 call TA::show (4110EBh)
system("pause");
00411B45 mov esi,esp
00411B47 push offset string "pause" (41573Ch)
00411B4C call dword ptr [__imp__system (4182C0h)]
00411B52 add esp,4
00411B55 cmp esi,esp
00411B57 call @ILT+320(__RTC_CheckEsp) (411145h)
return 0;
00411B5C xor eax,eax
}
//callShow()反汇编
void callShow()
{
00411490 push ebp
00411491 mov ebp,esp
00411493 sub esp,0CCh
00411499 push ebx
0041149A push esi
0041149B push edi
0041149C push ecx
0041149D lea edi,[ebp-0CCh]
004114A3 mov ecx,33h
004114A8 mov eax,0CCCCCCCCh
004114AD rep stos dword ptr es:[edi]
004114AF pop ecx
004114B0 mov dword ptr [ebp-8],ecx
TA::show();
004114B3 mov ecx,dword ptr [this] //这里是关键.
004114B6 call TA::show (4110EBh)
}
004114BB pop edi
004114BC pop esi
004114BD pop ebx
004114BE add esp,0CCh
004114C4 cmp ebp,esp
004114C6 call @ILT+320(__RTC_CheckEsp) (411145h)
004114CB mov esp,ebp
004114CD pop ebp
004114CE ret
总结:C++成员函数调用 即this call 调用约定
thiscall
它是C++类成员函数缺省的调用约定。
参数从右向左入栈
如果参数个数确定
也就是把类的实例,即对象的地址(或者说把this指针)通过ecx传递到调用函数,
调用的函数通过ecx取回this指针.
第一次调用时,取对象的实例ta的地址到ecx,然后调用TA::callShow
00411B35 lea ecx,[ta]
00411B38 call TA::callShow (411019h)
第二次调用时,直接把this指针传递到ecx,然后调用TA::show
004114B3 mov ecx,dword ptr [this]
004114B6 call TA::show (4110EBh)