5.1.9 · D4Instruction Set Architecture (ISA)

Exercises — Load - store architecture model

2,831 words13 min readBack to topic

Everything here builds on the parent note. If a symbol below feels unfamiliar, here is the full glossary we will reuse — read it once:


Level 1 — Recognition

L1.1 — Spot the illegal instruction

Below are four candidate instructions for a load/store machine. Exactly one cannot exist in a pure load/store ISA. Which, and why?

(a) LDR R1, [R2]        (b) ADD R1, R2, R3
(c) ADD R1, [R2], R3    (d) STR R1, [R2]
Recall Solution

Answer: (c). The single defining rule of a load/store architecture is: only load and store touch memory; the ALU only sees registers. Instruction (c) asks the ADD (an ALU op) to read straight from memory [R2] — that is forbidden.

  • (a) is a load — allowed to touch memory. ✓
  • (b) is an ALU op on three registers, no memory. ✓
  • (d) is a store — allowed to touch memory. ✓
  • (c) is an ALU op with a memory operand → illegal here (it is legal on a register-memory machine like x86, which is exactly the contrast the parent note draws).

L1.2 — Name the family

Fill each blank.

x86 that lets ADD [addr], EAX is a register-memory architecture. MIPS/ARM/RISC-V that forces load-then-compute-then-store is a load/store (register-register) architecture.

Recall Solution
  • ADD [addr], EAX folds a memory read + arithmetic + memory write into one instruction → register-memory (also just "CISC-style memory model").
  • The strict load → compute → store separation is the load/store model, also called register-register. See RISC vs CISC philosophy for the wider debate.

Level 2 — Application

L2.1 — Translate to load/store

Convert this register-memory line into legal load/store instructions. Assume R10 already holds the address of x, and you may use scratch registers R1, R2.

ADD [x], R5        ; meaning: memory[x] = memory[x] + R5
Recall Solution

The fused instruction does three hidden things: read x, add R5, write x back. Split them out:

LDR  R1, [R10]     ; R1 = memory[x]       (load)
ADD  R1, R1, R5    ; R1 = R1 + R5         (ALU, registers only)
STR  R1, [R10]     ; memory[x] = R1       (store)

One register-memory instruction became three load/store instructions — matching the parent's formula .

L2.2 — Count instructions with the formula

A computation needs arithmetic operations, requires loads and stores. On the register-memory machine, 3 of those 5 ops can absorb one memory operand each (so 3 memory accesses vanish into ALU ops).

(a) Instruction count on load/store, ? (b) Instruction count on register-memory, ? (Each fused op removes exactly one separate memory instruction.)

Recall Solution

(a) Load/store keeps everything separate: (b) Register-memory: 3 fused ops each swallow one memory access, removing 3 separate load/store instructions: So the register-memory version runs fewer instructions (8 < 11) — but read the next mistake box before you cheer.

L2.3 — Clock period from frequency

An ARM core runs at . What is its clock period in nanoseconds?

Recall Solution

(One tick lasts a third of a nanosecond. This is the "seconds per step" in our master equation.)


Level 3 — Analysis

L3.1 — Full time comparison

Compute total execution time for both machines on the same task, using the parent note's numbers.

  • x86 (register-memory): , , (so ).
  • ARM (load/store): , , (so ).

The figure lays out the two timelines side by side.

Figure — Load - store architecture model
Recall Solution

Plug into : They tie at ≈4.0 ns. The extra ARM instructions () are exactly cancelled by its lower CPI () and higher clock (). This is the whole point of the parent note: load/store trades more instructions for lower CPI and higher clock. In real silicon the tie usually tips ARM's way once Instruction pipelining hides the load latency.

L3.2 — Where does CPI = 4 come from?

The ARM sequence is three instructions and takes 12 pipeline cycles in steady state (one memory miss hidden behind other work, plus pipeline fill). Show , and separately show why x86's fused instruction stays at .

Recall Solution

CPI is total cycles divided by instruction count: The x86 fused ADD [addr], EAX cannot overlap its internal read → modify → write; the whole ~10-cycle memory latency is exposed as one indivisible instruction: Key insight: ARM's win is not fewer cycles per memory access — it is that pipelining lets other instructions run during the miss, so the average per-instruction cost falls.

L3.3 — Break the tie

Suppose engineers improve ARM's pipeline so the 3-instruction sequence now finishes in 9 cycles instead of 12 (better latency hiding). Keep . New ? Who wins now?

Recall Solution

New CPI: New time: Now : ARM wins. Better latency hiding (deeper/smarter pipelining, out-of-order issue) directly lowers CPI and hence total time, even though instruction count never changed.


Level 4 — Synthesis

