4.1.8 · D4Computer Architecture (Deep)

Exercises — Memory addressing modes — immediate, register, direct, indirect, indexed

2,023 words9 min readBack to topic

Throughout, we reuse one memory snapshot (the "world" for these problems):

Figure — Memory addressing modes — immediate, register, direct, indirect, indexed

Level 1 — Recognition

L1-1

State the addressing mode named by each instruction, and the number of operand memory accesses it needs.

  • (a) MOV R1, #100
  • (b) LOAD R1, [100]
  • (c) LOAD R1, [[100]]
  • (d) ADD R1, R2
  • (e) LOAD R1, [100 + R2]
Recall Solution L1-1

(a) Immediate — the number 100 is the data, sitting in the instruction word. 0 accesses. (b) Direct[100] is a literal address. EA , operand . 1 access. (c) Indirect — double brackets mean "the address of the address". EA , operand . 2 accesses. (d) Register — both operands live in CPU registers. 0 memory accesses. (e) Indexed — base 100 plus index register R2. EA , operand . 1 access.

Memory-access digits, in mode order (Imm, Reg, Direct, Indirect, Indexed) .

L1-2

Which single mode requires two memory reads to fetch its operand, and why exactly two?

Recall Solution L1-2

Indirect. Read #1 fetches the pointer (this is the EA). Read #2 fetches the operand . Every $M[\cdot]$ in the EA recipe costs one read; indirect's recipe is , which contains one $M[\cdot]$, so 1 (resolve) + 1 (final fetch) .


Level 2 — Application

L2-1

Using the shared state, compute the operand value loaded into R1 for each:

  • (a) MOV R1, #100
  • (b) LOAD R1, [100]
  • (c) LOAD R1, [[100]]
  • (d) LOAD R1, [100 + R2]
Recall Solution L2-1

(a) Immediate: operand . . (b) Direct: EA , operand . . (c) Indirect: EA , operand . . (d) Indexed: EA , operand . .

L2-2

R3=104. Evaluate LOAD R1, [[R3 - 4]] — a register-indirect with an offset inside the brackets. Assume [X] means read .

Recall Solution L2-2

Innermost first: . First read: → this is the EA. Second read (outer bracket): . . Two memory accesses (double brackets).

L2-3

An array of 4-byte integers is based at address . Register R2 holds a byte offset. What value of R2 selects element index 1 (the second element), and what operand does LOAD R1, [100 + R2] fetch then?

Recall Solution L2-3

Element index lives at byte offset . For , elemSize : offset , so R2 = 4. EA , operand . . This is exactly why indexed mode walks arrays: bump R2 by 4 each loop, reuse the same instruction.


Level 3 — Analysis

L3-1

Two instructions land at the same operand but by different routes. Given the shared state, show that LOAD R1, [[300]] and LOAD R1, [100] both put 200 into R1. Then state which is faster and by how many memory accesses.

Recall Solution L3-1

Indirect route [[300]]: read (EA), then read . . 2 accesses. Direct route [100]: EA , read . . 1 access. Same result 200; direct is faster by 1 memory access. The indirect version paid an extra read to chase the pointer stored at 300.

L3-2

You see LOAD R1, [100 + R2] with R2=104. A classmate claims "this is indirect, because points somewhere." Refute this precisely, then give the operand.

Recall Solution L3-2

