0

I saw a video on youtube where the system calls were present for each register. So does that mean system calls are stored in registers? If it is so how is this possible, I mean They are accessed by kernel which controls the OS. So how can a kernel access the registers and how does kernel know which system call is present in which register?

closed as unclear what you're asking by Rui F Ribeiro, Kusalananda, sebasth, msp9011, Thomas Aug 7 '18 at 19:06

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    It would be helpful to include a link to the video, and do you want the answer in assembly language? – Rob Aug 7 '18 at 16:58
4

There isn't a "system call ... for each register".

The system call interface is hardware architecture dependent. It is often (almost always?) the case that the process stores an integer corresponding to the desired system call in a pre-determined register, and then executes an instruction that triggers the CPU to transfer execution to the kernel's system call handling code. The kernel references the pre-determined register to identify which system call the process is requesting, and then executes the appropriate system call handler.

For example, consider this "hello world" program in x86_64 assembly for Linux:

$ cat hello.s
        .text
        .global
main:
        movq $1,   %rax # write() system call number
        movq $1,   %rdi # first parameter  -- standard output file descriptor
        movq $msg, %rsi # second parameter -- buffer
        movq $14,  %rdx # third parameter  -- buffer length
        syscall         # invoke system call

        movq $60,  %rax # exit() system call number
        movq $0,   %rdi # first parameter  -- exit status
        syscall         # invoke system call; this will never return

        .section .rodata
msg:
        .ascii "Hello, world!\n"

$ gcc hello.s
$ ./a.out
Hello, world!
$

For x86_64, the system call number is stored in register rax, the first parameter to the system all is stored in rdi, the second parameter to the system call is stored in rsi, and the third parameter is stored in rdx.

The example begins by placing the value 1 in register rax. 1 is the system call number for the write() system call. Next, 1 is placed in register rdi; 1 is the file descriptor for standard output and rdi is the register for the first parameter. Then, the address of the msg is stored in register rsi; rsi is the second parameter. Next, 14 is stored in rdx; 14 is the length of the string and rdx is the register for the third parameter. Then the syscall instruction triggers the CPU to transfer control to kernel code. The kernel inspects rax, uses the value in that register (1) to determine what system call to execute (write), then invokes the appropriate handler.

When the kernel finishes executing the system call, control returns the the user space process. It writes 60 to register rax; again rax is the register for the system call number and here 60 is the system call number for exit(). It writes 0 to register rdi – the first (and only) parameter to the exit system call; the exit status. Again, the syscall instruction triggers the CPU to transfer control to kernel code. The kernel inspects rax, uses the value in that register (60) to determine what system call to execute (exit), then invokes the appropriate handler. The exit() handler tears down the process, so that instruction never returns.

Examples that perform the same task will differ from hardware architecture to hardware architecture; it's not even the same for 32-bit Intel.

Not the answer you're looking for? Browse other questions tagged or ask your own question.