When we talk about computer programs, they do various tasks. Like printing a string to screen, handling a file, getting user input, existing the program etc. All of these tasks are not done by single programs. Programs get support from operating system to do some special things. Actually what happens hear is program calls Kernel to handle these requests. Windows systems have there own kernel while Linux distributions have there own Linux kernel. When a program want to print a string to screen it'll load arguments (string) and call specific system call. When the kernel receive the call it'll do what program wanted.
Yes there are many system calls for do various things. Like exit sys call, print sys-call etc. But how we identify a system call?. There is a unique number for every system call. When we want to use a sys call we call it with it's own number.
Calling procedure of a system call
1) Load EAX with the system call number
In above I mentioned that every system call has a unique sys call number. Before we call kernel to handle the system call we should specify the system call number. So kernel knows which sys call we want to execute. We store this Sys call number on the EAX register.
But how we can know these system call numbers? . In your Linux machine these are stored in /usr/include/asm/unistd.h file. Let's see that file.
You can see the system call number for exit is 1. Also write sys-call's number is 4.
2) Load arguments into EBX, ECX, EDX, EDI and ESI.
A system call is like a function. So when we call it we should supply arguments. For an example if we call the exit system call we should provide the status value. We need to put first argument on EBX, second one on ECX , third on EDX etc.As this way we can use EBX, ECX, EDX, EDI and ESI to store arguments. If there are more we can use the stack.
3) Call the kernel
This is the final step of making a system call. We use int 0x80 instruction to stop execution of our assembly program and handover our system call request to kernel.
Exit system call
The most easy system call to understand is exit system call. It will simply quit the program. Following small assembly code will demonstrate how we can use exit sys call.
global _start section .text _start: mov eax, 0x1 mov ebx, 0x5 int 0x80
Think about above code. It'll call exit system call which cause program to exit. There are three steps we did in above sys-call.
First we copied 0x1 (in hexadecimal) to eax register. That is the sys-call number. We know unique number of exit sys-call is one. So that is the way we tell kernel which sys-call we wanted to execute. We should fill eax with it's sys-call number.
As the second step we copied 0x5 into ebx. What we expected from it? It is status value. When a program quite in Linux there is a special value called status value. It indicated whether a program exited successfully or not. If a program exit with success it will return zero. Yes you are correct, we found such a situation at functions in C programming. So hear we returned five. (0x5 in hexadecimal) . That is optional we can return any number. But one another thing. After program completed and exited we can get that return value by entering echo $? in our Linux terminal.
As the final step we used a command int 0x80 This is called interrupt command. By using that we can break normal program procedure and awake kernel to to rest. Now kernel starts it's job. First it'll check eax for sys-call number After it figures out we want exit system call it checks ebx for status value. Finally it'll do what we wanted .
So I think you understood how we can use System calls in Assembly. In next article we are going to see how we can write a hello world program with the system calls. Thank you for reading.