There are many things that a programmer will need to do that require functionality reserved to the operating system. This typically has to do with which functionality the operating system developer thinks is safe and secure to expose to a user. For example in linux the execve() system call is used to spawn processes as this is a task that requires loading a file into memory not owned by the calling program which is typically prohibited. It also allows the operating system to handle the scheduling and signaling of the second program.
Because system calls require a context switch to kernel code they are typically implemented using an interrupt. x86 has several unused interrupts which can be bound to interrupt service routines and invoked in userland to jump into kernel code. In the case of linux, interrupt 0x80 is used.While system calls are all callable as C functions it is an interesting study to invoke one in assembly. The listing below is written in Intel syntax, and can be assembled using NASM, the netwide assembler. This choice is mostly motivated by my undying hatred of percent signs, and this listing can be fairly easily converted to the AT&T syntax used by the GNU assembler. We will be trying to print some text so we want to use sys_write. The C signature is
ssize_t write(int <i>fd</i>, const void *<i>buf</i>, size_t <i>count</i>)
Since all system calls are invocations of the same interrupt we will also need to pass an argument denoting which syscall we want (0x04 in the case of sys write). A full listing of system calls and associated register values can be found here.
section .text global _start _start: mov eax, 0x04 ;int 0x80 causes the operating system to check register eax for the syscall's code mov ebx, 1 ;fd=1 for stdout mov ecx, msg ;set buf to the string allocated bellow mov edx, len ;count=len(message) int 0x80 ;trigger interrupt ;we also have to invoke the exit system call (sys_exit is call 1) mov eax, 1 ;code 1 for sys_exit mov ebx, 0 ;equivalent to exit(0) int 0x80 section .data msg db "My Love's the Bogans!",0xa ;0xa is newline len equ $ - msg ;msg is a pointer to the head of the string $ is an alias in NASM for the previous address, in this case the end of the string
Finally, this can be compiled with
nasm -felf64 bogans.asm ld bogans.o -o bogans
Running the resulting binary should print the text then exit. While this is an atypical amount of work to print some text it is a good example of how system calls work at a low level.