I came across this wikibook which shows that there can be 7 arguments passed to syscall
, and I want to understand what is the purpose of each one of them.
This is not specified in the man page.
Also, I have found a table of the arguments you can pass to each syscall but I don't necessarily understand the common ground between them.
Ideally, I'm looking for an answer that specifies
arg #1 - pid
arg #2 - ...
Architecture is x86-64.
The table you linked to provides the list of arguments you're asking for.
I think what may be confusing you is that syscall
doesn't perform a single operation. Rather, it's a general-purpose API for anything you might want to ask the kernel to do -- open a file, map memory, fork a new process, and so on.
The specific operation you want the kernel to do is selected using the syscall number. Just picking the first one from the table, syscall 0 (known as sys_read
) reads from a file.
Obviously, the operations performed by the different syscalls require different arguments. Staying with the sys_read
example, we see in the table that it takes three arguments: The file descriptor (fd
), a pointer to a buffer (buf
) and a number of bytes to read (count
). So if you wanted to call this syscall, you would do it as follows:
#include <sys/syscall.h>
// Assuming these have been initialized appropriately.
unsigned int fd = ...;
char * buf = ...;
size_t count = ...;
syscall(SYS_read, fd, buf, count);
This answer has more information on when you might want to choose to use syscall
. The short version is that the reasons to use syscall
are few and far between.
Edit: As @PeterCordes points out, syscall numbers differ between ABIs, so you should use the constants defined in sys/syscall.h
instead of hardcoding syscall numbers yourself.
The answer you linked in the last paragraph describes when you'd want to use the
syscall(int, ...)
wrapper function in C. Not thesyscall
instruction to inline a syscall in asm. If you're playing around with toy programs and not linking libc, you usually want to use syscall directly.@PeterCordes: is there a
syscall
instruction? On older time we usedINT
, laterENTER
, and now I think just aJMP
(no real address, selector table of "segment" has the data on which ring and which kernel address to execute)@GiacomoCatenazzi: Yes, AMD introduced
syscall
, and reworked it for AMD64. It's the only way to use the 64-bit system-call ABI from user-space on Linux. It's not plausible thatenter
could be used for system calls - it's a slow way to make a stack frame; perhaps you're thinking ofsysenter
(Intel's 32-bit fast-system-call instruction)? See What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? for the difference and an example of using Linuxwrite
both ways.@MartinB: Oh, you're right, this is tagged
[x86-64]
but not[assembly]
, and hassyscall(2)
in the title. We get many questions about thesyscall
instruction, and the OP's first link was about assembly language. In the tags I follow I've basically never seen one like this, and I skimmed too quickly to notice I was making a wrong assumption >.<Since you're giving a portable answer, you don't want to hard-code the call numbers - they differ between ISAs, even between i386 and amd64. Use
__NR_read
orSYS_read
after including the appropriate headers (<asm/unistd.h>
or<sys/syscall.h>
).__NR_read
is 0 on x86-64, but not on i386.