Linux – Why did the system call registers and order change from Intel 32bit to 64bit

historylinuxsystem-calls

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, in ebx, ecx, edx, esi, edi, and ebp, 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, in rdi, rsi, rdx, r10, r8, and r9, 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 because SYSCALL, a new 64-bit instruction used to invoke system calls, needs %rcx for other purposes.