//a.h代码:
#pragma once
#include <iostream>
using namespace std;
void test();
#include "a.h"
//a.cpp代码:
class MyTest
{
public:
MyTest(){
cout << "MyTest()" << endl;
}
~MyTest(){
cout << "~MyTest()" << endl;
}
};
void test()
{
MyTest test;
}
//main.cpp
#include <iostream>
#include "a.h"
int main()
{
test();
int a=5;
int b=6;
return 0;
}
int main()
{
004114C0 push ebp
004114C1 mov ebp,esp
004114C3 sub esp,0D8h
004114C9 push ebx
004114CA push esi
004114CB push edi
004114CC lea edi,[ebp-0D8h]
004114D2 mov ecx,36h
004114D7 mov eax,0CCCCCCCCh
004114DC rep stos dword ptr es:[edi]
callmyfunc();
004114DE call callmyfunc (41125Dh)
int a=5;
004114E3 mov dword ptr [a],5
int b=6;
004114EA mov dword ptr [b],6
return 0;
004114F1 xor eax,eax
}
0041125D jmp callmyfunc (411520h)
void callmyfunc()
{
00411520 push ebp
00411521 mov ebp,esp
00411523 sub esp,0CCh
00411529 push ebx
0041152A push esi
0041152B push edi
0041152C lea edi,[ebp-0CCh]
00411532 mov ecx,33h
00411537 mov eax,0CCCCCCCCh
0041153C rep stos dword ptr es:[edi]
MyTest mytestclass;
0041153E lea ecx,[mytestclass]
00411541 call MyTest::MyTest (4111C7h)
}
00411546 lea ecx,[mytestclass]
00411549 call MyTest::~MyTest (41102Dh)
0041154E push edx
0041154F mov ecx,ebp
00411551 push eax
00411552 lea edx,[ (411574h)]
00411558 call @ILT+170(@_RTC_CheckStackVars@8) (4110AFh)
0041155D pop eax
0041155E pop edx
0041155F pop edi
00411560 pop esi
00411561 pop ebx
00411562 add esp,0CCh
00411568 cmp ebp,esp
0041156A call @ILT+415(__RTC_CheckEsp) (4111A4h)
0041156F mov esp,ebp
00411571 pop ebp
00411572 ret
call 指令
CPU执行call指令,进行两步操作:
(1)将当前的 IP 或 CS和IP 压入栈中;
(2)转移。
call 指令在实现转移之前, 要将返回地址存入堆栈的, 以便子程可以通过 ret 指令返回到 CALL 指令下面的指令接着运行;
jmp 就没用这些事儿, 直接过去就过去了, 以后的执行流程全由那里的说了算. 当然了, 一些特殊的执行流程控制技巧除外.
大概的意思,汇编我也不怎么懂.
004114DE call callmyfunc (41125Dh)
0041125D jmp callmyfunc (411520h)
然后直接jmp 到callmyfunc函数的地址.
callmyfunc函数结束的后面,加入了调用析构的代码如下:
00411546 lea ecx,[mytestclass]
00411549 call MyTest::~MyTest (41102Dh)
现在大概知道C++析构的原理了,编译器对调用函数做了个子过程包装,
然后加入析构调用代码.最后返回.
这样看来,如果函数中产生异常,可能会导致析构函数不能正确的调用,从而导致内存泄漏.
根据分析,继续测试.
C++标准规定,本地对象的析构函数的调用顺序与他们的构造顺序相反。C++标准规定,本地对象的析构函数的调用顺序与他们的构造顺序相反。C++标准规定,本地对象的析构函数的调用顺序与他们的构造顺序相反。C++标准规定,本地对象的析构函数的调用顺序与他们的构造顺序相反。
//C++标准规定,本地对象的析构函数的调用顺序与他们的构造顺序相反。
void callMyTest()
{
MyTestA MyTestAObj;
MyTestB MyTestBObj;
}
int main()
{
004121B0 push ebp
004121B1 mov ebp,esp
004121B3 sub esp,0D8h
004121B9 push ebx
004121BA push esi
004121BB push edi
004121BC lea edi,[ebp-0D8h]
004121C2 mov ecx,36h
004121C7 mov eax,0CCCCCCCCh
004121CC rep stos dword ptr es:[edi]
callMyTest();
004121CE call callMyTest (411159h)
int a=5;
004121D3 mov dword ptr [a],5
int b=6;
004121DA mov dword ptr [b],6
return 0;
004121E1 xor eax,eax
}
00411159 jmp callMyTest (411540h)
void callMyTest()
{
00411540 push ebp
00411541 mov ebp,esp
00411543 push 0FFFFFFFFh
00411545 push offset __ehhandler$?callMyTest@@YAXXZ (4155E8h)
0041154A mov eax,dword ptr fs:[00000000h]
00411550 push eax
00411551 sub esp,0D8h
00411557 push ebx
00411558 push esi
00411559 push edi
0041155A lea edi,[ebp-0E4h]
00411560 mov ecx,36h
00411565 mov eax,0CCCCCCCCh
0041156A rep stos dword ptr es:[edi]
0041156C mov eax,dword ptr [___security_cookie (41B044h)]
00411571 xor eax,ebp
00411573 push eax
00411574 lea eax,[ebp-0Ch]
00411577 mov dword ptr fs:[00000000h],eax
MyTestA MyTestAObj;
0041157D lea ecx,[ebp-11h]
00411580 call MyTestA::MyTestA (4110FAh)
00411585 mov dword ptr [ebp-4],0
MyTestB MyTestBObj;
0041158C lea ecx,[ebp-1Dh]
0041158F call MyTestB::MyTestB (41103Ch)
}
00411594 lea ecx,[ebp-1Dh]
00411597 call MyTestB::~MyTestB (41114Fh)
0041159C mov dword ptr [ebp-4],0FFFFFFFFh
004115A3 lea ecx,[ebp-11h]
004115A6 call MyTestA::~MyTestA (411226h)
004115AB push edx
004115AC mov ecx,ebp
004115AE push eax
004115AF lea edx,[ (4115DCh)]
004115B5 call @ILT+185(@_RTC_CheckStackVars@8) (4110BEh)
004115BA pop eax
004115BB pop edx
004115BC mov ecx,dword ptr [ebp-0Ch]
004115BF mov dword ptr fs:[0],ecx
004115C6 pop ecx
004115C7 pop edi
004115C8 pop esi
004115C9 pop ebx
004115CA add esp,0E4h
004115D0 cmp ebp,esp
004115D2 call @ILT+465(__RTC_CheckEsp) (4111D6h)
004115D7 mov esp,ebp
004115D9 pop ebp
004115DA ret