Today I read the chapter on calling functions from the ground up (page 53) in programming, and I have some knowledge about function calls in assembly language. Call this function name when calling a function in assembly language. The function execution process is as follows:
Prepare for execution
In the masterProgramIn each call to a function, the parameters are first pushed to the stack in reverse order;
Then call func_name. Here, call will do two things: first, put the return address of the function into the stack, and second, let the instruction execution pointer % EIP point to the start of the function.
Start execution
Now the function is being executed, but it executes the function.CodeWe need to do a little thing before, first put the original base address register % EBP value into the stack, because in program execution, % EBP needs to be used separately, then, the value of stack pointer % ESP is copied to % EBP, and % EBP remains unchanged in function execution. function parameters can be obtained through addressing.
Pushl % EBP
Movl % ESP, % EBP
The following code is executed. The function must first save its local variables in the stack, which is very simple. For example, to save a long data type, you only need to move the % ESP pointer down four bytes (because the stack growth direction is from high address to low address ), then, the data is migrated. the following is the stack content after saving two local variables long:
Parameter # n <--- N * 4 + 4 (% EBP)
...
Parameter 2 <--- 12 (% EBP)
Parameter 1 <--- 8 (% EBP)
Return address <--- 4 (% EBP)
Old % EBP <--- (% EBP)
Local variable 1 <----4 (% EBP)
Local variable 2 <----8 (% EBP) and (% ESP)
It can be seen from the above that all function parameters and local variables can be accessed through % EBP base address addressing.
% EBP uses other registers for the same base address addressing. However, for the x86 structure, the % EBP register may be more
Faster.
Execution ended:
Now the function execution is over. Before it returns, you need to do the following:
1. Store the return value of the function in the General Register % eax for external use.
2. Point % ESP to the position where the function starts execution, that is, movl % EBP, % ESP
3. Before the function returns ret, restore EBX, that is, popl % EBP.
Movl % EBP, % ESP
Popl % EBP
RET
As can be seen from the above, when % ESP points to the position where the function starts to execute, the local variable is meaningless (because at this time
The stack address that ESP points to is higher than the address of those local variables ).
After the function execution ends and RET returns, all function parameters pushed during call must also pop out (or four times the number of parameters is directly added to % ESP, ).
Addl $8, % ESP # Because two parameters are 8 bytes
The following is a piece of code: power. S, calculate 2 ^ 3 + 5 ^ 2
#=============================== ASM code begin ============================ ===
# Purpose: program to compile strate how functions work. This program will compute
# The value of 2 ^ 3 + 5 ^ 2
. Section. Data
. Section. Text
. Global _ start
_ Start:
Pushl $3
Pushl $2
Call power # Call the power (2, 3) Function
Addl $8, % ESP # After the function ends, the stack pointer % ESP must be returned before the parameter, that is, 4*2 is added.
Pushl % eax # Save the result of power (2, 3) calculated for the first time (in % eax) and save it on the stack
Pushl $2
Pushl $5
Call power # Call power (5, 2)
Addl $8, % ESP # After the function ends, the stack pointer % ESP must be returned before the parameter, that is, 4*2 is added.
Popl % EBX # extract the power (2, 3) Result of the first calculation from the stack and put it in % EBX
Addl % eax, % EBX # Add and save the two in % EBX
Movl $1, % eax
Int $0x80
# After the system call ends, the call number is saved in % eax (1), and the return value is saved in % EBX (computation result 33)
# Function long power (long a, long B) = a ^ B
. Type Power, @ Function
Power:
Pushl % EBP # % EBP
Movl % ESP, % EBP # % EBP stores % ESP value, used as the base address addressing below
Subl $4, % ESP
Movl 8 (% EBP), % EBX # assign the value of parameter A to % EBX
Movl 12 (% EBP), % ECx # assign the value of parameter B to % ECx
Movl % EBX,-4 (% EBP) # perform B-round CALCULATION ON A and store the intermediate results in-4 (% EBP ).
Power_loop_start:
CMPL $1, % ECx
Je end_power
Movl-4 (% EBP), % eax
Imull % EBX, % eax
Movl % eax,-4 (% EBP)
Decl % ECx
JMP power_loop_start
End_power:
Movl-4 (% EBP), % eax # return value to % EBX
Movl % EBP, % ESP # % ESP return to the start position of function execution
Popl % EBP # restore the % EBP value at the beginning of function execution before RET
RET
#========================= ASM code end ================================== =
# As power. S-O power. o
# LD power. O-o power
#./Power
# Echo $?
33