Grade by Grade
C. Computer Environments and Systems · Computer Environments and Systems

How a Program Runs on the Hardware

C1.4About 70 minutes
Learning goals
  • I can describe what happens, step by step, when I run a program: from storage to RAM to the CPU.
  • I can explain the fetch-decode-execute cycle and the jobs of the control unit, the ALU and registers.
  • I can identify which components are involved in each line of a program (for example, assignment stores a value in RAM and arithmetic happens in the CPU).
  • I can trace a simple simulated CPU program.

Words to know

control unit
The part of the CPU that fetches instructions, decodes them and directs the other parts.
ALU (arithmetic logic unit)
The part of the CPU that does arithmetic (+, −, ×, ÷) and logic and comparisons (and, or, <, ==).
register
A tiny, extremely fast storage location inside the CPU, holding one value the CPU is working on right now.
program counter (PC)
A register that holds the address of the next instruction to fetch.
fetch-decode-execute cycle
The repeating cycle the CPU follows for every instruction: fetch it from memory, decode it, execute it.
memory address
A number that identifies one location in RAM, like a house number.
stored-program concept
The idea that a program's instructions are stored in memory, just like data, so the CPU can fetch them.

What happens when you press Run?

You type a short Python program and press Run. A moment later, the answer appears. In between, at least five pieces of hardware from this unit worked together billions of times. This lesson follows the journey.

Here is the program we will follow:

price = 4.50
qty = 3
total = price * qty
print("Total:", total)

Three assignment statements and one output statement. Output: Total: 13.5

The journey of a program

  1. Storage → RAM. Your program is saved as a file on the SSD. When you press Run, the operating system loads the Python interpreter and your program into RAM. The CPU can only work on instructions and data that are in memory.
  2. The CPU runs instructions. The CPU repeats the fetch-decode-execute cycle for each instruction (more below).
  3. Assignment stores values in RAM. price = 4.50 sets aside a spot in RAM and stores 4.5 there, under the name price. qty = 3 does the same for 3. A variable name is a friendly label for a memory address.
  4. Arithmetic happens in the CPU. For total = price * qty, the CPU copies 4.5 and 3 from RAM (through the cache) into its registers, the ALU multiplies them, and the result 13.5 is stored back into RAM under the name total.
  5. Output goes through the operating system to a device. print asks the operating system to display text; the GPU draws it and the monitor shows it. Similarly, input() waits for the keyboard, and the typed text is stored in RAM.

(Python adds an extra step: it first translates your code into simpler instructions called bytecode, and the Python interpreter, which is itself a machine-code program, carries them out. You will look at this in the lessons Source Code and Machine Code and Interpreters and Compilers. The hardware story is the same.)

CPUControl unitfetches anddecodesALUarithmetic andcomparisonsRegistersprogram counter (PC), accumulator,instruction register...RAMthe program's instructionsand its variables(price = 4.5, qty = 3)address, dataand control busesInput / outputkeyboard, monitor, storage
Inside, the CPU has a control unit, an ALU and registers. Buses carry addresses, data and control signals between the CPU, RAM and input/output devices. Program instructions and variables both live in RAM (the stored-program concept).

The fetch-decode-execute cycle

Each machine instruction the CPU runs goes through the same three steps:

  • Fetch. The program counter (PC) register holds the address of the next instruction. The control unit fetches the instruction from that address in memory (usually from the cache, which keeps copies of RAM) and moves the PC on to the next instruction (in our simple model, by adding 1).
  • Decode. The control unit works out what the instruction means: which operation (load, add, store, compare, jump...) and which data or addresses it uses.
  • Execute. The instruction is carried out. Arithmetic and comparisons happen in the ALU; values move between registers and RAM; or data goes to or from an input/output device. A jump instruction changes the PC, which is how if statements and loops skip or repeat code.

Then the cycle starts again. A 3 GHz CPU has 3 billion clock cycles each second, and modern CPUs can complete several simple instructions per cycle on each core.

