1. Home
  2. Computer Organization & Architecture
  3. Addressing Modes

Addressing Modes

Where is the operand? Follow one LOAD instruction through nine addressing modes in 3D, from immediate and direct to indexed and auto-increment, and count the memory reads each one needs.

Interactive 3DBeginner12 min readCOAUpdated

Drag to rotate · Right-drag to pan · Click, then scroll to zoom · Space play · ←→ step

What's happening

Pseudocode

    Try this in the 3D model

    • Run Indexed, then PC-relative. Both add 40 to a register. Which register, and why is the PC 6 and not 5?
    • Run Indirect. How many memory reads does it need for one operand?
    • Compare Register (R0 = 45) with Register indirect (R0 = 52). What does the number 45 mean in each case?
    • Press Compare all modes. Which modes need no memory read for the operand at all?
    • After Auto-increment runs, R1 = 46. Which address would the same instruction read next time?

    Where is the operand?

    An instruction like LOAD R0, … says what to do: copy something into register R0. But where is that something? It might be inside the instruction, in a register, or somewhere in memory. The addressing mode is the rule the CPU uses to find it.

    A typical instruction has three parts:

    opcode mode address field
    what to do (LOAD) how to read the field a number or a register

    When the operand is in memory, the address the CPU finally reads from is called the effective address (EA).

    The machine in the model

    Every mode in the model runs on the same small machine, so you can compare the answers:

    Item Value
    The instruction at address 5, address field = 40
    PC after the fetch 6 (it already points to the next instruction)
    R1 45
    R2 (index register) 2
    Memory 40 to 46 43, 17, 31, 8, 26, 52, 19

    The nine modes

    Mode Written as Effective address R0 in the model Operand reads
    Immediate LOAD R0, #40 none, the operand is 40 40 0
    Register LOAD R0, R1 none, the operand is in R1 45 0
    Direct (absolute) LOAD R0, 40 40 43 1
    Indirect LOAD R0, @40 M[40] = 43 8 2
    Register indirect LOAD R0, (R1) R1 = 45 52 1
    Indexed LOAD R0, 40(R2) 40 + R2 = 42 31 1
    PC-relative LOAD R0, 40(PC) PC + 40 = 46 19 1
    Auto-increment LOAD R0, (R1)+ R1 = 45, then R1 becomes 46 52 1
    Auto-decrement LOAD R0, −(R1) R1 becomes 44 first, EA = 44 26 1

    Books write these differently. Indirect is often (40) instead of @40, and some machines mark modes with bits instead of symbols. The ideas are the same.

    The operand is already in the CPU

    • Immediate: the number is part of the instruction. It’s the fastest mode, but the value is fixed when the program is written.
    • Register: the instruction names a register, and the register holds the value.

    The address is in the instruction

    • Direct: the address field is the memory address.
    • Indirect: the address field points to a memory word that holds the real address, like a pointer stored in memory. It is flexible but needs two memory reads.

    The address is in a register

    • Register indirect: the register holds the address, like *p in C.
    • Auto-increment (R1)+: uses R1 as the address, then adds one item’s size to R1. Repeating the instruction walks forward through an array.
    • Auto-decrement −(R1): subtracts first, then uses R1. Together with auto-increment this gives push and pop for a stack.

    In the model memory holds one number per address, so the step is 1. On a real byte-addressed machine it is the size of the operand, for example 4 for a 32-bit word.

    Address = register + constant

    • Indexed: EA = address field + index register. The field is where an array starts, and the register picks the element.
    • Base register: the same addition, with the roles swapped. A base register holds where a block of data (or the whole program) starts, and the field is the offset inside it.
    • PC-relative: EA = PC + field. It is used for branches. The PC has already moved past the current instruction during the fetch, so the distance is measured from the next instruction.

    Which mode for which job?

    In a program Mode
    x = x + 1 (the constant 1) immediate
    a local variable kept in a register register
    a global variable direct
    *p register indirect
    a pointer that is itself stored in memory indirect
    a[i] indexed
    if / loop jumps PC-relative
    *p++ and pop auto-increment
    push auto-decrement

    Speed versus flexibility

    Every memory read costs time, so modes that keep the operand in the CPU are fastest and indirect is slowest. More modes also make instructions harder to decode. That is one reason RISC processors keep only a few (register, immediate, base + offset and PC-relative), while older CISC machines like the VAX had many more.

    When a question asks for the number of memory references of an instruction, check whether it counts the instruction fetch too. The model counts only the reads for the operand.

    Code

    mem = {40: 43, 41: 17, 42: 31, 43: 8, 44: 26, 45: 52, 46: 19}
    A = 40                                   # address field of the instruction
    
    def load(mode, regs):
        """Return (effective address, operand, memory reads) for LOAD R0 with this mode."""
        if mode == 'immediate':              # LOAD R0, #40
            return None, A, 0
        if mode == 'register':               # LOAD R0, R1
            return None, regs['R1'], 0
        if mode == 'direct':                 # LOAD R0, 40
            return A, mem[A], 1
        if mode == 'indirect':               # LOAD R0, @40
            ea = mem[A]                      # first read: the pointer
            return ea, mem[ea], 2
        if mode == 'register indirect':      # LOAD R0, (R1)
            return regs['R1'], mem[regs['R1']], 1
        if mode == 'indexed':                # LOAD R0, 40(R2)
            ea = A + regs['R2']
            return ea, mem[ea], 1
        if mode == 'pc-relative':            # LOAD R0, 40(PC)
            ea = regs['PC'] + A              # PC already points to the next instruction
            return ea, mem[ea], 1
        if mode == 'auto-increment':         # LOAD R0, (R1)+
            ea = regs['R1']
            regs['R1'] += 1                  # step the pointer AFTER using it
            return ea, mem[ea], 1
        if mode == 'auto-decrement':         # LOAD R0, -(R1)
            regs['R1'] -= 1                  # step the pointer BEFORE using it
            ea = regs['R1']
            return ea, mem[ea], 1
    
    for mode in ['immediate', 'register', 'direct', 'indirect', 'register indirect',
                 'indexed', 'pc-relative', 'auto-increment', 'auto-decrement']:
        regs = {'R1': 45, 'R2': 2, 'PC': 6}
        ea, value, reads = load(mode, regs)
        print(f'{mode:18} EA={ea}  R0={value}  reads={reads}')

    Common mistakes

    • PC-relative with the old PC. The PC is incremented during the fetch, so the base is the address of the next instruction.
    • Register vs register indirect. In register mode R1 is the value. In register indirect R1 holds the address of the value.
    • Indirect as if it were direct. With @40 the operand is not M[40] but M[M[40]].
    • Getting the order wrong for auto-increment and auto-decrement. Increment happens after the access, decrement before it.
    • Counting memory references. State whether the instruction fetch is included. Exam answers differ by one depending on that choice.

    Complexity at a glance

    Case / operationTimeWhy
    Immediate, register0 memory readsThe operand is already in the CPU.
    Direct, register indirect, indexed, PC-relative, auto-increment/decrement1 memory read
    Indirect2 memory readsOne for the pointer, one for the operand.

    Quick check

    Test yourself — pick an answer to see if you got it.

    1. LOAD R0, @40 uses indirect addressing. M[40] = 43 and M[43] = 8. What ends up in R0?

    2. Which addressing mode suits a constant, as in x = x + 1?

    3. In indexed mode the address field is 1000 and the index register holds 12. What is the effective address?

    4. Why does PC-relative addressing make code position-independent?

    5. R1 = 45. What does LOAD R0, (R1)+ do?

    Saved in this browser.
    Spotted a mistake or a bug in the 3D model?

    Report a mistake

    in Addressing Modes. Thank you — every report makes the lesson better for the next reader.

    We'll also include a link to the step of the 3D model you're on and your browser type, so we can reproduce it.