# Tracing a program

*Four instructions, step by step*

A program trace hand-executes a program one step at a time, following the fetch-decode-execute cycle and watching the registers and bus change. Tracing a short LOAD, ADD, STORE, HALT program shows the accumulator CPU actually computing a sum.

Group: Processor
URL: https://digiwleea.wleeaf.dev/learn/program-trace/

You have the [whole machine](https://digiwleea.wleeaf.dev/learn/cpu/) and its [language](https://digiwleea.wleeaf.dev/learn/machine-code/). The last thing to do is **run a program by hand**, the way the hardware does: follow [fetch-decode-execute](https://digiwleea.wleeaf.dev/learn/cpu/), tracking each register as the [control unit](https://digiwleea.wleeaf.dev/learn/control/)'s steps fire. Do this once and the CPU stops being a diagram and becomes a thing you can predict. We will compute `5 + 10` and store the answer.

## The program and the memory

Recall the [instruction set](https://digiwleea.wleeaf.dev/learn/machine-code/): `LOAD addr` (`0x1`) copies `memory[addr]` into the accumulator `ACC`; `ADD addr` (`0x2`) adds `memory[addr]` to `ACC`; `STORE addr` (`0x3`) writes `ACC` back to `memory[addr]`; `HALT` (`0xF`) stops the clock. Here is [memory](https://digiwleea.wleeaf.dev/learn/ram/), program at the bottom, data at the top, written in [hex](https://digiwleea.wleeaf.dev/learn/hexadecimal/):

| address | byte | meaning |
| --- | --- | --- |
| 0 | 0x1E | LOAD 14 |
| 1 | 0x2F | ADD 15 |
| 2 | 0x3D | STORE 13 |
| 3 | 0xF0 | HALT |
| 13 | 0x00 | result slot (starts 0) |
| 14 | 0x05 | the value 5 |
| 15 | 0x0A | the value 10 |

_Each program byte is opcode then operand: 0x2F is opcode 2 (ADD), operand 0xF (address 15). Addresses 14 and 15 hold the data 5 and 10; address 13 will receive the result._

> **KEY:** Notice there is **no line between code and data**: both are just bytes in the same RAM. The [program counter](https://digiwleea.wleeaf.dev/learn/counter/) decides which bytes are read as instructions (it walks 0, 1, 2, 3) and which the instructions treat as data (addresses 13, 14, 15). This is the *stored-program* idea, the foundation of every general-purpose computer.

**Q (Predict, then trace):** Before reading the trace below: after this whole program halts, what value is in the accumulator, and what value is in memory address 13? (The data is `5` at address 14 and `10` at address 15.)

**A:** The accumulator holds `15` and memory address 13 holds `15`. The program loads `5` (`ACC = 5`), adds `10` (`ACC = 15`), stores `ACC` to address 13 (`memory[13] = 15`), then halts. You wrote `5 + 10`; the machine left the answer `15` both in the accumulator and at address 13.

## The fetch that every instruction shares

Each instruction begins with the same **fetch**, driven by the control unit's step lines `T0`, `T1` (from the ring [counter](https://digiwleea.wleeaf.dev/learn/control/)):

1. **`T0`:** the [program counter](https://digiwleea.wleeaf.dev/learn/counter/) drives its address onto the [bus](https://digiwleea.wleeaf.dev/learn/tristate/); [RAM](https://digiwleea.wleeaf.dev/learn/ram/) reads that byte; the [instruction register](https://digiwleea.wleeaf.dev/learn/instruction-register/) loads it. Now the IR holds the instruction and exposes its opcode and operand.
2. **`T1`:** the program counter increments, so it already points at the *next* instruction. Then the steps branch on the opcode to do the execute phase.

## Running it, instruction by instruction

Start with `PC = 0` and `ACC` undefined. Fetch reads address 0.

1. **Fetch `0x1E` (PC 0 -> IR), PC becomes 1.** Opcode `1` = LOAD, operand `14`. **Execute:** put `14` on the address bus, RAM reads `memory[14] = 5` onto the bus, the accumulator loads it. Now `ACC = 5`.
2. **Fetch `0x2F` (PC 1 -> IR), PC becomes 2.** Opcode `2` = ADD, operand `15`. **Execute:** put `15` on the address bus, RAM reads `memory[15] = 10` into the ALU's `B` input; the ALU adds (`ACC + B = 5 + 10`); the accumulator loads the sum. Now `ACC = 15`.
3. **Fetch `0x3D` (PC 2 -> IR), PC becomes 3.** Opcode `3` = STORE, operand `13`. **Execute:** the accumulator drives `ACC = 15` onto the bus, RAM writes it into `memory[13]`. Memory address 13 now holds `15`.
4. **Fetch `0xF0` (PC 3 -> IR), PC becomes 4.** Opcode `F` = HALT. **Execute:** the control unit stops the clock. The machine freezes with `ACC = 15` and `memory[13] = 15`.

> **KEY:** That is a complete program run. You wrote `5 + 10`; the machine fetched four bytes, decoded each opcode, and performed the transfers, and the answer `15` (`0x0F`) is sitting in memory at address 13. Every step was one micro-operation: one value crossing the bus, gated by control lines, clocked into a register. Nothing magic, just the loop, repeated.

## Watching the execute core do the arithmetic

The figure is the [accumulator + ALU](https://digiwleea.wleeaf.dev/learn/datapath/) core, the part that does the LOAD and ADD execute steps. Driving its inputs over clocks reproduces the program's arithmetic directly: this is what the [control unit](https://digiwleea.wleeaf.dev/learn/control/) makes happen once it has fetched an instruction. Step it to relive the trace.

- Hold `LD = 1` (load on every edge) and set the function `F1 F0 = 00` (add).
- Put `5` (`0000 0101`) on `B`, clear the accumulator first if needed, and clock: this is the LOAD/ADD that lands `ACC = 5`.
- Put `10` (`0000 1010`) on `B` and clock again: the ALU adds, `ACC` becomes `15` (`0000 1111`), exactly the program's result.
- Try one more `ADD` with `B = 0` and `ZERO` stays low; subtract `15` (set `F0 = 1`, `B = 0000 1111`) and `ACC` returns to `0`, lighting the `ZERO` flag.

_Circuit diagram: The execute core (ACCALU): the accumulator wired into the ALU. B0-B7 is the operand the fetch step pulled from memory, F1 F0 is the operation the opcode chose, LD loads the result on a clock edge. Open it in the lab and replay the trace: add 5, then add 10, and read ACC = 15._

> **TIP:** To hand-trace **any** program, keep a small table of the machine's state, one column each for `PC`, `IR`, `ACC`, and any memory you touch, and fill in a row per instruction. Fetch advances `PC` and reloads `IR`; execute changes `ACC` or memory per the opcode. That table is all a CPU really is: state, transformed one instruction at a time.

> **KEY:** This is the end of the climb. From a single [transistor](https://digiwleea.wleeaf.dev/learn/transistor/) you built [gates](https://digiwleea.wleeaf.dev/learn/nand/), then [arithmetic](https://digiwleea.wleeaf.dev/learn/fulladder/) and [memory](https://digiwleea.wleeaf.dev/learn/regbit/), then a [register](https://digiwleea.wleeaf.dev/learn/register8/), [ALU](https://digiwleea.wleeaf.dev/learn/alu/), [counter](https://digiwleea.wleeaf.dev/learn/counter/), [RAM](https://digiwleea.wleeaf.dev/learn/ram/), and [control unit](https://digiwleea.wleeaf.dev/learn/control/), and now you have **traced a program executing on a computer you understand top to bottom**. Open the [lab](https://digiwleea.wleeaf.dev/lab/) and write your own four-instruction program; you know exactly what every byte will do.

### FAQ

**Q:** What is a program trace?

**A:** A program trace is hand-executing a program one step at a time, following the [fetch-decode-execute](https://digiwleea.wleeaf.dev/learn/cpu/) cycle and watching the registers (`PC`, `IR`, `ACC`) and memory change. Tracing a short `LOAD / ADD / STORE / HALT` program shows the accumulator CPU actually computing a sum: here, `5 + 10 = 15`.

**Q:** How does fetch-decode-execute work in this CPU?

**A:** Every instruction starts with the same fetch: on step `T0` the [program counter](https://digiwleea.wleeaf.dev/learn/counter/) drives its address onto the [bus](https://digiwleea.wleeaf.dev/learn/tristate/), [RAM](https://digiwleea.wleeaf.dev/learn/ram/) reads that byte, and the [instruction register](https://digiwleea.wleeaf.dev/learn/instruction-register/) loads it; on `T1` the PC increments to point at the next instruction. The steps then **branch on the opcode** to run the execute phase (read the operand, run the [ALU](https://digiwleea.wleeaf.dev/learn/alu/), load a register).

**Q:** What is the stored-program idea?

**A:** There is **no line between code and data**: both are just bytes in the same [RAM](https://digiwleea.wleeaf.dev/learn/ram/). The [program counter](https://digiwleea.wleeaf.dev/learn/counter/) decides which bytes are read as instructions (it walks `0, 1, 2, 3`) and which the instructions treat as data (here addresses 13, 14, 15). This stored-program idea is the foundation of every general-purpose computer.

**Q:** How do you hand-trace any program?

**A:** Keep a small state table with a column for `PC`, `IR`, `ACC`, and any memory you touch, then fill one row per instruction: fetch advances `PC` and reloads `IR`, and execute changes `ACC` or memory per the opcode. That table is all a CPU really is: state, transformed one instruction at a time.
