Hello world in Linux x86-64 assembly
A “hello world” program writes to stdout (calling
write) then exits (calling
The assembly program
hello.s below does that on Linux x86-64.
global _start section .text _start: mov rax, 1 ; write( mov rdi, 1 ; STDOUT_FILENO, mov rsi, msg ; "Hello, world!\n", mov rdx, msglen ; sizeof("Hello, world!\n") syscall ; ); mov rax, 60 ; exit( mov rdi, 0 ; EXIT_SUCCESS syscall ; ); section .rodata msg: db "Hello, world!", 10 msglen: equ $ - msg
To run it:
$ nasm -f elf64 -o hello.o hello.s $ ld -o hello hello.o $ ./hello Hello, world!
The first important document is the x86-64 ABI specification, maintained by Intel. (Weirdly, the official location for the ABI specification is some random dude’s personal GitHub account. Welcome to the sketchy world of assembly.) The ABI specification describes system calls in the abstract, as it applies to any operating system. Importantly:
- The system call number is put in
- Arguments are put in the registers
r9, in that order.
- The system is called with the
- The return value of the system call is in
rax. An error is signalled by returning
The second document
is the Linux 64-bit system call table.
This specifies the system call number for each Linux system call.
For our example, the
write system call is
Finally, you want the man pages for the system calls, which tell you their signature, e.g.:
#include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);
Armed with this, we know to:
- put the system call number
- put the
- put the
- put the
- finally, call
More by Jim
- The inception bar: a new phishing method
- The hacker hype cycle
- Project C-43: the lost origins of asymmetric crypto
- How Hacker News stays interesting
- My parents are Flat-Earthers
- The dots do matter: how to scam a Gmail user
- The sorry state of OpenSSL usability
- I hate telephones
- The Three Ts of Time, Thought and Typing: measuring cost on the web
- Granddad died today
- Your syntax highlighter is wrong