There is such a piece of C ++ code:
#include <cstdio>class CExample { int x, y; public: CExample(int va, int vb) { x = va;y = vb; } CExample(const CExample& C) { x = C.x;y = C.y; } ~CExample() {printf("~CExample()\n"); } void Show () { printf("%d, %d\n", x, y);return ; }};void fun(CExample E) { printf("In F(CExample)\n"); return ;}int main() { CExample A(100, 200); CExample B = A; B.Show(); fun(A); return 0;}
Running result:
The compiling and debugging environment is VC 6.0. The notes are as follows:
Main function:
30: int main () {00401130 push ebp00401131 mov EBP, esp00401133 push 0ffh00401135 push offset _ ehhandler $ _ main (00413422) 0040113a mov eax, FS: [00000000] 00401140 push into mov dword ptr fs: [0], esp00401148 sub ESP, 5ch0040114b push ebx0040114c Push Pull edi0040114e Lea EDI, [ebp-68h] 00401151 mov ECx, 17h00401156 mov eax, 0cccccccch0040115b rep STOs dword ptr [EDI]; The above code is to create a stack, EBP = 124500 031: cexample A (100,200); 0040115d push 0c8h; Push 200 into Stack 00401162 push 64 h; push 100 into Stack 00401164 Lea ECx, [ebp-14h]; the EBP-14h is the memory address of A, which occupies 8 bytes and saves the address to the ECX register 00401167 call @ ILT + 0 (cexample: cexample) (00401005 ); call the constructor cexample (INT, INT) 00401_c mov dword ptr [ebp-4], 032: cexample B = A; 00401173 Lea eax, [ebp-14h]; save a's memory address to eax register 00401176 push eax; press eax into Stack 00401177 Lea ECx, [ebp-1Ch]; EBP-1Ch It is the memory address of B, which occupies 8 bytes. Save the address to the ECX register for 0040117a call @ ILT + 20 (cexample: cexample) (00401019); call the copy constructor, copy the value in A to B's memory space; carefully observe the stack address to understand 0040117f mov byte PTR [ebp-4], 133: B. show (); 00401183 Lea ECx, [ebp-1Ch] 00401186 call @ ILT + 25 (cexample: Show) (0040101e) 34: Fun (a); 0040118b sub ESP, 8; ESP = 1244884, ESP-8 = 1244876; ESP-8 is a piece of memory,; before calling fun, first call the copy constructor to copy a, copy the content; stored in this memory space (A cexample object, recorded as temp) 0040 118e mov ECx, esp; ECx register save temp object memory address 00401190 mov dword ptr [ebp-20h], esp; EBP-20h this space save temp object memory address 00401193 Lea edX, [ebp-14h]; edX register saves a object's memory address 00401196 push edX; esp = 1244872, press a's memory address to stack 00401197 call @ ILT + 20 (cexample: cexample) (00401019); esp = 1244868, function return address pushed to stack, call copy constructor 0040119c mov dword ptr [ebp-28h], eax; esp = 1244876, EBP-28 h = 1244876, save the temp memory address 0040119f call @ ILT + 15 (fun) (004 01014); esp = 1244872, the return address of the function is pushed into the stack, and the fun function 004011a4 is called to add ESP, 8; _ cdecl rule to restore the stack segment, EBP = 124500035: Return 0; 004011a7 mov dword ptr [ebp-24h], 0004011ae mov byte PTR [ebp-4], 0004011b2 Lea ECx, [ebp-1Ch]; EBP-1ch is B's memory address, save to ECx 004011b5 call @ ILT + 5 (cexample ::~ Cexample) (0040100a); Call destructor, destroy object b004011ba mov dword ptr [ebp-4], 0ffffffffh004011c1 Lea ECx, [ebp-14h]; EBP-14 H is a memory address, save to ECx 004011c4 call @ ILT + 5 (cexample ::~ Cexample) (0040100a); Call destructor, destroy object a004011c9 mov eax, dword ptr [ebp-24h] 36 :}
Copy const cexample (const cexample & C ):
11: cexample (const cexample & C) {00401270 push ebp00401271 mov EBP, esp00401273 sub ESP, pull Push Pull push edi00401279 push ecx00401_a Lea EDI, [ebp-44h] 0040127d ECx, 11h00401282 mov eax, 0cccccccch00401287 rep STOs dword ptr [EDI]; above is the stack creation code, EBP = 124486400401289 pop ECx; restores the ECX register content, that is, the temp memory address 0040128a mov dword ptr [ebp-4], ECx; EBP-4 = 1244860, this stack memory save temp memory address 12: x = C. x; 0040128d mov eax, dword ptr [ebp-4]; EBP-4 = 1244860, eax get temp memory address (eax points to temp) 00401290 mov ECx, dword ptr [EBP + 8]; EBP + 8 = 1244872, ECx obtains the memory address of a (ECx points to a) 00401293 mov edX, dword ptr [ECx]; edX = 100 (the first address of a is 100,100 and later than 200) 00401295 mov dword ptr [eax], EDX; temp. X = 10013: Y = C. y; 00401297 mov eax, dword ptr [ebp-4] 0040129a mov ECx, dword ptr [EBP + 8] 0040129d mov edX, dword ptr [ECx + 4]; edX = 200004012a0 mov dword ptr [eax + 4], EDX; likewise, temp. y = 20014:} 004012a3 mov eax, dword ptr [ebp-4]; eax registers save temp memory space 004012a6 pop edi004012a7 pop esi004012a8 pop ebx004012a9 mov ESP, ebp004012ab pop EBP; recover EBP, EBP = 1245000004012ac RET 4; restore the stack segment of this function
Fun function:
25: void fun (cexample e) {00401050 push ebp00401051 mov EBP, esp00401053 push 0ffh00401055 push offset _ ehhandler $? Fun @ yaxvcexample @ Z (004133f9) 0040105a mov eax, FS: [00000000] 00401060 push eax00401061 mov dword ptr fs: [0], esp00401068 sub ESP, pull push ebx00401_c push esi0040106d push edi0040da-e Lea EDI, [ebp-4Ch] 00401071 mov ECx, 10h00401076 mov eax, 1_rep STOs dword ptr [EDI] 0040107d mov dword ptr [ebp-4], 0; EBP = 1244868, the above is the stack creation code 26: printf ("in F (cexample) \ n"); 00401084 push offset Str Ing "in F (cexample) \ n" (0000001c) 00401089 call printf (00401320) 00400000e add ESP, 427: return; 00401091 mov dword ptr [ebp-4], 0ffffffh00401098 Lea ECx, [EBP + 8]; EBP + 8 = 1244876, which is the temp memory address; ECx registers save 004020. B call @ ILT + 5 (cexample ::~ Cexample) (0040100a); call the destructor to destroy the temp object (end of life) 28:} 004010a0 mov ECx, dword ptr [ebp-0Ch] 004010a3 mov dword ptr fs: [0], ecx004010aa pop edi004010ab pop esi004010ac pop ebx004010ad add ESP, descricmp EBP, esp004010b2 call _ chkesp (00401780) 004010b7 mov ESP, descripop EBP; restore EBP, EBP = descriret
The following mainly analyzes the working mechanism of the program when calling the fun function:
When "Fun (a);" is executed, first call the copy constructor to create an object temp, which occupies the stack space of 8 bytes. The content is copy
The contents of A. Then, push the temp memory address of the object into the stack of the fun function and call the fun function. When the fun function ends, call the destructor to destroy the temp object, the stack space occupied by the temp object is recycled.