I have a piece of assembly code which does a write system call (is that correct?) via
call write@plt
Before doing so, the values of rax
, address rsp
, edi
, rsi
and rdx
are set/modified.
How do I know which registers are used as arguments for write or system function calls in general?
My guess is that for write it's rsp
, edi
and rsi
since in C
it takes 3 arguments:
ssize_t write(int fd, const void *buf, size_t nbytes);
When you
call write@plt
you don't directly invoke the write(2) system call, but a tiny wrapper around that (a tiny C function which does the syscall and setserrno
on failure).So this
write
function is using the standard C calling convention, defined in the ABI (application binary interface). For Linux x86-64 read the SysV ABI interface for x86-64Read also vdso(7) to find out a bit more about how some syscalls are actually done. Others might use the
SYSENTER
machine instruction, etc... Some details are given in the ABI spec (stricto sensu, the real syscall is not using any stack and passes arguments & results thru registers). Read also the Linux Assembly HowTo (more focused on 32 bits x86).Also, C standard libraries for Linux are free software, generally GNU glibc or perhaps musl-libc, etc... So study their source code to understand exacty how
write
is implemented.