After class C ++, Mr. Yang gave his students a question about the memory structure of C ++ function calls. In the process of referring to "programmer's self-cultivation", I had some doubts about the description in the book. Therefore, I made a disassembly of program 1 in the VS2008 environment, with the single-step debugging, I checked the memory changes and found some minor errors in the diagram and description in the book. Record the actual process here.
// Program 1
# Include <iostream>
Using namespacestd;
Int foo (inti ){
Int a = 1, B = 2;
B =;
Return I;
}
Int main (){
Int a = foo (0 xABCDEF );
Return 0;
}
The first thing to note is that the implementation of the program running varies according to the compiler. Therefore, we need to emphasize that all the processes discussed in this article are carried out in the VS2008 compiling environment, we also examine the disassembly of the debug version.
Figure 1 stack structure during running
Figure 1 shows the stack structure for function calling. The following describes what is done in each step of the Assembly command.
The EBP pointer and ESP pointer must be specified in advance. The former is a fixed value during the operation of a function (when other functions are not called), as shown in position 1; the latter is the top pointer of the stack.
Collation
Operator
Corresponding assembly
Memory operations
1
Main
Function
Push 0 ABCDEFh
Function parameter pressure Stack
ESP point to location 1
2
Main
Function
Call foo (11C1028h)
During the call, the next instruction address (the so-called return address) after the function is called is automatically pushed to the stack.
ESP point to location 2
3
Foo
Function
Push ebp
Mov ebp, esp
Apply the old EBP value to the stack;
ESP point to location 3
Assign the current ESP value to EBP, so EBP also points to location 3
4
Foo
Function
Sub esp, 0D8h
Reserve space for local variables on the stack
ESP pointing position 4
5
Foo
Function
Push ebx
Push esi
Push edi
Register pressure stack Storage
ESP points to Location 5
6
Foo
Function
Lea edi, [ebp-0D8h]
Mov ecx, 36 h
Mov eax, 0 CCCCCCCCh
Rep stos dword ptr es: [edi]
Assign the address value of location 4 to the EDI register;
Assign all memory values between location 4 and location 3 to 0 CCCCCCCCh (from low to high)
In this case, ESP points to Location 5.
7
Foo
Function
Mov dword ptr [a], 1
Mov dword ptr [B], 2
Assign values to a and B in the local variable area through pointer access;
Note: a and B are not continuously stored in the stack, and the space of local variables is not fully occupied.
ESP position unchanged
8
Foo
Function
Mov eax, dword ptr [a]
Mov dword ptr [B], eax www.2cto.com
The EAX register is used to assign values to local variables. pointer access is still required.
ESP position unchanged
9
Foo
Function
Mov eax, dword ptr [I]
Implement the return of the foo function in steps 8, 9, and 10;
Pass the returned value through the EAX register
ESP still points to Location 5, that is, the last register to be pressed
10
Foo
Function
Pop edi
Pop esi
Pop ebx
Remove the register from the previous Stack
ESP pointer pointing to position 4
11
Foo
Function
Mov esp, ebp
Pop ebp
Assigning the EBP value to the ESP pointer means that the memory space of the local variable is released.
ESP point to location 3
Send the old EBP value of the previous stack to the EBP.
ESP point to location 2
12
Foo
Function
Ret
Function return will jump to the next instruction Location Based on the returned address of the previous pressure Stack
ESP point to location 1
13
Main
Function
Add esp, 4
Releases the foo function parameter of the previous stack. So far, the foo function has completely ended its life.
ESP points to 0
14
Main
Function
Mov dword ptr [a], eax
Pass the return value through EAX and assign the return value to variable;
The main function's content about calling the foo function has ended.
It should be noted that after the function completes initialization such as on-site protection, ESP always points to the top of the stack space of the current function. At this time, if the current function calls another function, the EBP will be treated as the old EBP pressure stack, and the content related to the new function will start to press the stack from the position pointed by the current ESP.