// A. h code:
# Pragma once
# Include <iostream>
Using namespace std;
Void test ();
# Include "a. h"
// A. cpp Code:
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, 36 h
004114D7 mov eax, 0 CCCCCCCCh
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 (411520 h)
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, 33 h
00411537 mov eax, 0 CCCCCCCCh
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, [(411574 h)]
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 Command
The CPU executes the call command in two steps:
(1) press the current IP address, CS, and IP address into the stack;
(2) transfer.
Before implementing the transfer, the call command saves the return address to the stack so that the child can return the return address to the CALL command through the ret command and then run it;
Jmp has no use of these things, and it has passed over. The Execution Process in the future will all be decided by that. Of course, except for some special execution process control skills.
I don't know much about compilation.
004114DE call callmyfunc (41125Dh)
0041125D jmp callmyfunc (411520 h)
Then, directly use jmp to the address of the callmyfunc function.
After the callmyfunc function ends, the code for calling the Destructor is added as follows:
00411546 lea ecx, [mytestclass]
00411549 call MyTest ::~ MyTest (41102Dh)
Now we know the principle of C ++ destructor. The Compiler wraps sub-processes for calling functions,
Then add the Destructor call code and return the code.
In this case, if an exception occurs in the function, the Destructor may fail to be called correctly, resulting in Memory leakage.
Continue the test based on the analysis.
From the world