c++ new,delete,析构函数原理,汇编展示

   479:  String2* str2 = new String2;
00401821 6A 10            push        10h       //传入对象大小
00401823 E8 C8 03 00 00   call        operator new (401BF0h)     //分配内存
00401828 83 C4 04         add         esp,4
0040182B 89 85 0C FF FF FF mov         dword ptr [ebp-0F4h],eax
00401831 33 FF            xor         edi,edi
00401833 3B C7            cmp         eax,edi
00401835 89 7D FC         mov         dword ptr [ebp-4],edi
00401838 74 0B            je          main+55h (401845h)
0040183A 8B C8            mov         ecx,eax       //传入this指针
0040183C E8 9F FC FF FF   call        String2::String2 (4014E0h)
00401841 8B F0            mov         esi,eax
00401843 EB 02            jmp         main+57h (401847h)
00401845 33 F6            xor         esi,esi 

 151:  MyString()      构造函数
00615080 55               push        ebp 
00615081 8B EC            mov         ebp,esp
00615083 81 EC D8 00 00 00 sub         esp,0D8h
00615089 53               push        ebx 
0061508A 56               push        esi 
0061508B 57               push        edi 
0061508C 51               push        ecx 
0061508D 8D BD 28 FF FF FF lea         edi,[ebp-0D8h]
00615093 B9 36 00 00 00   mov         ecx,36h
00615098 B8 CC CC CC CC   mov         eax,0CCCCCCCCh
0061509D F3 AB            rep stos    dword ptr es:[edi]
0061509F 59               pop         ecx 
006150A0 89 4D F8         mov         dword ptr [ebp-8],ecx
006150A3 8B 45 F8         mov         eax,dword ptr [this]
006150A6 C7 00 F4 A0 62 00 mov         dword ptr [eax],offset MyString::`vftable' (62A0F4h)     设置虚函数表
   152:  {
   153:   m_pcdata = new char[1];
006150AC 6A 01            push        1   
006150AE E8 8F C3 FF FF   call        operator new[] (611442h)
006150B3 83 C4 04         add         esp,4
006150B6 89 85 2C FF FF FF mov         dword ptr [ebp-0D4h],eax
006150BC 8B 45 F8         mov         eax,dword ptr [this]
006150BF 8B 8D 2C FF FF FF mov         ecx,dword ptr [ebp-0D4h]
006150C5 89 48 04         mov         dword ptr [eax+4],ecx
   154:   *m_pcdata = 0;
006150C8 8B 45 F8         mov         eax,dword ptr [this]
006150CB 8B 48 04         mov         ecx,dword ptr [eax+4]
006150CE C6 01 00         mov         byte ptr [ecx],0
   155:   m_nsize = 1;
006150D1 8B 45 F8         mov         eax,dword ptr [this]
006150D4 C7 40 08 01 00 00 00 mov         dword ptr [eax+8],1
   156:   cout<<"MyString()\n";
006150DB 68 E0 A0 62 00   push        offset string "MyString()\n" (62A0E0h)
006150E0 A1 A8 26 63 00   mov         eax,dword ptr [__imp_std::cout (6326A8h)]
006150E5 50               push        eax 
006150E6 E8 AA C5 FF FF   call        std::operator<<<std::char_traits<char> > (611695h)
006150EB 83 C4 08         add         esp,8
   157:  };


   480:  delete str2;
00401847 3B F7            cmp         esi,edi
00401849 C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh
00401850 74 10            je          main+72h (401862h)
00401852 8B CE            mov         ecx,esi                                             //传入this指针
00401854 E8 27 FD FF FF   call        String2::~String2 (401580h)     //调用析构函数

00401859 56               push        esi 
0040185A E8 01 03 00 00   call        operator delete (401B60h)     //释放内存

0040185F 83 C4 04         add         esp,4

从上面的汇编码来看c++的new是调用一个全局的operator new在这个函数里调用了c的malloc。然后调用类的构造函数,在构造函数体先调用基类的构造函数,最后设置虚函数表,如果有基类的话会重新设置基类的虚函数表。单继承派生类和基类是公用一个虚函数表这种情况下不用去设置基类的虚函数表,在有多个基类的情况下就需要重新设置基类的虚函数表了。其实在实例化一个派生类的时候基类的虚函数表和派生类是同一个表只不过偏移量不同而已。一般情况下基类的虚函数地址在虚函数表的前面。delete先调用析构函数然后就是全局的operator  delete 函数。

有不妥的地方还请指教。

你可能感兴趣的:(C++,c,汇编,String,delete,byte)