5.1.3 · D4Instruction Set Architecture (ISA)

Exercises — Addressing modes

2,384 words11 min readBack to topic

We reuse one machine state for the whole page so you build fluency on a single mental picture.

Notation reminder (all from the parent): = the address/displacement field baked into the instruction; = "contents of register "; = "contents of memory at address ". is the address we finally read the operand from.

Figure — Addressing modes

Look at the picture above: each mode is a path from the instruction to the operand. Short paths (immediate, register) never touch memory; long paths (indirect) touch it twice. Every exercise below is "trace the path, then count the hops."


Level 1 — Recognition

Goal: name the mode and apply its EA rule directly.

L1.1

LOAD 500 is a direct instruction. What is , and what operand loads?

Recall Solution

WHAT: Direct mode means the address field is the address: . WHY: no register, no second lookup — the bits point straight at the data. , operand . Memory accesses = 1.

L1.2

LOAD #500 uses immediate mode. What operand loads and how many memory accesses?

Recall Solution

WHAT: the # says the operand is the number itself. Operand . WHY: the value travels inside the instruction word, so no address is ever formed. is undefined (there is none). Memory accesses = 0.

L1.3

LOAD (R1) is register-indirect with . Give and the operand.

Recall Solution

WHAT: register-indirect means the register holds the address: . , operand . Memory accesses = 1. WHY only one: the pointer was already in the register, so we skip the "read the pointer" hop.


Level 2 — Application

Goal: combine a field and a register, or chain two memory reads.

L2.1

LOAD (100)memory-indirect mode, . Find and the operand.

Recall Solution

Step 1 (WHAT): read the pointer cell. . So . Step 2 (WHY): location 100 stores an address, not the data; we must follow it. Operand . Memory accesses = 2 (read pointer, then read operand).

L2.2

LOAD 3(R1)displacement/based mode, , . Find and operand.

Recall Solution

WHAT: displacement adds a small constant offset to a base register: . , operand . Memory accesses = 1. WHY this shape: points at an array's start; the constant 3 selects element index 3. This is literally how array[3] compiles.

L2.3

LOAD 100(R2)indexed mode, (base), (index). Find .

Recall Solution

WHAT: same arithmetic, opposite roles — the constant is the base and the register varies: . Operand (not in our table — the point is the address, ). Memory accesses = 1.


Level 3 — Analysis

Goal: reason about accesses, PC-relative distances, and side effects.

L3.1

For each instruction, state the number of memory accesses to fetch the operand (do not count the instruction fetch): LOAD #7, LOAD R1, LOAD 500, LOAD (100), LOAD (R1), LOAD 3(R1).

Recall Solution
  • LOAD #70 (immediate: value in instruction).
  • LOAD R10 (register: operand in register).
  • LOAD 5001 (direct: one read at 500).
  • LOAD (100)2 (indirect: pointer read + operand read).
  • LOAD (R1)1 (register-indirect: pointer already in register).
  • LOAD 3(R1)1 (displacement: one add, one read). Pattern: count how many times you must read memory to reach the operand. Immediate/register = 0; one indirection through memory adds 1 hop each.

L3.2

BRANCH +6 with (PC-relative). What target address is computed? Now the OS reloads the program 1000 bytes higher, so at run time for the same instruction. What target now?

Recall Solution

WHAT: PC-relative stores a distance: . Original: . Relocated: . WHY it matters: the instruction never stored "206." It stored "+6." So wherever the loader drops the code, the branch still lands 6 past the current point — this is position independence. See Instruction Format for where the lives in the encoded word.

L3.3

LOAD (R1)+auto-increment, , . Give the operand loaded and the register value after the instruction. Then, without re-loading R1, what does a second LOAD (R1)+ load?

Recall Solution

First execution — WHAT/WHY: auto-increment reads then steps the pointer so the next access is teed up for free. , operand . Then . Second execution: , operand . Then . This is exactly the *p++ streaming idiom (see Pointers and Arrays).


Level 4 — Synthesis

Goal: chain modes, decode ambiguous operands, and connect to real hardware structures.

L4.1 — Two-level indirection by hand

