Registers stored on the stack in system_call
When the system_call function is called, it must check some arguments and call the function specified in the system call table according to the argument passed to eax. This is the part that preserves the registers:
system_call:
pushl %eax
SAVE_ALL
movl $0xffffe000, %ebx /* or 0xfffff000 for 4-KB stacks */
andl %esp, %ebx
Why does he save eax twice? (in the pushl command% eax and in the SAVE_ALL macro, which also saves eax).
source to share
In a standard C call on x86-32, it is used %eax
to return a value from a function. Linux system calls also return a return value to user space in %eax
. How is this done on x86-32?
The syscall entry point arch/x86/entry/entry_32.S
calls the syscall handler function and then overwrites the stored value %eax
(stored in SAVE_ALL
) on the stack with its return value. Later, returning back to user space, the stored values โโof all registers are popped off the stack into registers. Since the value %eax
stored SAVE_ALL
was overwritten with the required return value, when the user code resumes execution, naturally it finds the return value of syscall in %eax
.
But there are times when the kernel needs to find the original stored value %eax
. Even if the value saved in SAVE_ALL
has already been overwritten, it can still look at the value saved first pushl %eax
. In the kernel code, this value is called orig_eax
. (Grep is the kernel source, and you'll find it in several places.)
Take a look at the macro RESTORE_REGS
in arch/x86/entry/entry_32.S
and you will see that it takes a parameter pop
that is used to set up the stack after it has popped all the stored register values โโback into registers. You will RESTORE_REGS 4
only find in the place where syscall goes back to user space. This is "4" to get rid of the value pushl %eax
you asked for, also known as orig_eax
!
source to share