100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Memory Addressing Modes

How assembly instructions specify where an operand's value actually lives — immediate, register, direct, and indexed addressing explained with examples.

FoundationsIntermediate10 min readJul 10, 2026
Analogies

Memory Addressing Modes

An addressing mode is the specific way an instruction's operand tells the CPU where to find the actual value it should operate on. The same mnemonic, mov, behaves completely differently depending on the addressing mode of its operands: mov eax, 5 places a literal constant into a register, while mov eax, [rbx] tells the CPU to treat the value in RBX as a memory address, go fetch the 4 bytes stored there, and load that into EAX. Choosing the right addressing mode is central to writing correct and efficient assembly, because array traversal, struct field access, and pointer dereferencing are all implemented purely through the addressing modes an ISA provides — there is no separate 'array' or 'struct' concept at the machine level, only combinations of base registers, index registers, scale factors, and displacement constants.

🏏

Cricket analogy: Addressing modes are like the different ways a captain can instruct a fielder: 'stand at exactly deep square leg' (a fixed direct address) versus 'stand wherever the previous fielder is plus five meters' (register-relative addressing) — same instruction format, completely different meaning based on how the location is specified.

Immediate, Register, and Direct Addressing

Immediate addressing embeds the actual constant value right inside the instruction itself, as in mov eax, 42, where 42 is encoded directly into the machine code bytes and requires no memory access at all beyond fetching the instruction. Register addressing uses a register's contents directly as the operand, such as add eax, ebx, which is fast because both operands already live in on-chip storage with no RAM access required. Direct (absolute) addressing specifies a fixed, literal memory address to read from or write to, as in mov eax, [0x404000], which is useful for accessing a global variable at a known, fixed location but becomes fragile the moment code is relocated in memory, which is why position-independent code typically avoids pure direct addressing in favor of RIP-relative addressing instead.

🏏

Cricket analogy: Immediate addressing is like a pre-decided fixed target score written on the scoreboard before the innings even starts — the value 42 doesn't need to be looked up anywhere, it's baked into the plan itself.

Indirect and Indexed (Base + Index + Scale + Displacement) Addressing

Register-indirect addressing treats a register's value as a pointer: mov eax, [rbx] reads the 4-byte value found at the memory address currently stored in RBX, which is how dereferencing a pointer variable is implemented in every compiled C program. x86-64's most powerful mode combines four components in a single instruction — base register, index register, scale factor, and constant displacement — written as mov eax, [rbx + rcx*4 + 8], which computes the effective address as RBX + (RCX × 4) + 8 in one step; this single instruction form is precisely how compilers implement array indexing like array[i] for a 4-byte-element array, where RBX is the array's base address, RCX is the index i, the scale factor 4 matches the element size, and the displacement offsets past any leading struct fields. Understanding this addressing form explains why choosing data types with power-of-two sizes (1, 2, 4, or 8 bytes) lets a compiler use the hardware's built-in scale factor instead of emitting extra multiply instructions.

🏏

Cricket analogy: Indirect addressing is like a captain saying 'throw the ball to whoever RBX is currently pointing at' rather than naming a fixed fielder — the actual target is looked up through a reference that can change between overs.

asm
; x86-64 NASM: addressing modes side by side
section .data
    numbers dd 10, 20, 30, 40   ; an array of 4-byte (dword) integers

section .text
    global _start

_start:
    mov     eax, 42              ; immediate addressing: literal constant
    mov     ebx, eax             ; register addressing: EBX = EAX
    mov     rcx, numbers         ; RCX now holds the array's base address

    mov     edx, [rcx]           ; register-indirect: reads numbers[0] -> 10
    mov     esi, 2               ; index i = 2
    mov     edi, [rcx + rsi*4]   ; base+index+scale: reads numbers[2] -> 30

    mov     eax, 60
    xor     rdi, rdi
    syscall

Direct (absolute) addressing embeds a fixed memory address into the instruction, which breaks under Address Space Layout Randomization (ASLR) and position-independent executables, since the program's actual load address changes each run. Modern compilers default to RIP-relative addressing (e.g. mov eax, [rip + var]) for this exact reason — always prefer it over hardcoded absolute addresses in real-world assembly.

  • An addressing mode determines how an instruction's operand locates its actual value: immediate, register, direct, or indirect/indexed.
  • Immediate addressing embeds a literal constant directly in the instruction's encoded bytes, needing no memory access.
  • Register addressing uses a register's contents directly as the operand, the fastest option since no RAM access occurs.
  • Direct addressing reads or writes a fixed literal memory address, but is fragile under ASLR/relocation.
  • Register-indirect addressing ([reg]) dereferences a pointer stored in a register, the basis of pointer dereferencing.
  • Base + index*scale + displacement addressing computes array[i]-style access in a single instruction.
  • Modern position-independent code favors RIP-relative addressing over hardcoded absolute addresses.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#AssemblyLanguageStudyNotes#MemoryAddressingModes#Memory#Addressing#Modes#Immediate#StudyNotes#SkillVeris#ExamPrep