I'm learning x86_64 assembly on Linux and I've run into some conflicting information that I was hoping could get cleared up. On one hand, I've read that for syscall arguments, you would use registers in the order of rdi, rsi, rdx, and so on. But on the other hand I've read that you use the registers rbx, rcx, rdx, and so on. One person told me that the reasoning for this is because of ABI, but I'm not totally understanding what that exactly means.
Why are there two formats for this and which would be the proper one to use?
syscall is an instruction in x86-64, and is used as part of the ABI for making system calls. (The 32-bit ABI uses int 80h or sysenter , and is also available in 64-bit mode, but using the 32-bit ABI from 64-bit code is a bad idea, especially for calls with pointer arguments.)
On a 64-bit x86 Linux machine, there's a special instruction "syscall" to make system calls: a request to the kernel to do something. You identify which system call you'd like to make by loading a syscall number into register rax.
To execute a system call, the system call number is saved in the general-purpose register (GPR) eax . The arguments of the corresponding system call are stored in the GPRs ebx , ecx , and edx .
According to this Wikibooks page, it depends on which instruction you are using to perform the syscall.
If you are using int $0x80
(the 32-bit ABI with call numbers from asm/unistd_32.h
), then you should use eax
for the syscall number, and ebx
, ecx
, edx
, esi
, edi
, and ebp
for the parameters (in that order).
If you are using the syscall
instruction (the 64-bit ABI with native call numbers from asm/unistd.h
), you should use rax
for the syscall number and rdi
, rsi
, rdx
, r10
, r8
, and r9
for the parameters.
What are the calling conventions for UNIX & Linux system calls on i386 and x86-64
In 64-bit mode syscall
is preferred because it's faster, available on all x86-64 Linux kernels, and supports 64-bit pointers and integers. The int 0x80
ABI truly takes input in ecx
, not rcx
, for example, making it unusable for write
or read
of a buffer on the stack in 64-bit code.
What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?.
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