The so-called process is the meaning of function in C language.
This chapter describes the details of the function call procedure.
Stack frame
The IA32 program uses stacks to support the operation of the program, which is used to hold data that is staged at the time of the call.
It can:
- Parameters of the transfer function
- Store return Data
- Save the data for some registers so that they can be recovered later
Each section of the function constructs a space in the stack, called the stack frame. The stack frame is called because this space is used 栈指针
and 帧指针
defined.
Stack pointer: %esp
, S represents the stack, which points to the top of the stack frame, and the pointer is movable.
Frame pointer: %ebp
, b I guess it should be base, which points to the bottom of the stack frame, the pointer is not movable, and its address is usually offset to get the data stored in the stack, so it is called基址指针
When another function is called in one function, it is common to let%EBP point to the%ESP position and then%esp to run backwards, eventually building a stack frame space.
To describe the stack frame, use a small example of a simple program
int target(int b){
b=b+2;
return b;
}
void claller(){
int a=2;
int c=target(a);
}
Assembly:
I'm using gcc under Windows.
.file "1.c"
.text
.align 2
.globl target
.def target; .scl 2; .type 32; .endef
target:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $2, %eax
popl %ebp
ret
.align 2
.globl caller
.def caller; .scl 2; .type 32; .endef
caller:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $2, (%esp)
call target
addl $3, %eax
leave
ret
Introduce several instructions before interpreting the Assembly
Pager
- Call Label calls the specified function
- Call *operand indirectly invokes the specified function, Operand can be a register
- The function of call is to put the return address into the stack (which is the value of the program counter) and jump to the target code location.
Add
call next
next:
pop %eax
The program segment is the only way to save the values in the program counter to%exa
Ret
- POPs the data from the stack (which is actually the return address) and jumps to the location indicated by this address
Supplement
At the beginning of the function, the stack pointer automatically moves down a distance to open up the stack frame space, which is based on the data used by the function. And sometimes this space is not all used, because GCC adheres to a x86 programming guideline, That is, the stack space used by a function must be an integer multiple of 16 bytes, in order to ensure strict alignment of the data, so sometimes the compiler allocates this space that will never be used.
Recursive
It's too complicated for you to watch and play.
Usage conventions for registers
As can be seen in the example above, the caller (caller) does not overwrite the value of the register that the callee (target) will use later when invoking a function.
For example, when Target starts, it saves the value of the%EBP to the stack, and it is taken out when it is returned to caller. Here is the callee responsible for the register data not being overwritten.
The IA32 uses a uniform register usage Convention to indicate who holds the data for those registers.
The content is:
Register %eax
, %edx
which %ecx
is divided into the register saved by the caller
- Before calling a function, save the value of the register to the caller's stack frame, use the register at random within the callee's program, and return to the caller's stack frame before the saved data is put back into the register.
Registers %ebx
, %esi
which are %edi
divided into registers saved by the callee
- In the callee's program segment, if a place is to use one of those 3 registers, the data in the register is saved to the callee stack frame, and the data in the stack frame is returned to the register before the call is completed. Like the example above
From for notes (Wiz)
List of attachments
In-depth understanding of the computer system 3.7 process