About

6.3 The Fetch–Decode–Execute Cycle & RTL Traces

Theory: The Fetch–Decode–Execute Cycle & RTL Traces

A program is a sequence of stored instructions. The CPU runs it by repeating one loop, the fetch–decode–execute cycle (also called the instruction cycle), from power-on until it halts. Every instruction, no matter how simple or complex, passes through the same stages. Being able to trace the registers through this cycle is one of the most common exam questions on MARIE.

The Four Stages

  1. Fetch: copy the instruction whose address is in the PC from memory into the IR, and advance the PC so it points at the next instruction.
  2. Decode: look at the opcode IR[15–12] to find out which instruction this is, and copy the address field IR[11–0] into the MAR.
  3. Get operand (only if needed): if the instruction uses a value from memory (Load, Add, Subt, AddI, …), read it into the MBR.
  4. Execute: carry out the instruction’s remaining microoperations. Then go back to step 1.

Diagram loads as you scroll.

The RTL of Fetch and Decode

These microoperations are identical for every instruction:

Fetch:   MAR <- PC
         IR  <- M[MAR]
         PC  <- PC + 1
Decode:  MAR <- IR[11-0]
         (decode IR[15-12])
Operand: MBR <- M[MAR]            (only if the instruction needs it)
Execute: ... depends on the opcode ...

The PC is incremented during fetch, before the instruction executes. So while an instruction is executing, the PC already holds the address of the next instruction. This is why Skipcond skips by doing one more PC ← PC + 1, and why JnS saves the PC as the return address.

Mini-example

The PC holds 100 and M[100]=1104M[100] = \text{1104} (Load 104). Fetch: MAR = 100, IR = 1104, PC = 101. Decode: MAR = IR[11–0] = 104, opcode 1 = Load. Operand: MBR = M[104]. Execute: AC ← MBR.

Reading a Trace Table

A trace table has one row per microoperation and one column per register (PC, IR, MAR, MBR, AC). Write a register’s value after that microoperation; values that do not change are copied down. Dashes mean “unknown / not yet set”. Highlighting in your head which cell changes in each row is the fastest way to check yourself: each microoperation changes exactly one register (the one on the left of the arrow), except the fetch step that also increments the PC.

The Addition Program (Null & Lobur, Table 4.3)

AddressInstructionHex
100Load 1041104
101Add 1053105
102Store 1062106
103Halt7000
10400230023
105FFE9FFE9
10600000000

It computes 002316+FFE916\text{0023}_{16} + \text{FFE9}_{16}, i.e. 35+(−23)=12=000C1635 + (-23) = 12 = \text{000C}_{16}, and stores the result in 106. The full register traces are in Worked Example 1.

Interrupts (brief)

Real machines add one more step to the loop: after each instruction, the CPU checks for an interrupt (a signal from an I/O device, a timer, or an error such as division by zero; a program can also raise a software interrupt). If one is pending, the CPU saves the PC (and other state), runs an interrupt service routine, then restores the state and continues the interrupted program. MARIE’s basic cycle omits interrupts so the core loop stays simple.

Diagram loads as you scroll.


Worked Examples

Exercise 1

Trace the register contents (PC, IR, MAR, MBR, AC) for every microoperation of the addition program at addresses 100–106 (Load 104, Add 105, Store 106, Halt, with data 0023, FFE9, 0000). Initially PC = 100. What is in location 106 at the end?

Show solution ↓
Solution

(a) Load 104

StepRTNPCIRMARMBRAC
(initial values)100----------------
FetchMAR ← PC100----100--------
IR ← M[MAR]1001104100--------
PC ← PC + 11011104100--------
DecodeMAR ← IR[11–0]1011104104--------
(decode IR[15–12])1011104104--------
Get operandMBR ← M[MAR]10111041040023----
ExecuteAC ← MBR101110410400230023

(b) Add 105

StepRTNPCIRMARMBRAC
(initial values)101110410400230023
FetchMAR ← PC101110410100230023
IR ← M[MAR]101310510100230023
PC ← PC + 1102310510100230023
DecodeMAR ← IR[11–0]102310510500230023
(decode IR[15–12])102310510500230023
Get operandMBR ← M[MAR]1023105105FFE90023
ExecuteAC ← AC + MBR1023105105FFE9000C