It is indexed, not indirect. The distinction: indexed performs an addition with no extra memory read; indirect performs an extra memory read . Here EA (pure arithmetic, no dereference of 's "target"). Operand . . 1 memory access — proving it is not indirect (which would be 2).

L3-3

For each mode, if the instruction lives at a fixed spot but you want it to touch a different memory cell on the next run without rewriting the instruction bits, which modes can do it and how?

Recall Solution L3-3
  • Immediate: ❌ operand is baked into the bits — fixed forever.
  • Register: operand target is a fixed register number, but its contents can change → the value differs, though not the memory cell (no memory involved).
  • Direct: ❌ address A is literal in the bits — same cell every time.
  • Indirect: ✅ change the contents of (the pointer) and the same instruction reaches a new target.
  • Indexed: ✅ change the index register ; EA moves without touching the bits. Conclusion: runtime retargeting needs a changeable piece (register or a memory pointer) — indexed and indirect. This is why loops and pointers use them.

Level 4 — Synthesis

L4-1

Write a 3-instruction loop body (pseudocode) that sums a 4-byte-integer array based at A=100 using indexed mode, and explain why immediate/direct modes cannot express this loop compactly.

Recall Solution L4-1
LOAD  R1, [100 + R2]     ; fetch current element (indexed)
ADD   Racc, R1           ; accumulate (register mode)
ADD   R2, #4             ; advance byte offset by one 4-byte element (immediate)

(plus a branch to repeat until R2 reaches the array's byte-length). Why not immediate/direct? Immediate bakes a constant in the bits — it cannot name a moving cell. Direct bakes a fixed address — you'd need a separate LOAD for every element ([100], [104], [108], …), i.e. unrolled code proportional to array size. Indexed reuses one instruction while the index register moves the EA. Note all three modes appear: indexed (fetch), register (accumulate), immediate (the stride #4).

L4-2

A linked-list node stores {value at offset 0, next-pointer at offset 4}. The head node is at address 300. Given M[300]=100, M[304]=200, M[100]=200, M[200]=350, M[104]=42, write the accesses to (a) read the head node's value, and (b) advance to the next node's address. Which mode(s) does each use?

Recall Solution L4-2

(a) head value = field at offset 0 of node@300 → M[300]. If we LOAD R1, [300] that's direct, giving . So head value . 1 access. (b) next pointer = field at offset 4 of node@300 → LOAD R1, [300 + 4] (indexed, offset 4) reads . So the next node's address is 200. 1 access. To then read the next node's value: LOAD R1, [[300 + 4]] — indexed-then-indirect: read (the pointer), then . 2 accesses, value . This is the classic "follow the chain" pattern: indexed picks the pointer field, indirect follows it.


Level 5 — Mastery

L5-1

Design task. Your ISA has a 16-bit instruction: 4-bit opcode, 2-bit mode field, and a 10-bit operand field. (i) How many distinct addressing modes can the 2-bit field encode? (ii) In direct mode, what is the largest byte address the 10-bit field can name? (iii) Argue why indexed mode lets this small machine still reach far beyond that limit.

Recall Solution L5-1

(i) 2 bits encode modes. (ii) 10 bits name distinct addresses, i.e. addresses through . Largest direct address . (iii) In indexed mode EA . The base (10 bits) is small, but the index register is full machine-width (say 16+ bits). Since the register supplies most of the address at runtime, EA can far exceed 1023 — the register carries the high bits the instruction word cannot. This is exactly how small instruction words still address large memories: put the big number in a register, not the instruction.

L5-2

Cost analysis. A program does operand fetches. 40% are indirect, 35% are indexed, 25% are direct. If one memory access costs 5 ns and an ALU addition (for indexed) costs 1 ns, compute total operand-access time. (Register/immediate parts excluded.)

Recall Solution L5-2

Counts: indirect , indexed , direct .

  • Indirect: 2 accesses each → ns.
  • Indexed: 1 access + 1 addition each → ns.
  • Direct: 1 access each → ns. Total ns. Notice indirect, though only 40% of fetches, dominates the cost (4000 of 7350 ns) — because of its 2-access penalty. This is the quantitative reason pointer-heavy code is slow (see Memory Hierarchy and Access Latency).

Recall One-line recap of the whole ladder

Recognise the mode (L1) → compute its operand from state (L2) → separate value from cost/flexibility (L3) → build loops & pointer-chases from modes (L4) → reason about encoding limits & timing (L5). The invariant behind all of it: EA is a recipe; each $M[\cdot]$ in that recipe is a real memory read.

Related: Instruction Encoding & Opcodes · Registers and the Register File · Pointers in C · Arrays and Stride · CPU Datapath and Control Unit.