Reading — step 1 of 5
Learn
Assembly works with memory directly. Pointers are addresses; arrays are sequential memory.
Memory addressing modes
mov rax, [rbx] ; load 8 bytes from address rbx
mov rax, [rbx + 8] ; address rbx + 8
mov rax, [rbx + rcx*4] ; rbx + rcx*4 — array indexing
mov rax, [rbx + rcx*4 + 8] ; full form: base + index*scale + disp
The scale must be 1, 2, 4, or 8 (matches type sizes).
Loading a string byte-by-byte
section .data
msg db "hello", 0
section .text
_start:
lea rsi, [msg] ; load address of msg into rsi
xor rcx, rcx ; index = 0
.loop:
mov al, [rsi + rcx] ; load one byte
test al, al
jz .done ; null terminator — done
; ... process al ...
inc rcx
jmp .loop
.done:
lea rsi, [msg] is Load Effective Address — gets the address without dereferencing. Same as mov rsi, msg for static data.
Sizes
byte(8 bits) —al,bl, etc.word(16 bits) —ax,bxdword(32 bits) —eax,ebxqword(64 bits) —rax,rbx
When writing memory, specify the size if ambiguous:
mov byte [counter], 0 ; 1 byte
mov word [counter], 100 ; 2 bytes
mov dword [counter], 1000 ; 4 bytes
mov qword [counter], 10000 ; 8 bytes
String operations
x86 has dedicated string instructions:
movs(move string)cmps(compare strings)scas(scan string)lods(load string)stos(store string)
Use with rep prefix for multi-byte ops. Plus rep movsb etc. Modern compilers usually inline manually for performance.
Counting bytes example
section .data
msg db "hello world", 0
section .text
_start:
lea rsi, [msg]
xor rcx, rcx ; counter
.loop:
cmp byte [rsi + rcx], 0
je .done
inc rcx
jmp .loop
.done:
; rcx now holds string length (excluding null)
bss vs data vs text
.text— code (executable).data— initialized data.bss— uninitialized data (zero-initialized at startup)
section .data
counter dq 42 ; 8 bytes, initialized to 42
section .bss
buffer resb 1024 ; 1024 bytes, zeroed
nums resq 100 ; 100 qwords (800 bytes)
Stack frame patterns
Functions use the stack for locals and saved registers:
my_func:
push rbp
mov rbp, rsp ; save frame
sub rsp, 32 ; allocate 32 bytes of locals
mov [rbp-8], rdi ; save first arg
; ... body ...
mov rsp, rbp ; deallocate
pop rbp
ret
This is the System V AMD64 ABI for function calls. Compilers emit this pattern automatically.
Why bare metal matters
Understanding how data lives in memory, how pointers really work, why i++ and ++i differ — knowing assembly demystifies all of that. Even if you never write production assembly, reading it helps debug optimized code, reverse-engineer binaries, and reason about CPU performance.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…