You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
The processor is where computation actually happens, and at A-Level the examiners expect a forensic level of detail about how it works. It is not enough to say "the CPU fetches an instruction" — you must be able to name the specific register that holds the address, the specific bus that carries it, and the exact sequence of micro-steps that move data around inside the chip. This lesson dissects the internal architecture of a typical processor: its control unit and ALU, its set of special-purpose registers, the three buses that connect it to memory, and a complete, step-by-step trace of the Fetch-Decode-Execute (FDE) cycle written in register transfer notation (RTN).
By the end you should be able to write the FDE cycle out in RTN from memory, explain how each register and bus participates, distinguish the roles of the MAR and the MDR without hesitation, and describe how interrupts fit into the cycle.
This lesson maps to the AQA A-Level Computer Science (7517) specification, §4.7.3 Structure and role of the processor and its components:
flowchart TB
subgraph CPU["Processor (CPU)"]
CU["Control Unit (CU)<br/>decodes + sequences"]
CLK["System Clock"]
ALU["Arithmetic Logic Unit (ALU)"]
ACC["Accumulator (ACC)"]
PC["Program Counter (PC)"]
CIR["Current Instruction Register (CIR)"]
MAR["Memory Address Register (MAR)"]
MDR["Memory Data Register (MDR)"]
SR["Status Register (flags)"]
ALU --> ACC
ACC --> ALU
CLK --> CU
end
MAR -->|"address bus"| MEM["Main Memory"]
MEM <-->|"data bus"| MDR
CU <-->|"control bus"| MEM
The ALU is the calculator of the processor. It performs:
The ALU usually works hand-in-hand with the accumulator (ACC): one operand often comes from the ACC, the result is written back to the ACC, and flags are updated in the status register.
The control unit is the conductor of the orchestra. It:
The clock generates a continuous stream of regular pulses. Each micro-operation of the FDE cycle is synchronised to these pulses, so that data is only moved between registers at well-defined moments. The clock speed (e.g. 3.5 GHz = 3.5 billion pulses per second) sets the basic tempo of the processor.
A register is a very small, very fast store inside the CPU, used to hold a single value during processing. The special-purpose registers each have a dedicated job:
| Register | Full Name | Purpose |
|---|---|---|
| PC | Program Counter | Holds the address of the next instruction to be fetched |
| MAR | Memory Address Register | Holds the address of the memory location about to be read from or written to |
| MDR | Memory Data Register (also called MBR — Memory Buffer Register) | Holds the data/instruction just read from memory, or the data about to be written to memory |
| CIR | Current Instruction Register | Holds the instruction currently being decoded and executed |
| ACC | Accumulator | A working register that holds operands and results of ALU operations |
| IX | Index Register | Holds a value added to a base address in indexed addressing |
| SR / Flags | Status Register | Holds individual flag bits (e.g. carry C, zero Z, negative N, overflow V) set by ALU operations |
Exam Tip: Name registers precisely — the MAR and MDR are not interchangeable. Remember the mnemonic: MAR = Address, MDR = Data. The MAR is connected to the address bus; the MDR is connected to the data bus. Mixing them up is the single most common error in FDE-cycle questions.
To describe data movement precisely, we use register transfer notation. The arrow ← means "is copied into". Square brackets [ ] mean "the contents of the memory location whose address is given inside". So:
MAR ← [PC] means copy the contents of the PC into the MAR.MDR ← [[MAR]] means fetch from memory the word at the address held in the MAR, and copy it into the MDR.PC ← [PC] + 1 means increment the PC by one.You will use this notation to write out the FDE cycle.
It helps to classify the registers by role:
The status register sits slightly apart: it is special-purpose (the ALU writes its flags automatically) but the programmer reads it indirectly through conditional branch instructions. Knowing which registers are programmer-visible and which are internal housekeeping is exactly the kind of precise distinction that earns marks when a question asks you to "describe the purpose" of a named register.
The CPU communicates with main memory and I/O over the system bus, which is really three buses bundled together:
| Bus | Direction | Width (typical) | Purpose |
|---|---|---|---|
| Address bus | Unidirectional (CPU → memory) | 32 or 64 lines | Carries the address of the memory location being accessed; driven from the MAR |
| Data bus | Bidirectional | 8, 16, 32 or 64 lines | Carries data and instructions between CPU and memory / I/O; connected to the MDR |
| Control bus | Bidirectional | Several lines | Carries control signals — read, write, clock, interrupt request, bus request / bus grant |
n address lines you can address 2n locations. A 32-line address bus therefore addresses 232 locations ≈ 4 GB.A common exam calculation: "A processor has a 16-bit address bus and an 8-bit data bus. State the maximum number of memory locations and the size of each location."
If the address bus were widened to 20 lines, the addressable space would jump to 220=1,048,576 locations (1 MB) — every extra address line doubles the addressable memory. This powers-of-two relationship is identical to the one you use for unsigned binary ranges, and is a frequent two-or-three-mark question.
The status register (flags register) deserves a closer look because it is how the processor "remembers" the outcome of an operation so that a later branch can act on it. After an ALU operation, individual bits are set or cleared:
| Flag | Set when… | Used by |
|---|---|---|
| Zero (Z) | the result is zero | BEQ / branch-if-equal, BRZ |
| Negative (N) | the result's sign bit is 1 | branch-if-negative / less-than tests |
| Carry (C) | an unsigned operation produced a carry/borrow out | multi-word arithmetic, unsigned comparisons |
| Overflow (V) | a signed result is out of range | signed comparisons, error detection |
For example, a CMP R1, R2 instruction subtracts internally and sets the Z flag if the values were equal; a following BEQ then tests Z to decide whether to branch. This Compare-then-Branch pairing is exactly how a high-level if (a == b) compiles down to machine code, and it ties the status register directly to the branch trace shown earlier.
The FDE cycle is the fundamental loop of any Von Neumann processor. Every machine-code instruction passes through three stages.
| Step | RTN | Plain-English explanation |
|---|---|---|
| 1 | MAR ← [PC] | The address of the next instruction is copied from the PC into the MAR. |
| 2 | (control bus) | The CU asserts a memory read signal on the control bus; the address in the MAR is placed on the address bus. |
| 3 | MDR ← [[MAR]] | Memory returns the instruction at that address along the data bus into the MDR. |
| 4 | CIR ← [MDR] | The instruction is copied from the MDR into the CIR ready for decoding. |
| 5 | PC ← [PC] + 1 | The PC is incremented so it points at the next instruction. (A branch may overwrite this during Execute.) |
CIR.The decoded instruction is carried out. Depending on the opcode this may mean:
Suppose memory and registers start as follows. The program adds the value at address 21 to the accumulator and stores the result back at address 22.
| Address | Contents |
|---|---|
| 0 | LDA 20 (load contents of address 20 into ACC) |
| 1 | ADD 21 (add contents of address 21 to ACC) |
| 2 | STA 22 (store ACC into address 22) |
| 20 | 14 |
| 21 | 9 |
| 22 | 0 |
Initial state: PC = 0, ACC = 0.
# --- Instruction 1: LDA 20 ---
FETCH: MAR ← [PC] # MAR = 0
MDR ← [[MAR]] # MDR = LDA 20
CIR ← [MDR] # CIR = LDA 20
PC ← [PC] + 1 # PC = 1
DECODE: opcode = LDA, operand = 20 (direct addressing)
EXECUTE: MAR ← 20 # address of the data
MDR ← [[MAR]] # MDR = 14
ACC ← [MDR] # ACC = 14
# --- Instruction 2: ADD 21 ---
FETCH: MAR ← [PC] # MAR = 1
MDR ← [[MAR]] # MDR = ADD 21
CIR ← [MDR] # CIR = ADD 21
PC ← [PC] + 1 # PC = 2
DECODE: opcode = ADD, operand = 21 (direct addressing)
EXECUTE: MAR ← 21 # address of the data
MDR ← [[MAR]] # MDR = 9
ACC ← [ACC] + [MDR] # ACC = 14 + 9 = 23
# --- Instruction 3: STA 22 ---
FETCH: MAR ← [PC] # MAR = 2
MDR ← [[MAR]] # MDR = STA 22
CIR ← [MDR] # CIR = STA 22
PC ← [PC] + 1 # PC = 3
DECODE: opcode = STA, operand = 22 (direct addressing)
EXECUTE: MAR ← 22 # destination address
MDR ← [ACC] # MDR = 23
[[MAR]] ← [MDR] # memory[22] = 23
Notice how the same fetch sequence repeats verbatim for every instruction — only the operand and the execute phase differ. This regularity is exactly what makes pipelining (a later lesson) possible.
Branches are the one case where the PC's "point to the next instruction" behaviour is overridden. Consider a conditional branch BRZ 8 ("branch to address 8 if the last result was zero") sitting at address 5, with PC = 5 and the zero flag set:
FETCH: MAR ← [PC] # MAR = 5
MDR ← [[MAR]] # MDR = BRZ 8
CIR ← [MDR] # CIR = BRZ 8
PC ← [PC] + 1 # PC = 6 (provisional "next instruction")
DECODE: opcode = BRZ, operand = 8, test the zero flag
EXECUTE: IF zero flag = 1 THEN
PC ← 8 # OVERWRITE the PC with the branch target
ENDIF
# next fetch will now read from address 8, not 6
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.