先看一个没有虚函数的类
{
public:
A()
{
_a = 0;
_b = 0;
cout<<"A::A"<<endl;
}
~A()
{
cout<<_a;
cout<<"A::~A"<<endl;
}
void fun1()
{
cout<<_a<<endl;
cout<<_b<<endl;
cout<<_c<<endl;
cout<<"A::fun1"<<endl;
}
int fun2(int a,int b)
{
cout<<_a<<endl;
cout<<a<<b<<endl;
cout<<"A::fun2"<<endl;
return 0;
}
protected:
private:
int _a;
int _b;
int _c;
};
// 反汇编 代码
--- d:\vs_projects\test112\test112\test112.cpp ---------------------------------
1: // test112.cpp : 定义控制台应用程序的入口点。
2: //
3:
4: #include "stdafx.h"
5: #include <iostream>
6: using namespace std;
7:
8: class A
9: {
10: public:
11: A()
012F1610 55 push ebp
012F1611 8B EC mov ebp,esp
012F1613 81 EC CC 00 00 00 sub esp,0CCh
012F1619 53 push ebx
012F161A 56 push esi
012F161B 57 push edi
012F161C 51 push ecx
012F161D 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
012F1623 B9 33 00 00 00 mov ecx,33h
012F1628 B8 CC CC CC CC mov eax,0CCCCCCCCh
012F162D F3 AB rep stos dword ptr es:[edi]
012F162F 59 pop ecx
012F1630 89 4D F8 mov dword ptr [ebp-8],ecx
12: {
13: _a = 0;
012F1633 8B 45 F8 mov eax,dword ptr [this] // 此处的 this 就是 ebp -8 也就是 ecx 的值 访问第一个类成员变量
012F1636 C7 00 00 00 00 00 mov dword ptr [eax],0
14: _b = 0;
012F163C 8B 45 F8 mov eax,dword ptr [this]
012F163F C7 40 04 00 00 00 00 mov dword ptr [eax+4],0 // ecx+4 第二个 因为是 int
15: cout<<"A::A"<<endl;
012F1646 8B F4 mov esi,esp
012F1648 68 2D 10 2F 01 push offset stlp_std::endl<char,stlp_std::char_traits<char> > (12F102Dh)
012F164D 68 2C 6C 2F 01 push offset string "A::A" (12F6C2Ch)
012F1652 A1 88 A3 2F 01 mov eax,dword ptr [__imp_stlp_std::cout (12FA388h)]
012F1657 50 push eax
012F1658 E8 D4 FA FF FF call stlp_std::operator<<<stlp_std::char_traits<char> > (12F1131h)
012F165D 83 C4 08 add esp,8
012F1660 8B C8 mov ecx,eax
012F1662 FF 15 8C A3 2F 01 call dword ptr [__imp_stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<< (12FA38Ch)]
012F1668 3B F4 cmp esi,esp
012F166A E8 03 FB FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
16: }
012F166F 8B 45 F8 mov eax,dword ptr [this]
012F1672 5F pop edi
012F1673 5E pop esi
012F1674 5B pop ebx
012F1675 81 C4 CC 00 00 00 add esp,0CCh
012F167B 3B EC cmp ebp,esp
012F167D E8 F0 FA FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
012F1682 8B E5 mov esp,ebp
012F1684 5D pop ebp
012F1685 C3 ret
--- 无源文件 -----------------------------------------------------------------------
下面看类成员函数 fun1
--- d:\vs_projects\test112\test112\test112.cpp ---------------------------------
22: void fun1()
23: {
012F3BB0 55 push ebp
012F3BB1 8B EC mov ebp,esp
012F3BB3 81 EC CC 00 00 00 sub esp,0CCh
012F3BB9 53 push ebx
012F3BBA 56 push esi
012F3BBB 57 push edi
012F3BBC 51 push ecx
012F3BBD 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
012F3BC3 B9 33 00 00 00 mov ecx,33h
012F3BC8 B8 CC CC CC CC mov eax,0CCCCCCCCh
012F3BCD F3 AB rep stos dword ptr es:[edi]
012F3BCF 59 pop ecx
012F3BD0 89 4D F8 mov dword ptr [ebp-8],ecx
24: cout<<_a<<endl;
012F3BD3 8B F4 mov esi,esp
012F3BD5 68 2D 10 2F 01 push offset stlp_std::endl<char,stlp_std::char_traits<char> > (12F102Dh)
012F3BDA 8B FC mov edi,esp
012F3BDC 8B 45 F8 mov eax,dword ptr [this]
012F3BDF 8B 08 mov ecx,dword ptr [eax]
012F3BE1 51 push ecx
012F3BE2 8B 0D 88 A3 2F 01 mov ecx,dword ptr [__imp_stlp_std::cout (12FA388h)]
012F3BE8 FF 15 84 A3 2F 01 call dword ptr [__imp_stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<< (12FA384h)]
012F3BEE 3B FC cmp edi,esp
012F3BF0 E8 7D D5 FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
012F3BF5 8B C8 mov ecx,eax
012F3BF7 FF 15 8C A3 2F 01 call dword ptr [__imp_stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<< (12FA38Ch)]
012F3BFD 3B F4 cmp esi,esp
012F3BFF E8 6E D5 FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
25: cout<<_b<<endl;
012F3C04 8B F4 mov esi,esp
012F3C06 68 2D 10 2F 01 push offset stlp_std::endl<char,stlp_std::char_traits<char> > (12F102Dh)
012F3C0B 8B FC mov edi,esp
012F3C0D 8B 45 F8 mov eax,dword ptr [this]
012F3C10 8B 48 04 mov ecx,dword ptr [eax+4]
012F3C13 51 push ecx
012F3C14 8B 0D 88 A3 2F 01 mov ecx,dword ptr [__imp_stlp_std::cout (12FA388h)]
012F3C1A FF 15 84 A3 2F 01 call dword ptr [__imp_stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<< (12FA384h)]
012F3C20 3B FC cmp edi,esp
012F3C22 E8 4B D5 FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
012F3C27 8B C8 mov ecx,eax
012F3C29 FF 15 8C A3 2F 01 call dword ptr [__imp_stlp_std::basic_ostream<char,stlp_std::char_traits<char> >::operator<< (12FA38Ch)]
012F3C2F 3B F4 cmp esi,esp
012F3C31 E8 3C D5 FF FF call @ILT+365(__RTC_CheckEsp) (12F1172h)
26: cout<<_c<<endl;
012F3C36 8B F4 mov esi,esp
012F3C38 68 2D 10 2F 01 push offset stlp_std::endl<char,stlp_std::char_traits<char> > (12F102Dh)
012F3C3D 8B FC mov edi,esp
012F3C3F 8B 45 F8 mov eax,dword ptr [this]
012F3C42 8B 48 08 mov ecx,dword ptr [eax+8]
012F3C45 51 push ecx
012F3C46 8B 0D 88 A3 2F 01 mov ecx,dword ptr [__imp_stlp_std::cout (12FA388h)]
ecx this 指针指向了类的起始地址
如果 有虚表可能稍微有点不同.
this 的前4个字节就是虚表了而不是第一个成员变量了, 第一个成员变量要ecx+4
如果 虚表+虚继承 this 的前4个依然是虚表,后4个虚继承指针 第一个成员变量就是ecx+8 了