0023+FFE9=1000C\text{0023} + \text{FFE9} = \text{1000C}; the carry out of bit 15 is discarded in a 16-bit register, leaving 000C = 12 ✓ (35−23=1235 - 23 = 12).

(c) Store 106

StepRTNPCIRMARMBRAC
(initial values)1023105105FFE9000C
FetchMAR ← PC1023105102FFE9000C
IR ← M[MAR]1022106102FFE9000C
PC ← PC + 11032106102FFE9000C
DecodeMAR ← IR[11–0]1032106106FFE9000C
(decode IR[15–12])1032106106FFE9000C
Get operand(not necessary)1032106106FFE9000C
ExecuteMBR ← AC1032106106000C000C
M[MAR] ← MBR1032106106000C000C

(d) Halt

StepRTNPCIRMARMBRAC
(initial values)1032106106000C000C
FetchMAR ← PC1032106103000C000C
IR ← M[MAR]1037000103000C000C
PC ← PC + 11047000103000C000C
DecodeMAR ← IR[11–0]1047000000000C000C
Execute(halt)1047000000000C000C

Location 106 now holds 000C (= 12).

Exercise 2

Using the addition program, answer without drawing the full table:

(a) Which registers change during the fetch of any instruction? (b) Which instruction(s) of the program do not need the “get operand” step? Why? (c) What value is in the PC while Add 105 is executing? (d) How many memory reads does the complete program perform (fetches + operands)?

Show solution ↓
Solution

(a) MAR (← PC), IR (← M[MAR]) and PC (← PC + 1). MBR and AC are untouched by fetch.

(b) Store 106 (it writes the AC to memory; it does not read a value) and Halt (no memory operand at all).

(c) 102: the PC was incremented during fetch, so it already points at the next instruction (Store 106).

(d) 4 instruction fetches (Load, Add, Store, Halt) + 2 operand reads (Load, Add) = 6 memory reads, plus 1 memory write (Store).

Exercise 3

Trace the sample1.mas program (it starts at address 010):

        ORG 010
        load x
        subt y
        output
        halt
x,      dec -12
y,      dec 20

Give its hex code and trace PC, IR, MAR, MBR and AC through all four instructions. What does it output?

Show solution ↓
Solution

Addresses: 010 load x, 011 subt y, 012 output, 013 halt, 014 x, 015 y. So x = 014, y = 015.

Hex: 1014, 4015, 6000, 7000, FFF4 (−12-12: 12=000C12 = \text{000C}, invert → FFF3, +1 → FFF4), 0014 (20).

Instr.StepRTNPCIRMARMBRAC
initial010----------------
load xFetchMAR ← PC010----010--------
IR ← M[MAR]0101014010--------
PC ← PC + 10111014010--------
DecodeMAR ← IR[11–0]0111014014--------
OperandMBR ← M[MAR]0111014014FFF4----
ExecuteAC ← MBR0111014014FFF4FFF4
subt yFetchMAR ← PC0111014011FFF4FFF4
IR ← M[MAR]0114015011FFF4FFF4
PC ← PC + 10124015011FFF4FFF4
DecodeMAR ← IR[11–0]0124015015FFF4FFF4
OperandMBR ← M[MAR]01240150150014FFF4
ExecuteAC ← AC − MBR01240150150014FFE0
outputFetchMAR ← PC01240150120014FFE0
IR ← M[MAR]01260000120014FFE0
PC ← PC + 101360000120014FFE0
DecodeMAR ← IR[11–0]01360000000014FFE0
ExecuteOutREG ← AC01360000000014FFE0
haltFetchMAR ← PC01360000130014FFE0
IR ← M[MAR]01370000130014FFE0
PC ← PC + 101470000130014FFE0
DecodeMAR ← IR[11–0]01470000000014FFE0

−12−20=−32-12 - 20 = -32. Check the hex: 32=002032 = \text{0020}, invert → FFDF, +1 → FFE0 ✓. The program outputs −32.

