first, how to pass the parameters
When the assembler calls the C function, the function's entry parameters are routed using stacks, and the parameters are passed from right to left. That is, the last (rightmost) parameter of the function first goes into the stack, and the first parameter to the left is finally put into the stack, then executes the call instruction to invoke the C function. ii. Elimination of parameters
After the C function returns, the assembler needs to erase the function parameters that were previously pushed into the stack, that is, the caller is responsible for clearing the stack space occupied by the parameter.
For example, the C function to be invoked and the parameters to be passed are printsomething (arg1, arg2, Arg3, ARG4);
So it should be written in the assembler:
PUSHL arg4
pushl arg3 pushl arg2 pushl arg1 call printsomething
addl , $0x10
Iii. delivery of return values
The return value of the C function, if it is a 32-bit integer, is saved in the EAX register and, if it is a 64-bit integer, is saved in the EDX:EAX register. Iv. about the return address
When the call instruction is executed, the CPU presses the address (the return address) of the next instruction in the command to the stack (see the EIP).
Five, on the stack switch
If the call also involves code privilege level changes, then the CPU will also carry out stack switching, the process is more complex. I can refer to my blog: control transfer by calling the door
Note : The Linux kernel uses only interrupt doors and trap doors to handle the invocation of privilege-level changes and does not use the call instruction to handle the privilege-level changes. vi. use JMP command instead of call instruction
We can use the JMP instruction instead of the call command to achieve the purpose of invoking the C function. The method is: After all parameters into the stack, manually put the next instruction to execute the address (return address) into the stack, and then directly using the JMP instruction to jump to the called function of the entry address to execute. When the called function executes its most final ret instruction, it pops the return address of our artificially pressed stack into the EIP register, which returns the execution flow to the main function.
reference materials
"Complete analysis of Linux kernel" (Zhao, Machinery Industry Press, 2006)