反汇编-C/C++中类的反汇编-2-构造函数和析构函数

构造函数

正向代码

#include<iostream>
using namespace std;

class Base
{
public:
Base()
{
printf("Base::Base()\n");
}
};
class Child : public Base
{
public:
Child()
{
printf("Child::Child()\n");
}
};

int main()
{
Child Childtest1;
return 0;
}

逆向代码

int main()
{
00AC1A10 push       ebp  
00AC1A11 mov         ebp,esp  
00AC1A13 sub         esp,0D0h  
00AC1A19 push       ebx  
00AC1A1A push       esi  
00AC1A1B push       edi  
00AC1A1C lea         edi,[ebp-0D0h]  
00AC1A22 mov         ecx,34h  
00AC1A27 mov         eax,0CCCCCCCCh  
00AC1A2C rep stos   dword ptr es:[edi]  
00AC1A2E mov         eax,dword ptr [__security_cookie (0ACA004h)]  
00AC1A33 xor         eax,ebp  
00AC1A35 mov         dword ptr [ebp-4],eax  
00AC1A38 mov         ecx,offset _42C85800_main@cpp (0ACC029h)  
00AC1A3D call       @__CheckForDebuggerJustMyCode@4 (0AC1325h)  
Child Childtest1;
00AC1A42 lea         ecx,[Childtest1]  
00AC1A45 call       Child::Child (0AC1258h)  
return 0;
00AC1A4A xor         eax,eax  
}
class Child : public Base
{
public:
Child()
00AC1800 push       ebp  
00AC1801 mov         ebp,esp  
00AC1803 sub         esp,0CCh  
00AC1809 push       ebx  
00AC180A push       esi  
00AC180B push       edi  
00AC180C push       ecx  
00AC180D lea         edi,[ebp-0CCh]  
00AC1813 mov         ecx,33h  
00AC1818 mov         eax,0CCCCCCCCh  
00AC181D rep stos   dword ptr es:[edi]  
00AC181F pop         ecx  
00AC1820 mov         dword ptr [this],ecx  
00AC1823 mov         ecx,offset _42C85800_main@cpp (0ACC029h)  
00AC1828 call       @__CheckForDebuggerJustMyCode@4 (0AC1325h)  
00AC182D mov         ecx,dword ptr [this]  
00AC1830 call       Base::Base (0AC1253h)  
{
printf("Child::Child()\n");
00AC1835 push       offset string "Child::Child()\n" (0AC7B40h)  
00AC183A call       _printf (0AC10CDh)  
00AC183F add         esp,4  
}
00AC1842 mov         eax,dword ptr [this]  
00AC1845 pop         edi  
00AC1846 pop         esi  
00AC1847 pop         ebx  
00AC1848 add         esp,0CCh  
00AC184E cmp         ebp,esp  
00AC1850 call       __RTC_CheckEsp (0AC1244h)  
00AC1855 mov         esp,ebp  
00AC1857 pop         ebp  
00AC1858 ret  

结论:

通过代码可以看到,最先其实先是调用调用类的构造函数,在该构造函数中先执行上一个父类的构造函数,然后再继续构造该类,当编译器认为构造函数不必要的时候,不会创建

析构函数

正向代码

#include<iostream>
using namespace std;

class Base
{
public:
~Base()
{
printf("Delete Base::~Base()\n");
}
};
class Child : public Base
{
public:
~Child()
{
printf("Delete Child::~Child()\n");
}
};

int main()
{
Child Childtest1;




return 0;
}

逆向代码

int main()
{
00631A10 push       ebp  
00631A11 mov         ebp,esp  
00631A13 sub         esp,0D8h  
00631A19 push       ebx  
00631A1A push       esi  
00631A1B push       edi  
00631A1C lea         edi,[ebp-0D8h]  
00631A22 mov         ecx,36h  
00631A27 mov         eax,0CCCCCCCCh  
00631A2C rep stos   dword ptr es:[edi]  
00631A2E mov         ecx,offset _42CAFE56_源@cpp (063C029h)  
00631A33 call       @__CheckForDebuggerJustMyCode@4 (0631325h)  
Child Childtest1;




return 0;
00631A38 mov         dword ptr [ebp-0D4h],0  
00631A42 lea         ecx,[Childtest1]  
00631A45 call       Child::~Child (06312A3h)  
00631A4A mov         eax,dword ptr [ebp-0D4h]  
}
class Child : public Base
{
public:
~Child()
{
00631800 push       ebp  
00631801 mov         ebp,esp  
00631803 sub         esp,0CCh  
00631809 push       ebx  
0063180A push       esi  
0063180B push       edi  
0063180C push       ecx  
0063180D lea         edi,[ebp-0CCh]  
00631813 mov         ecx,33h  
00631818 mov         eax,0CCCCCCCCh  
0063181D rep stos   dword ptr es:[edi]  
0063181F pop         ecx  
00631820 mov         dword ptr [this],ecx  
00631823 mov         ecx,offset _42CAFE56_源@cpp (063C029h)  
00631828 call       @__CheckForDebuggerJustMyCode@4 (0631325h)  
printf("Delete Child::~Child()\n");
0063182D push       offset string "Delete Child::~Child()\n" (0637B4Ch)  
00631832 call       _printf (06310CDh)  
00631837 add         esp,4  
}
0063183A mov         ecx,dword ptr [this]  
0063183D call       Base::~Base (0631168h)  
00631842 pop         edi  
00631843 pop         esi  
00631844 pop         ebx  
00631845 add         esp,0CCh  
0063184B cmp         ebp,esp  
0063184D call       __RTC_CheckEsp (0631249h)  
00631852 mov         esp,ebp  
00631854 pop         ebp  
00631855 ret  

结论

这里可以很明显的看到,,在调用完子类的析构函数后,会继续调用父类的析构函数。它也是先调用子类的析构函数,然后再在子类的析构函数内部调用父类的析构函数