Exercise 4

Part of a program to find the larger of A = 7 and B = 12:

AddressInstructionHex
102Skipcond 0008000
103Jump 1079107
104Load B (B at 10D)110D
105Store Max (Max at 10E)210E
106Jump 1099109

Just before address 102 executes: PC = 102, IR = 410D, MAR = 10D, MBR = 000C, AC = FFFB. Trace the instructions at 102, 104 and 106 (in the order they execute) and say where execution goes after each.

Show solution ↓
Solution

AC = FFFB = −5-5 (it is A−B=7−12A - B = 7 - 12).

Skipcond 000 at 102

StepRTNPCIRMARMBRAC
initial102410D10D000CFFFB
FetchMAR ← PC102410D102000CFFFB
IR ← M[MAR]1028000102000CFFFB
PC ← PC + 11038000102000CFFFB
DecodeMAR ← IR[11–0]1038000000000CFFFB
ExecuteIR[11–10] = 00 and AC <\lt 0, so PC ← PC + 11048000000000CFFFB

The Jump 107 at 103 is skipped. Next instruction: 104.

Load B at 104

StepRTNPCIRMARMBRAC
FetchMAR ← PC1048000104000CFFFB
IR ← M[MAR]104110D104000CFFFB
PC ← PC + 1105110D104000CFFFB
DecodeMAR ← IR[11–0]105110D10D000CFFFB
OperandMBR ← M[MAR]105110D10D000CFFFB
ExecuteAC ← MBR105110D10D000C000C

(105 Store Max then writes 000C to 10E; PC becomes 106.)

Jump 109 at 106 (registers before: PC = 106, IR = 210E, MAR = 10E, MBR = 000C, AC = 000C)

StepRTNPCIRMARMBRAC
FetchMAR ← PC106210E106000C000C
IR ← M[MAR]1069109106000C000C
PC ← PC + 11079109106000C000C
DecodeMAR ← IR[11–0]1079109109000C000C
ExecutePC ← IR[11–0]1099109109000C000C

Execution continues at 109 with Max = 000C = 12, the larger value ✓.

Exercise 5

Memory holds: M[300]=D305M[300] = \text{D305} (LoadI 305), M[305]=0310M[305] = \text{0310}, M[310]=0099M[310] = \text{0099}. With PC = 300, trace the instruction through fetch, decode and execute. What ends up in the AC?

Show solution ↓
Solution
StepRTNPCIRMARMBRAC
initial300----------------
FetchMAR ← PC300----300--------
IR ← M[MAR]300D305300--------
PC ← PC + 1301D305300--------
DecodeMAR ← IR[11–0]301D305305--------
OperandMBR ← M[MAR]301D3053050310----
ExecuteMAR ← MBR301D3053100310----
MBR ← M[MAR]301D3053100099----
AC ← MBR301D30531000990099

The AC gets 0099: location 305 held the address 310, and location 310 held the data. Note the two memory reads after decode, which is the cost of indirection.

Exercise 6

Explain, register by register, what happens in the fetch–decode–execute cycle for Subt 0FF stored at address 200, given M[0FF]=0005M[\text{0FF}] = \text{0005} and AC = 0012 before the instruction.

Show solution ↓
Solution

Subt 0FF encodes as 40FF.

  1. MAR ← PC: the MAR gets 200, the address of the instruction.
  2. IR ← M[MAR]: memory location 200 is read; the IR gets 40FF.
  3. PC ← PC + 1: the PC becomes 201, ready for the next instruction.
  4. MAR ← IR[11–0]: the address field 0FF goes into the MAR; the control unit decodes IR[15–12] = 0100 = Subt.
  5. MBR ← M[MAR]: Subt needs an operand, so M[0FF] = 0005 is read into the MBR.
  6. AC ← AC − MBR: the ALU computes 0012−0005=000D\text{0012} - \text{0005} = \text{000D} (18 − 5 = 13) and the result goes back into the AC via the dedicated AC/MBR/ALU path.

Final: PC = 201, IR = 40FF, MAR = 0FF, MBR = 0005, AC = 000D ✓.