1

https://www.cs.fsu.edu/~langley/CNT5605/2017-Summer/assembly-example/assembly.html

I see examples like the following. But I don't find the manual of the syscalls. For example, 60 is for exit and 1 is for write. Is there a complete manual for all syscalls (including the call number and the meaning of the arguments)?

    global  _start
    section .text

_start:

    ; ssize_t write(int fd, const void *buf, size_t count)
    mov rdi,1           ; fd
    mov rsi,hello_world     ; buffer
    mov rdx,hello_world_size    ; count
    mov rax,1           ; write(2)
    syscall

    ; exit(result)
    mov rdi,0           ; result
    mov rax,60          ; exit(2)
    syscall

hello_world:    db "Hello World!",10
hello_world_size EQU $ - hello_world
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user1424739
  • 11,937
  • 17
  • 63
  • 152
  • 1
    Ahh, a classic Professor Langley example! – h0r53 Jan 25 '21 at 17:00
  • 3
    This is x86_64 assembly. System calls are defined at kernel level for this architecture and OS. See https://filippo.io/linux-syscall-table/ – h0r53 Jan 25 '21 at 17:02
  • Read the man pages. That + the standard calling convention, and `asm/unistd.h` for call numbers, is how you can actually make a call. In GAS, you can just include the C header and use `__NR_write` instead of ever hard-coding the number `1`. For NASM, you could pre-process those macro defs into NASM macros. – Peter Cordes Jan 25 '21 at 17:28
  • @PeterCordes Could you show examples for each case? – user1424739 Jan 25 '21 at 17:33
  • 1
    Each case of what? `#include ` just works in a .S file that you build with GCC (not `as` directly). Example of doing that in GAS: [Running 32 bit assembly code on a 64 bit Linux & 64 bit Processor : Explain the anomaly](https://stackoverflow.com/a/2500944). Also related [Hello, world in assembly language with Linux system calls?](https://stackoverflow.com/q/61519222) has more details about system calls. Also semi related: [How to rewrite a files content? Linux x86\_64, assembly, GAS](https://stackoverflow.com/a/53126331) – Peter Cordes Jan 25 '21 at 17:45

1 Answers1

5

System calls are defined at the kernel level (OS specific) for each CPU architecture. The code you provided is x86_64 assembly, so that is your target CPU architecture. Based on your example you are using a Linux kernel. A detailed list of native system calls for x86_64 on Linux can be found here: https://filippo.io/linux-syscall-table/

You can actually edit this table on your system to create your own system calls, but be very careful when doing so! Kernel-level programming can be quite dangerous. The system call table on linux exists in the arch/x86/syscalls directory, which is in the directory that stores your kernel source.

cat /kernel-src/arch/x86/syscalls/syscall_64.tbl

As mentioned by @PeterCordes you can also find system call numbers on your machine in asm/unistd.h, which in the case of my machine was found in /usr/include/x86_64-linux-gnu/asm/unistd_64.h. If you are interested you should be able to find x86 calls in the same directory.

h0r53
  • 3,034
  • 2
  • 16
  • 25
  • I don't see it. Do I need to install some package on Linux to see it. $ cat /kernel-src/arch/x86/syscalls/syscall_64.tbl cat: /kernel-src/arch/x86/syscalls/syscall_64.tbl: No such file or directory – user1424739 Jan 25 '21 at 17:34
  • 1
    `kernel-src` is not the name of the directory. It will have its own name on your system (or linprog for that matter). Try searching for the location of `/arch/x86/syscalls` or better yet, the `syscall_64.tbl` file itself. – h0r53 Jan 25 '21 at 17:37
  • 1
    @user1424739: You don't need a copy of the kernel source code, just look for `asm/unistd_64.h` (which `asm/unistd.h` will #include when building 64-bit code.) – Peter Cordes Jan 26 '21 at 17:59
  • @PeterCordes I'd like to check the original git repo. Which linux git repo has /usr/include/x86_64-linux-gnu/asm/unistd_64.h? – user1424739 Jan 26 '21 at 22:45
  • 1
    @user1424739: none, it's auto-generated from `syscall_64.tbl` of course, by either Linux or glibc. It would be bad to hard-code those numbers in multiple places. And obviously it wouldn't have that full path in a git tree. And BTW, on my Arch GNU/Linux system, those headers are in `/usr/include/asm/unistd_64.h`. – Peter Cordes Jan 26 '21 at 22:52
  • @user1424739 You really shouldn't need a syscall reference outside of your machine in the first place, and IIRC unistd_64.h is generated when you compile your kernel (which I believe is what PeterCordes is saying). Perhaps you're interested in learning more about how syscalls work or even creating your own. Try Googling "linux kernel programming custom system calls C" for a few tutorials, but I will again warn you to *be very careful* and practice in an isolated, recoverable, environment if possible. Corrupting syscall tables can wreck your kernel. – h0r53 Jan 26 '21 at 23:17
  • @h0r53 Can a docker container be used for this purpose? – user1424739 Jan 27 '21 at 01:35
  • @user1424739 I don't think docker containers can load/unload kernel modules, or install a custom kernel, but I'm not really sure. I'd recommend a VM. – h0r53 Jan 27 '21 at 01:52