Reputation: 8397
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?
Upvotes: 12
Views: 11899
Reputation: 13016
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?.
Upvotes: 14