FETCHget instructionfrom RAMDECODEwork out whatit meansEXECUTEdo it (ALU,RAM or I/O)repeatsbillions oftimes a secondEach pass:1. The PC register says where thenext instruction is in RAM.2. The control unit decodes it.3. The ALU calculates, or data movesbetween registers, RAM and I/O.4. The PC moves on (or jumps, foran if statement or a loop).
The fetch-decode-execute cycle. Every line of Python you write becomes many of these tiny steps.
Line of PythonWhat the hardware does
price = 4.50CPU executes the assignment; the value 4.5 is stored in RAM under the name price.
qty = 3The value 3 is stored in RAM under the name qty.
total = price * qtyValues are loaded from RAM (via cache) into registers; the ALU multiplies; 13.5 is stored in RAM as total.
print("Total:", total)total is read from RAM; the CPU passes the text to the operating system; the GPU and monitor display it.
name = input()The program waits for the keyboard; the typed text is stored in RAM under the name name.
if total > 10:The ALU compares total with 10; based on the result, the CPU either continues or jumps (changes the PC).
Which components are involved in common programming operations.

A pretend CPU you can run

Real machine instructions are just numbers, which are hard to read. The program below simulates a tiny CPU with one register called the accumulator (acc) and a program counter (pc). Its instructions are:

  • LOAD a: copy the value at RAM address a into acc
  • ADD a: add the value at address a to acc (this is the ALU's job)
  • STORE a: copy acc into RAM address a
  • PRINT a: output the value at address a
  • HALT: stop

Its little program adds the numbers at addresses 6 and 7 and stores the answer at address 8, just like total = a + b. (To keep the code short, the instructions are kept in a separate list; in a real computer they sit in RAM beside the data.)

program = [["LOAD", 6], ["ADD", 7], ["STORE", 8], ["PRINT", 8], ["HALT", 0]]
ram = [0, 0, 0, 0, 0, 0, 12, 30, 0] # data at addresses 0 to 8
acc = 0 # accumulator register
pc = 0 # program counter register
running = True
while running:
op, addr = program[pc] # FETCH the instruction pc points to
pc = pc + 1 # point to the next instruction
if op == "LOAD": # DECODE the operation, then EXECUTE it
acc = ram[addr]
elif op == "ADD":
acc = acc + ram[addr]
elif op == "STORE":
ram[addr] = acc
elif op == "PRINT":
print("Output:", ram[addr])
elif op == "HALT":
running = False
print(op, addr, "-> acc =", acc, " pc =", pc)

A fetch-decode-execute simulator. Each line of the trace shows one instruction, the accumulator after it ran, and where the program counter points next. Output (one line each): LOAD 6 -> acc = 12 pc = 1 / ADD 7 -> acc = 42 pc = 2 / STORE 8 -> acc = 42 pc = 3 / Output: 42 / PRINT 8 -> acc = 42 pc = 4 / HALT 0 -> acc = 42 pc = 5

Worked example

Example 1: Which components are involved?

For this program, say which component does the main work in each line.

  1. age = int(input("Age? "))
  2. months = age * 12
  3. if months > 200:
  4.     print("Over 200 months old!")
  1. Line 1: the keyboard sends the typed characters; the operating system passes them to the program. int() is carried out by the CPU, which converts the text to a number. The number is stored in RAM under age.
  2. Line 2: age is loaded from RAM into a register, the ALU multiplies by 12, and the result is stored in RAM under months.
  3. Line 3: months is loaded into a register and the ALU compares it with 200. If the comparison is false, the CPU jumps past line 4 by changing the program counter.
  4. Line 4 (only if true): the text goes through the operating system to the GPU and monitor.

Input from the keyboard to RAM; arithmetic and comparison in the ALU; values stored in RAM; output through the GPU to the monitor.

Worked example

Example 2: Write a pretend-CPU program

Using the simulator's instructions, write a program that computes ram[6] + ram[7] + ram[6] and prints the result. With 12 at address 6 and 30 at address 7, what is printed?

  1. Start with LOAD 6 (acc = 12).
  2. ADD 7 (acc = 42), then ADD 6 again (acc = 54).
  3. STORE the result at a free address, such as 8, then PRINT 8 and HALT.
  4. Program: [["LOAD", 6], ["ADD", 7], ["ADD", 6], ["STORE", 8], ["PRINT", 8], ["HALT", 0]].

The PRINT step outputs Output: 54 (the simulator also prints its trace lines).

Just for fun

In the time it takes you to blink (roughly a third of a second), a 3 GHz processor ticks through about one billion clock cycles. So if your program seems slow, the CPU is probably waiting for something: you, the internet, or the storage drive.

Hands-on activity

Be the computer

You need: 9 sticky notes or small pieces of paper (numbered 0 to 8 for RAM addresses), a sheet labelled CPU with two boxes (ACC and PC), a pencil, and a computer with Python.

  1. Lay the 9 notes in a row as RAM. Write 12 on note 6, 30 on note 7, and 0 on all the others.
  2. On another paper, write the program: LOAD 6, ADD 7, STORE 8, PRINT 8, HALT, numbered 0 to 4.
  3. Set PC = 0 and ACC = 0. Now act as the CPU: fetch the instruction at PC, add 1 to PC, decode it (say aloud what it means) and execute it by changing ACC or a RAM note. Repeat until HALT.
  4. Run the simulator above and compare its trace with yours.
  5. Change the program so it computes ram[7] − ram[6] by adding a SUB instruction to the simulator (copy the ADD branch and change + to −). Predict the output first.

What to look for: the paper trace matches the simulator (ACC goes 12, 42, 42, 42, 42; note 8 ends at 42). For step 5, the new branch is elif op == "SUB": then acc = acc - ram[addr], and the program LOAD 7, SUB 6, STORE 8, PRINT 8, HALT outputs Output: 18.

Your turn

1

Which part of the CPU does the arithmetic in total = price * qty?

2

Where is the value of a variable stored while a program runs?

3

What does the program counter hold?

4

Name the three steps of the CPU's instruction cycle, in order.

5

Why must a program be loaded into RAM before it runs?

6

In the simulator, what would [["LOAD", 7], ["STORE", 8], ["PRINT", 8], ["HALT", 0]] print?

7

How does an if statement change the order in which the CPU runs instructions?

More practice: warm-up

1

What does ALU stand for?

2

What is a register?

3

Which component does input() wait for?

4

Which part of the CPU decodes instructions?

5

What does the STORE instruction do in the simulator?

More practice: on your own

1

Trace the simulator program [["LOAD", 7], ["ADD", 7], ["ADD", 6], ["STORE", 5], ["PRINT", 5], ["HALT", 0]] with 12 at address 6 and 30 at address 7. Give acc after each instruction and the output.

2

For count = count + 1, list the hardware steps.

3

Explain the stored-program concept and why it was important.

4

A loop runs total = total + n 1000 times. Roughly how many times does the ALU add? Why is this still fast?

5

Why does the CPU use cache instead of going to RAM every time?

Challenge

1

Add a JUMP a instruction to the simulator that sets pc = a. What happens if you run [["LOAD", 6], ["ADD", 7], ["JUMP", 1]]? Why is that a problem, and what does a real loop need?

2

A 4 GHz single-core CPU could complete one simple instruction per cycle. About how long would 2 billion instructions take? Why do real programs often take longer?

3

Explain, using the components in this lesson, why the line big = [0] * 100_000_000 could make a computer with little RAM slow down.

Check your understanding

Quiz

1.

When x = 5 runs, where is the value 5 stored?

2.

Which part of the CPU performs a + b and a < b?

3.

What is the correct order of the instruction cycle?

4.

What does the program counter (PC) hold?

5.

In the simulator, ram[6] = 12 and ram[7] = 30. What line does the PRINT instruction output when it runs LOAD 7, ADD 6, STORE 8, PRINT 8, HALT?

6.

Before a program can run, the operating system first loads it...

For parents and teachers

Big idea: Expectation C1.4 asks students to identify the components involved in executing programming operations: for example, assignment statements store values in RAM and arithmetic happens in the CPU. The simulator makes this concrete.

How to help: Play the "Be the computer" activity with your teen: you can read out the instructions while they act as the CPU. Ask "Where is that number right now: storage, RAM or a register?" Any program from the Programming Basics unit can be traced the same way.

Common difficulties:

  • Thinking variables live "in the program file" or on the drive while the program runs. They live in RAM.
  • Mixing up the control unit (directs) and the ALU (calculates).
  • Forgetting that the PC moves on before the instruction executes (in the simulator, pc = pc + 1 comes right after the fetch).
  • The simulator keeps instructions in a separate list for simplicity; real computers store instructions in RAM alongside data.