In the book Low-Level Programming: C, Assembly, and Program Execution on Intel® 64 Architecture it says,
On system call arguments The arguments for system calls are stored in a different set of registers than those for functions. The fourth argument is stored in
r10
, while a function accepts the fourth argument inrcx
!The reason is that
syscall
instruction implicitly usesrcx
. System calls cannot accept more than six arguments.
You can see this also mentioned in this Stack Overflow post,
A system-call is done via the syscall instruction. This clobbers %rcx and %r11, as well as %rax, but other registers are preserved.
I understand clobbering rax
to store the return code, but why is rcx
, and r11
clobbered in syscall
? Is there a list of the specific syscalls that clobber rcx
/r11
? Is there a convention for the clobbering? Are they assumed safe in any syscalls?
SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR. SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR.
The syscall instruction uses rcx to store the address of the next instruction to return to, and r11 to save the value of the rflags register. These values will then be restored by the sysret instruction.
(The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR.
The SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer.
The syscall instruction uses rcx
to store the address of the next instruction to return to, and r11
to save the value of the rflags
register. These values will then be restored by the sysret
instruction.
This is done by the CPU when executing the CPU instruction, so any OS-specific calling conventions need to avoid using these registers to pass arguments to syscalls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With