Skip to main content
← All posts

Part 11: Linux 64-Bit System Calls, NASM Macros & Dynamic Memory Allocation

Md. Harun-Or-RoshidNov 5, 20263 min readArticle
Part 11: Linux 64-Bit System Calls, NASM Macros & Dynamic Memory Allocation

Curriculum Capstone & Kernel Interfacing

Welcome to the grand finale of our 11-part assembly language masterclass. Having mastered computer architecture, memory addressing, arithmetic, bitwise manipulation, branching, and calling conventions, we now confront the boundary between user-space application code and the Linux operating system kernel. In Part 11, we master the 64-bit syscall instruction, explore the Linux System Call Dispatch Table, author sophisticated multi-line NASM macros, perform low-level file I/O operations, allocate anonymous virtual memory via sys_mmap, and examine hybrid C/Assembly integration.

1. The Linux x86-64 System Call Architecture

In 64-bit Linux, user processes run in CPU privilege Ring 3 (unprivileged user space). Hardware access, file writing, process creation, and network transmission are restricted to Ring 0 (kernel space). The transition from Ring 3 to Ring 0 is initiated via the high-performance syscall instruction (which reads the kernel entry address from the hardware MSR_LSTAR Model-Specific Register).

Syscall Number (RAX)System Call NameArgument 1 (RDI)Argument 2 (RSI)Argument 3 (RDX)Argument 4 (R10)
0sys_readunsigned int fdchar *bufsize_t count-
1sys_writeunsigned int fdconst char *bufsize_t count-
2sys_openconst char *filenameint flagsumode_t mode-
3sys_closeunsigned int fd---
9sys_mmapvoid *addrsize_t lenint protint flags
60sys_exitint error_code---

CRITICAL SYSCALL REGISTER DIFFERENCE: RCX vs. R10

Notice that while standard C functions pass the 4th argument in RCX, Linux system calls pass the 4th argument in R10! This is because the CPU hardware syscall instruction internally uses RCX to save the user-space return Instruction Pointer (RIP) and R11 to save RFLAGS.

2. Multi-Line NASM Macros with Local Labels

NASM allows defining sophisticated multi-line macros using %macro and %endmacro. To prevent duplicate symbol collisions during macro expansion, local labels within a macro must be prefixed with %%:

; Macro: write_str buffer_label, length

%macro write_str 2

mov rax, 1 ; sys_write

mov rdi, 1 ; stdout fd

lea rsi, [%1] ; Buffer address

mov rdx, %2 ; Length

syscall

%endmacro


; Macro: exit_process status_code

%macro exit_process 1

mov rax, 60 ; sys_exit

mov rdi, %1

syscall

%endmacro

3. Dynamic Memory Allocation via sys_mmap

While the legacy sys_brk syscall expands the process data segment, modern production memory allocators (like jemalloc or glibc malloc) allocate dynamic memory pages directly from the Linux kernel using anonymous memory mappings (sys_mmap, syscall 9):

; Allocate 64 KB (16 pages) of Read/Write zero-initialized memory

mov rax, 9 ; sys_mmap

xor rdi, rdi ; addr = NULL (kernel selects virtual address)

mov rsi, 65536 ; length = 64 KB

mov rdx, 3 ; prot = PROT_READ (1) | PROT_WRITE (2)

mov r10, 0x22 ; flags = MAP_PRIVATE (0x02) | MAP_ANONYMOUS (0x20)

mov r8, -1 ; fd = -1 (no underlying file)

xor r9, r9 ; offset = 0

syscall

; On return: RAX contains pointer to newly allocated 64KB virtual memory buffer!

; If RAX < 0 (e.g. -ENOMEM), allocation failed.

4. Series Conclusion & Next Engineering Horizons

Congratulations on completing the Mastering Modern Assembly Language curriculum! Over these 11 intensive engineering installments, you have journeyed from the silicon gates of the CPU to the cutting edge of 64-bit systems programming. You now possess the mental model required to analyze compiled binaries, audit systems for memory corruption vulnerabilities, optimize algorithms for cache throughput, and write blazing-fast low-level software.

  • Explore our companion series: Microprocessor & Microcontroller Architecture to understand hardware pinouts and silicon fabrication.
  • Investigate vector SIMD programming using AVX2 and AVX-512 extensions (YMM/ZMM registers).
  • Practice dynamic binary analysis and reverse engineering using Ghidra, IDA Pro, and GEF.
Share:
Share on X
Share on LinkedIn
Share on Facebook
Share on Reddit
Share on WhatsApp
Share on Telegram
Copy link

Related reading