X86 Assembly/Interfacing with Linux
Prerequisites: X86 Assembly/X86 Interrupts, X86_Assembly/GAS_Syntax
Using syscalls
Syscalls are a way of interfacing directly with Linux. Most often, you could use the C library instead and get portability.
Syscalls are identified by a number that must be in EAX before making the interrupt. If the syscall takes an argument, it is placed in EBX. Further arguments are placed in EBX ,ECX, EDX, ESI and EDI, in that order.
Syscalls do not use the stack at all, and the stack will not be touched in any way.
void _exit(int status)
Syscall Number: 1
You often see Linux assembly programs ending like this:
movl $1, %eax # system call number 1 = _exit movl $0, %ebx # argument for _exit int $0x80
The 1 in EAX is the number of the _exit syscall, and 0 is the argument. Sometimes, people do not bother setting EBX as they don't care what return value they get. It is however bad practice, as a non-zero exit value in Linux means failure.
Beware: Output can be buffered, which will make it disappear if you call _exit too early. _exit is probably overused because it always works, even if you broke your stack. The correct solution is the not destroy your stack and use ret from main instead. Of course, you can use C's exit() too.
ssize_t write(int fd, const void *buf, size_t count);
Syscall Number: 4
Example:
.data newline: .ascii "\n" .text [...] movl $4, %eax # sys_write movl $1, %ebx # file descriptor 1 = stdout leal newline, %ecx # void* (address of bytes to write) movl $1, %edx # length of bytes to write int $0x80 # execute syscall
Getting system call numbers from their names
On Ubuntu Precise (32-bit), they can be seen in /usr/include/i386-linux-gnu/asm/unistd_32.h. A more portable (over different distributions) method would be using the C compiler. In the Bourne shell you can quickly just start the C preprocessor and include syscall.h and look up your syscall number over stdout/stdin:
$ echo "#include<syscall.h>\nSYS_write" | cpp | tail -n1 4
The final line has your syscall number, it is expanded from the preprocessor macro name you wrote.
Getting more information on a specific system call
System calls are in man's section 2. Example: man 2 write.