Read a File via syscalls
open/read/write/close a file using only Linux syscalls.
Code
; cat_file(path) rdi = path (C string)
section .rodata
buf_len: equ 4096
section .bss
buf: resb buf_len
section .text
global cat_file
cat_file:
; open(path, O_RDONLY, 0) syscall #2
mov rax, 2
mov rsi, 0 ; O_RDONLY
xor rdx, rdx
syscall
test eax, eax
js .fail ; negative -> error
mov r12, rax ; save fd in callee-saved r12
push r12 ; preserve r12 across our own calls
.read_loop:
; read(fd, buf, buf_len) syscall #0
mov rax, 0
mov rdi, r12
lea rsi, [rel buf]
mov rdx, buf_len
syscall
test rax, rax
jle .close ; 0 -> EOF, <0 -> error
mov r13, rax ; save bytes read
; write(1, buf, n) syscall #1
mov rax, 1
mov rdi, 1
lea rsi, [rel buf]
mov rdx, r13
syscall
jmp .read_loop
.close:
; close(fd) syscall #3
mov rax, 3
mov rdi, r12
syscall
pop r12
xor eax, eax
ret
.fail:
mov rax, -1
retExplanation
This implements a tiny 'cat' using only Linux syscalls: open (2) returns a file descriptor, read (0) fills a buffer and returns bytes read (0 at EOF), write (1) sends it to stdout, close (3) releases the fd. The fd is kept in r12 because read and write both clobber rax (their return value). 'test eax,eax; js' checks for the negative return that signals an error.
More Assembly Snippets
Hello World via Linux syscall
A freestanding x86-64 program that prints and exits using only kernel syscalls.
Function Call Convention (System V AMD64)
Pass args in registers, preserve callee-saved regs, keep rsp 16-byte aligned.
Loop Summation (1..N)
Sum integers 1..N with a counted loop using dec/jnz.
strlen — Scan Until NUL
Compute C-string length by scanning memory until a zero byte.
memcpy — Copy with rep movsb
Use the rep movsb string instruction for a tight memory copy.
Bit Manipulation: popcount, ctz, abs
Use BMI/ABM instructions for branchless bit operations.