My running x86-64 assembly notebook. Each note = my comment in a callout, a tiny example under it, and the Intel SDM page to read more.
[ ] = memory access 2026-09-26[ ] to say: go to memory. Without brackets you work with the value itself. With brackets you use the value as an address and read/write what is stored there.mov rax, rbx ; NO brackets -> copy the value of rbx into rax
mov rax, [rbx] ; brackets -> READ 8 bytes from the address stored in rbx
mov [rbx], rax ; brackets on the left -> WRITE rax to that address
mov rax, [rbx+rcx*8+16] ; full form: [base + index*scale + displacement]
mov rax, rbx gives 0x7ffc1000 · mov rax, [rbx] gives 0x2a[ ] but does not reference memory. It only does the address math and keeps the result in the register.; rbx = 0x1000, memory at 0x1008 holds 0x2a
mov rax, [rbx+8] ; goes to memory -> rax = 0x2a (the value)
lea rax, [rbx+8] ; only math -> rax = 0x1008 (the address)
* = assembly [base + offset] 2026-09-26* means: follow the pointer. In assembly this becomes [ ]. The address inside can be a base register alone ([eax]), base + immediate ([esi+34]), or base + register ([ecx+eax]). The address is computed at run time.; pseudo C ; assembly
*eax = 1; mov dword ptr [eax], 1 ; write constant (must give a size!)
ecx = *eax; mov ecx, [eax] ; read from address in eax
*eax = ebx; mov [eax], ebx ; write ebx to that address
*(esi+34) = eax; mov [esi+34], eax ; base + immediate offset
eax = *(esi+34); mov eax, [esi+34] ; read the same slot back
edx = *(ecx+eax); mov edx, [ecx+eax] ; base + register offset
[esi+34] = struct member — esi holds the struct start, 34 is the fixed distance of one member. [ecx+eax] = data buffer — ecx is the buffer start, eax is an index only known at run time.