7

According to System V X86-64 ABI, function calls in the applications use the following sequence of registers to pass integer arguments:

rdi, rsi, rdx, rcx, r8, r9

But system call arguments (other than syscall number) are passed in another sequence of registers:

rdi, rsi, rdx, r10, r8, r9

Why does the kernel use r10 instead of rcx for the fourth argument? Is it somehow related to the fact that rcx is not preserved while r10 is?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ruslan
  • 18,162
  • 8
  • 67
  • 136
  • `r10` is used for passing the http://c2.com/cgi/wiki?StaticChain pointer, in languages where that's needed (ABI footnote 13 and Figure 3.4 (pg21)). Otherwise `r10` is caller-saved: i.e. functions are free to use it *without* saving/restoring it. I don't see any commentary in the ABI about why they chose to use `r10` for syscalls instead of `rcx`. The kernel does destroy `rcx` and `r11`, though. – Peter Cordes Aug 27 '15 at 21:59
  • http://stackoverflow.com/questions/21322100/linux-x64-why-does-r10-come-before-r8-and-r9-in-syscalls discussed this question from a different angle. Some of the comments are relevant, but in the end, @technosaurus says "I never did track down exactly why rcx was used to save the entry point instead of r10". So we haven't figured out why they didn't keep the register -> arg mapping for system calls the same as for function calls. It appears it would have been possible. – Peter Cordes Aug 27 '15 at 22:10

1 Answers1

14

X86-64 system calls use syscall instruction. This instruction saves return address to rcx, and after that it loads rip from IA32_LSTAR MSR. I.e. rcx is immediately destroyed by syscall. This is the reason why rcx had to be replaced for system call ABI.

This same syscall instruction also saves rflags into r11, and then masks rflags using IA32_FMASK MSR. This is why r11 isn't saved by the kernel.

So, these changes reflect how the syscall mechanism works. This is why the kernel is forced to declare rcx and r11 as not saved and even can't use them for parameter passing.

Reference: Intel's Instruction Set Reference, look for SYSCALL.

Ruslan
  • 18,162
  • 8
  • 67
  • 136