I was working on memorizing the order of the Linux system calls so I could more easily identify this. And, then I found this paper here, and it says,
To make a system call in 32-bit Linux, place the system call number in
eax
, then its arguments, in order, inebx
,ecx
,edx
,esi
,edi
, andebp
, then invoke int 0x80.
And, then,
To make a system call in 64-bit Linux, place the system call number in
rax
, then its arguments, in order, inrdi
,rsi
,rdx
,r10
,r8
, andr9
, then invoke syscall.
How come the order gets so mutilated between 64 bit and 32 bit? I know this question may be historical rather than technical.
This is totally decided by the kernel, right? Are there technical reasons to favor the newer convention?
Best Answer
It is largely up to the kernel, however there is a good reason to use the chosen calling convention on 64-bit x86: it matches the chosen user-space convention. The System V x86-64 ABI, which is what Linux uses, specifies that functions use registers
%rdi
,%rsi
,%rdx
,%rcx
,%r8
, and%r9
to pass arguments. The system call convention is very close to that: the only difference is that it uses%r10
instead of%rcx
, mainly becauseSYSCALL
, a new 64-bit instruction used to invoke system calls, needs%rcx
for other purposes.