L4.1 — Hand-schedule a full expression

Write legal load/store assembly for Assume R10, R11, R12 hold the addresses of a, b, c, and R13 the address of d. Use immediate #3. Then state how many registers hold live intermediate values simultaneously at the busiest moment.

Recall Solution
LDR  R1, [R10]     ; R1 = a
LDR  R2, [R11]     ; R2 = b
ADD  R3, R1, R2    ; R3 = a + b        (intermediate 1)
LDR  R4, [R12]     ; R4 = c
ADD  R5, R4, #3    ; R5 = c + 3        (intermediate 2)
MUL  R6, R3, R5    ; R6 = (a+b)(c+3)
STR  R6, [R13]     ; d = R6

Busiest moment: just before the MUL, both partial results must be alive at once — R3 = a+b and R5 = c+3. That is 2 live intermediates. This is why load/store ISAs ship many registers (32 in RISC-V/MIPS): intermediates live in registers instead of spilling to memory. See Register allocation.

L4.2 — Count everything

For the L4.1 program, report , , (ALU ops), and total . Verify .

Recall Solution
  • Loads: LDR R1, LDR R2, LDR R4.
  • Stores: STR R6.
  • ALU ops: ADD, ADD, MUL.
  • Total lines: . Check:

L4.3 — Register spill

Now imagine a tiny machine with only registers R1, R2 usable for data (a stress test). You must still compute . Because you cannot hold both intermediates at once, you must spill one to memory (a scratch slot [SP]). How many extra load/store instructions does spilling add versus the L4.1 plan?

Recall Solution

With 2 registers you compute a+b first, but you have nowhere to keep it while you compute c+3, so you store it to [SP], do the second sum, then load it back for the multiply:

LDR  R1, [R10]     ; a
LDR  R2, [R11]     ; b
ADD  R1, R1, R2    ; R1 = a+b
STR  R1, [SP]      ; SPILL a+b to memory      <-- extra store
LDR  R1, [R12]     ; c
ADD  R1, R1, #3    ; R1 = c+3
LDR  R2, [SP]      ; RELOAD a+b                <-- extra load
MUL  R1, R2, R1    ; product
STR  R1, [R13]     ; d

Extra instructions vs L4.1: one store + one load = 2 extra. This is the concrete cost of too few registers, and precisely why load/store designs favour large register files. See Register allocation and Memory hierarchy.


Level 5 — Mastery

L5.1 — Design decision under a real-time deadline

You are designing a CPU for an anti-lock braking controller. The hard requirement: every instruction's worst-case time must be known and bounded so you can prove a control loop always finishes within a deadline. You may choose register-memory or load/store. Which do you pick, and give the one-sentence engineering reason grounded in .

Recall Solution

Choose load/store. Its arithmetic instructions have fixed, low CPI (they never touch memory), and memory latency is isolated into explicit loads/stores you can bound separately — so every instruction's worst-case cycle cost is predictable, which is exactly what a provable real-time deadline needs. A register-memory ADD [addr] hides variable cache latency inside an arithmetic instruction, making its CPI (and thus its slice of ) unpredictable.

L5.2 — When would you accept register-memory anyway?

Give one concrete situation where the register-memory model's fewer instructions genuinely helps, despite everything above.

Recall Solution

When instruction-fetch bandwidth or code size is the bottleneck — e.g. a memory-constrained embedded device, or a workload where the instruction cache thrashes. Fewer, denser instructions () mean fewer bytes to fetch and store, easing pressure on the Memory hierarchy and Instruction encoding. This is a large part of why x86's dense CISC encoding survived: legacy code density and I-cache footprint. The trade lives in the same equation — you accept a higher CPI to shrink and the fetch traffic.

L5.3 — Prove the crossover

Using , find the ARM steady-state cycle count (for the 3-instruction sequence) at which ARM exactly ties x86. Keep x86 at and ARM at (). Recall , so ARM's time is .

Recall Solution

Notice — the total cycle count is the product. So: Set equal to x86: So 12 cycles is exactly the tie point — matching L3.2. Any pipeline improvement that gets ARM below 12 total cycles (e.g. L3.3's 9 cycles) makes load/store the winner; anything above 12 loses.


Recall Quick self-check (reveal after attempting all)

Only load and store touch memory in a load/store ISA ::: True — the defining rule. Formula for load/store instruction count ::: . Master timing equation ::: . at 3 GHz ::: . Why load/store can tie x86 despite more instructions ::: lower CPI and higher clock cancel the larger . Cost of too few registers ::: register spilling adds extra store+load instructions.

Related: RISC vs CISC philosophy · Instruction pipelining · Register allocation · Addressing modes · Instruction encoding · Memory hierarchy