8.1 Fetch, Decode, and Execute
Chapter 7 treated instructions as tools for building programs. Chapter 8 looks beneath that view: how does a bit pattern in memory become controlled changes to registers, flags, and memory? The answer is an instruction cycle, a dependency-ordered sequence that obtains instruction bytes, interprets them, gathers operands, produces a result, and commits that result.
Chapter 4 introduced the 8086 Bus Interface Unit, Execution Unit, and prefetch queue. Those units can overlap work. The phase model below is therefore a teaching trace of one instruction's dependencies, not a claim that the real chip leaves every unit idle between five rigid boxes.
One instruction moves through distinct kinds of state
A useful conceptual cycle has five phases:
1. Fetch: read instruction bytes from the address identified by CS:IP and advance IP past those bytes.
2. Decode: interpret opcode fields, operand width, addressing form, and instruction length.
3. Operand read: obtain register values, immediates, or a memory operand.
4. Execute: route data through transfer logic or the arithmetic logic unit (ALU).
5. Writeback: latch the result into the selected architectural destination and update specified flags.
Consider ADD AX,BX encoded as 01 D8, with AX=0001H and BX=0002H. Fetching two bytes can advance IP from 0100H to 0102H before AX changes. Decode identifies ADD, word width, AX as destination, and BX as source. Operand read makes 0001H and 0002H available internally. Execute produces 0003H. AX remains 0001H until writeback enables it to latch 0003H.
This separation explains a common diagnostic clue: a correct value may exist at an ALU output while the programmer-visible destination remains old. Producing a value and committing state are different events.
Variable-length instructions make boundaries part of decoding
8086 instructions do not all occupy the same number of bytes. An opcode may be followed by a ModR/M byte, displacement, immediate data, or some combination. Memory does not mark which bytes are opcodes. The decoder must start at a known instruction boundary and use the current instruction's fields to determine where the next boundary lies.
For the stream:
Address: 0100 0101 0102 0103 0104 0105 0106
Byte: B8 34 12 40 75 FD F4sequential decoding gives:
- 0100H–0102H:
B8 34 12→MOV AX,1234H
- 0103H:
40→INC AX
- 0104H–0105H:
75 FD→JNZ 0103H
- 0106H:
F4→HLT
The relative branch displacement FDH means signed −3. It is added to the IP after the two-byte JNZ, so target=0106H−3=0103H. A valid branch target must land on an instruction boundary. Landing at 0101H would enter the middle of MOV's immediate and make the decoder interpret data as an opcode.
A taken control transfer replaces the sequential next IP with a target. On an 8086 it also invalidates prefetched bytes from the abandoned path, because those bytes no longer match the new IP. Section 8.4 will connect this lost work to performance.
We now know what information each phase must produce. Section 8.2 examines the hardware routes that carry operand values to the ALU and commit results to registers.