An addressing mode is the rule that says *where* an instruction's operand actually comes from. The same ADD might add a constant baked into the instruction, the contents of a register, or a value sitting somewhere in memory. Each mode is a different chain of lookups, trading speed for flexibility — and the final memory address a mode computes is called the effective address.
The five common modes
1Immediate — the operand is a constant written *inside* the instruction. No lookup at all, so it is the fastest, but the value is fixed when the program is built. (ADD r1, #5)
2Register — the operand is the contents of a named register. One fast register read, no memory touch. (ADD r1, r2)
3Direct (absolute) — the instruction holds the *memory address* of the operand; one memory access fetches it. (LOAD r1, (1000))
4Indirect — the address in the instruction points to a memory word that holds the *real* address — a pointer. Two memory accesses, but the target can change at runtime. (LOAD r1, @(1000))
5Indexed — the effective address is a base plus the contents of an index register; bumping the index walks an array with the same instruction. (LOAD r1, 1000(r2))
More indirection, more reach
Read the list top to bottom and you are adding lookups: immediate needs zero memory accesses, direct needs one, indirect needs two. Each extra hop costs time but buys flexibility — indirect gives you pointers, indexed gives you arrays.
Worked example: walking an array
Say array A starts at address 1000 and the index register r2 holds 3. With indexed mode, LOAD r1, 1000(r2) computes the effective address1000 + 3 = 1003, then loads the word there into r1. To read the next element, just increment r2 to 4 — the *same instruction* now reaches 1004. That is exactly how a loop scans an array.
Indexed mode: EA = base + index register
base = 1000 (start of array A)
r2 = 3 (index)
EA = 1000 + 3 = 1003
r1 <- Memory[1003] ; loads A[3]
r2++ -> 4 ; same instruction now reaches A[4]
Direct vs indirect — easy to confuse
In direct mode the address field *is* the operand's address. In indirect mode the address field points to a word that *contains* the address — one extra hop. Treating one as the other reads the wrong memory entirely.
OperationTimeSpace
Immediate / Register · value is in the instruction or a register0 memory accesses—
Direct · address given outright1 memory access—
Indirect · follow a pointer first2 memory accesses—
Check yourself
Index register r2 holds 3 and the instruction is LOAD r1, 1000(r2) in indexed mode. Which memory address is read?