windows下,vs2017
C++代码:
1、类中没有虚函数:
class Base
{
public:
int x=1;
int b=2;
Base()
{
x = 3;
b = 4;
}
void b_test1()
{
printf("b_test1\n");
}
};
class Sub:Base
{
public:
int x=10;
int b=11;
int c=12;
Sub()
{
x = 21;
b = 22;
c = 23;
}
void b_test1()
{
printf("sub_test1\n");
}
};
int main()
{
Sub sub;
return 0;
}
反汇编代码:
Sub sub;
00BC1818 8D 4D E4 lea ecx,[sub] //sub变量地址传给ecx
00BC181B E8 CB F8 FF FF call Sub::Sub (0BC10EBh)
Sub::Sub:
00BC10EB E9 60 06 00 00 jmp Sub::Sub (0BC1750h)
Sub()
00BC1750 55 push ebp
00BC1751 8B EC mov ebp,esp
00BC1753 81 EC CC 00 00 00 sub esp,0CCh //分配栈空间
00BC1759 53 push ebx
00BC175A 56 push esi
00BC175B 57 push edi
00BC175C 51 push ecx //把sub地址压栈
00BC175D 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00BC1763 B9 33 00 00 00 mov ecx,33h
00BC1768 B8 CC CC CC CC mov eax,0CCCCCCCCh
00BC176D F3 AB rep stos dword ptr es:[edi] //栈空间数据初始化
00BC176F 59 pop ecx //sub地址出栈
00BC1770 89 4D F8 mov dword ptr [this],ecx //把sub地址付给this指针。
00BC1773 8B 4D F8 mov ecx,dword ptr [this] //this指针传给ecx
00BC1776 E8 B7 F8 FF FF call Base::Base (0BC1032h) //调用基类的构造函数
Base::Base:
00BC1032 E9 A9 06 00 00 jmp Base::Base (0BC16E0h)
Base()
00BC16E0 55 push ebp
00BC16E1 8B EC mov ebp,esp
00BC16E3 81 EC CC 00 00 00 sub esp,0CCh
00BC16E9 53 push ebx
00BC16EA 56 push esi
00BC16EB 57 push edi
00BC16EC 51 push ecx
00BC16ED 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00BC16F3 B9 33 00 00 00 mov ecx,33h
00BC16F8 B8 CC CC CC CC mov eax,0CCCCCCCCh
00BC16FD F3 AB rep stos dword ptr es:[edi]
00BC16FF 59 pop ecx //子类this指针出栈,存放到ecx中
00BC1700 89 4D F8 mov dword ptr [this],ecx //将子类的this指针赋给基类的this指针。
class Base
{
public:
int x=1;
00BC1703 8B 45 F8 mov eax,dword ptr [this]
00BC1706 C7 00 01 00 00 00 mov dword ptr [eax],1 类成员数据初始化
int b=2;
00BC170C 8B 45 F8 mov eax,dword ptr [this]
00BC170F C7 40 04 02 00 00 00 mov dword ptr [eax+4],2
{
x = 3;
00BC1716 8B 45 F8 mov eax,dword ptr [this] //基类构造函数,修改成员变量的值。
00BC1719 C7 00 03 00 00 00 mov dword ptr [eax],3
b = 4;
00BC171F 8B 45 F8 mov eax,dword ptr [this]
00BC1722 C7 40 04 04 00 00 00 mov dword ptr [eax+4],4
}
00BC1729 8B 45 F8 mov eax,dword ptr [this]
00BC172C 5F pop edi
00BC172D 5E pop esi
00BC172E 5B pop ebx
00BC172F 8B E5 mov esp,ebp
00BC1731 5D pop ebp
00BC1732 C3 ret
class Sub:Base
{
public:
int x=10;
00BC177B 8B 45 F8 mov eax,dword ptr [this]
00BC177E C7 40 08 0A 00 00 00 mov dword ptr [eax+8],0Ah //子类成员变量初始化,注意成员变量的地址
int b=11;
00BC1785 8B 45 F8 mov eax,dword ptr [this]
00BC1788 C7 40 0C 0B 00 00 00 mov dword ptr [eax+0Ch],0Bh
int c=12;
00BC178F 8B 45 F8 mov eax,dword ptr [this]
00BC1792 C7 40 10 0C 00 00 00 mov dword ptr [eax+10h],0Ch
{
x = 21;
00BC1799 8B 45 F8 mov eax,dword ptr [this]
00BC179C C7 40 08 15 00 00 00 mov dword ptr [eax+8],15h //子类构造函数修改子类成员变量的值。
b = 22;
00BC17A3 8B 45 F8 mov eax,dword ptr [this]
00BC17A6 C7 40 0C 16 00 00 00 mov dword ptr [eax+0Ch],16h
c = 23;
00BC17AD 8B 45 F8 mov eax,dword ptr [this]
00BC17B0 C7 40 10 17 00 00 00 mov dword ptr [eax+10h],17h
}
00BC17B7 8B 45 F8 mov eax,dword ptr [this]
00BC17BA 5F pop edi
00BC17BB 5E pop esi
00BC17BC 5B pop ebx
00BC17BD 81 C4 CC 00 00 00 add esp,0CCh
00BC17C3 3B EC cmp ebp,esp
00BC17C5 E8 5D F9 FF FF call __RTC_CheckEsp (0BC1127h)
00BC17CA 8B E5 mov esp,ebp
00BC17CC 5D pop ebp
00BC17CD C3 ret
return 0;
00BC1820 33 C0 xor eax,eax
}
2、类中包含虚函数:
class Base
{
public:
int x=1;
int b=2;
Base()
{
x = 3;
b = 4;
}
virtual void b_test1()
{
printf("b_test1\n");
}
};
class Sub:Base
{
public:
int x=10;
int b=11;
int c=12;
Sub()
{
x = 21;
b = 22;
c = 23;
}
virtual void b_test1()
{
printf("sub_test1\n");
}
};
int main()
{
Sub sub;
return 0;
}
反汇编:
int main()
{
01041A30 55 push ebp
01041A31 8B EC mov ebp,esp
01041A33 81 EC E4 00 00 00 sub esp,0E4h
01041A39 53 push ebx
01041A3A 56 push esi
01041A3B 57 push edi
01041A3C 8D BD 1C FF FF FF lea edi,[ebp-0E4h]
01041A42 B9 39 00 00 00 mov ecx,39h
01041A47 B8 CC CC CC CC mov eax,0CCCCCCCCh
01041A4C F3 AB rep stos dword ptr es:[edi]
01041A4E A1 00 A0 04 01 mov eax,dword ptr [__security_cookie (0104A000h)]
01041A53 33 C5 xor eax,ebp
01041A55 89 45 FC mov dword ptr [ebp-4],eax
Sub sub;
01041A58 8D 4D E0 lea ecx,[sub]
01041A5B E8 A9 F6 FF FF call Sub::Sub (01041109h) //断点到此处:
return 0;
01041A60 33 C0 xor eax,eax
}
Sub::Sub:
01041109 E9 F2 06 00 00 jmp Sub::Sub (01041800h)
Sub()
01041800 55 push ebp
01041801 8B EC mov ebp,esp
01041803 81 EC CC 00 00 00 sub esp,0CCh
01041809 53 push ebx
0104180A 56 push esi
0104180B 57 push edi
0104180C 51 push ecx
0104180D 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
01041813 B9 33 00 00 00 mov ecx,33h
01041818 B8 CC CC CC CC mov eax,0CCCCCCCCh
0104181D F3 AB rep stos dword ptr es:[edi]
0104181F 59 pop ecx
01041820 89 4D F8 mov dword ptr [this],ecx
01041823 8B 4D F8 mov ecx,dword ptr [this]
01041826 E8 0C F8 FF FF call Base::Base (01041037h)
Base::Base:
01041037 E9 44 07 00 00 jmp Base::Base (01041780h)
Base()
01041780 55 push ebp
01041781 8B EC mov ebp,esp
01041783 81 EC CC 00 00 00 sub esp,0CCh
01041789 53 push ebx
0104178A 56 push esi
0104178B 57 push edi
0104178C 51 push ecx
0104178D 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
01041793 B9 33 00 00 00 mov ecx,33h
01041798 B8 CC CC CC CC mov eax,0CCCCCCCCh
0104179D F3 AB rep stos dword ptr es:[edi]
0104179F 59 pop ecx
010417A0 89 4D F8 mov dword ptr [this],ecx
010417A3 8B 45 F8 mov eax,dword ptr [this]
010417A6 C7 00 34 7B 04 01 mov dword ptr [eax],offset Base::`vftable' (01047B34h)
//注意此处的不同,没有虚函数的话,[eax]是基类第一个成员的地址,有虚函数存在,此处存放的是该类的虚函数表的地址。
class Base
{
public:
int x=1;
010417AC 8B 45 F8 mov eax,dword ptr [this]
010417AF C7 40 04 01 00 00 00 mov dword ptr [eax+4],1 //基类的第一个成员地址为[eax+4]
int b=2;
010417B6 8B 45 F8 mov eax,dword ptr [this]
010417B9 C7 40 08 02 00 00 00 mov dword ptr [eax+8],2
{
x = 3;
010417C0 8B 45 F8 mov eax,dword ptr [this]
010417C3 C7 40 04 03 00 00 00 mov dword ptr [eax+4],3
b = 4;
010417CA 8B 45 F8 mov eax,dword ptr [this]
010417CD C7 40 08 04 00 00 00 mov dword ptr [eax+8],4
}
010417D4 8B 45 F8 mov eax,dword ptr [this]
010417D7 5F pop edi
010417D8 5E pop esi
010417D9 5B pop ebx
010417DA 8B E5 mov esp,ebp
}
010417DC 5D pop ebp
010417DD C3 ret
0104182B 8B 45 F8 mov eax,dword ptr [this]
0104182E C7 00 4C 7B 04 01 mov dword ptr [eax],offset Sub::`vftable' (01047B4Ch)
//将子类的虚表地址修改成该类的虚表地址。
class Sub:Base
{
public:
int x=10;
01041834 8B 45 F8 mov eax,dword ptr [this]
01041837 C7 40 0C 0A 00 00 00 mov dword ptr [eax+0Ch],0Ah //子类成员变量初始化,在基类成员下面。
int b=11;
0104183E 8B 45 F8 mov eax,dword ptr [this]
01041841 C7 40 10 0B 00 00 00 mov dword ptr [eax+10h],0Bh
int c=12;
01041848 8B 45 F8 mov eax,dword ptr [this]
0104184B C7 40 14 0C 00 00 00 mov dword ptr [eax+14h],0Ch
{
x = 21;
01041852 8B 45 F8 mov eax,dword ptr [this]
01041855 C7 40 0C 15 00 00 00 mov dword ptr [eax+0Ch],15h
b = 22;
0104185C 8B 45 F8 mov eax,dword ptr [this]
0104185F C7 40 10 16 00 00 00 mov dword ptr [eax+10h],16h
c = 23;
01041866 8B 45 F8 mov eax,dword ptr [this]
01041869 C7 40 14 17 00 00 00 mov dword ptr [eax+14h],17h
}
01041870 8B 45 F8 mov eax,dword ptr [this]
01041873 5F pop edi
01041874 5E pop esi
01041875 5B pop ebx
01041876 81 C4 CC 00 00 00 add esp,0CCh
0104187C 3B EC cmp ebp,esp
0104187E E8 C2 F8 FF FF call __RTC_CheckEsp (01041145h)
01041883 8B E5 mov esp,ebp
01041885 5D pop ebp
01041886 C3 ret
return 0;
01041A60 33 C0 xor eax,eax