Master the fundamental concepts of x86 assembly (intel syntax) through this focused micro-challenge.
Userspace cannot read disks or map memory directly. On x86-64 Linux you load a number into rax, arguments into rdi/rsi/rdx/r10/r8/r9, and execute syscall. glibc's write wrapper adds cancellation points and error handling; your assembly calls the kernel raw. strace logs these crossings; seccomp filters them in Docker.
nasmLoading…
| Syscall | rax | arg1 (rdi) | arg2 (rsi) | arg3 (rdx) |
|---|---|---|---|---|
| read | 0 | fd | buf | count |
| write | 1 | fd | buf | count |
| exit | 60 | status |
Errors return -errno in rax (negative values). Compare against zero after syscall.
For this exercise, you will wrap read, write, and exit as callable functions. This task asks you to preserve the AMD64 argument registers your caller sets, because botching the wrapper is how bare-metal demos write to the wrong fd silently.
Keep the relevant man page, ABI doc, or Rust reference chapter open while you work. When your output disagrees with the reference implementation on the same machine, the mismatch is usually an alignment rule, an off-by-one terminator, or a register slot you misread in GDB. Skim the official documentation for the tool or ABI named in the exercise; the prose changes, but register roles, syscall numbers, and ownership rules stay stable across releases.
Implement system call wrappers for common operations.
Requirements:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github