Some ISAs allow LOAD ((100)) (double indirect). Trace it fully on our table.

Recall Solution

Step 1: innermost pointer: . Step 2: follow it: — this is now the next pointer. Step 3: follow again: operand . , operand . Memory accesses = 3 (each (...) layer costs one extra read). This is how you'd chase a pointer-to-a-pointer; every level of "follow the arrow" adds one hop.

L4.2 — Stack pop with auto-increment

A stack grows downward (push decrements, pop increments). Register R3 = 600 is the stack pointer, . Model a pop as LOAD (R3)+. What value is popped, and where does R3 point after?

Recall Solution

WHAT: pop = read the top, then move the pointer up off it. , popped value . Then . WHY auto-increment fits pop: the read-then-advance order exactly matches "take the top item, then shrink the stack." (A push would use auto-decrement: move down first, then write.) See Stack and Subroutines.

L4.3 — Same , four different operands

Using , compute the operand loaded under immediate, direct, indirect, and (treating 100 as a displacement with ) displacement modes. One address field, four answers — explain why.

Recall Solution
  • Immediate #100: operand (the literal). 0 accesses.
  • Direct 100: , operand . 1 access.
  • Indirect (100): , operand . 2 accesses.
  • Displacement 100(R2): , operand . 1 access. WHY four answers: the bits 100 are identical; the mode bits in Instruction Format decide whether 100 means a value, an address, a pointer's address, or an offset. Same bits, different recipe.

Level 5 — Mastery

Goal: design-level reasoning — choose modes, count total cost, argue trade-offs.

L5.1 — Total memory traffic of a loop

A loop sums 4 array elements. Version A uses direct addressing with 4 separate LOAD instructions (each names an absolute address). Version B uses LOAD (R1)+ inside a loop. Count operand memory accesses for each (ignore instruction fetches and the loop overhead).

Recall Solution
  • Version A: 4 direct loads → operand accesses.
  • Version B: 4 auto-increment loads → operand accesses. Operand traffic is identical (4). The real win of B is fewer instructions and no hard-coded addresses: one reusable loop body instead of four unrolled loads, and it works for any array R1 points at. Cost lives in instruction count and code size, not operand reads here.

L5.2 — When does indirect actually pay?

You must read one element from a table whose location changes at run time (chosen by earlier code). Compare direct vs indirect. Which is even possible, and what is the access cost?

Recall Solution

Direct requires knowing the address at compile time — impossible if it's decided at run time. So direct is out. Indirect stores the run-time address in a known pointer cell (say 100): LOAD (100), operand , 2 accesses. Trade-off: indirect pays 1 extra memory read but buys the ability to point somewhere not known when the program was written. That extra hop is the price of run-time flexibility — exactly the Memory Hierarchy tension between speed and generality.

L5.3 — RISC vs CISC mode budget

A CISC design offers LOAD ((base + index*scale)) in a single instruction. A RISC design forbids memory-indirect and scaling, offering only register and displacement modes. Argue why the RISC choice can be faster overall despite needing more instructions.

Recall Solution

CISC single instruction hides: an add (base+index), a shift (×scale), a memory read (pointer), and a second memory read (operand) — up to 2 memory accesses + 2 ALU ops behind one opcode. That lengthens decode and the critical path; the slowest mode sets the clock for everyone. RISC splits the work into several simple, fixed-length instructions (compute address in a register with displacement, then one LOAD (R)), each doing at most 1 memory access. Simpler decode → shorter cycle, deeper pipelining, and the compiler can reorder/overlap the pieces. Verdict: more instructions, but each is cheap and pipelines cleanly — often a net win. It's a trade-off, not a free lunch. See RISC vs CISC.



Recall Feynman recap for a 12-year-old

Every exercise was a treasure hunt. Some maps write the treasure right on them (immediate). Some give a spot to dig (direct — one dig). Some give a spot that holds another map (indirect — two digs). Some say "start at your friend R1 and walk 3 steps" (displacement). Auto-increment is a friend who takes one step forward after each dig, so the next dig is ready. Your whole job: read the map's rule, find the final X, and count how many times you had to dig.