8086 Architecture & Programmer's Model

The 8086 exposes sixteen-bit data, pointer, segment, instruction, and flag registers while its original implementation splits execution from bus access and overlaps both through a six-byte prefetch queue. The register contract survived far longer than that implementation.

The 8086 is useful because its architecturally visible machine is small enough to hold in one diagram, yet already contains the ideas that make x86 distinctive: variable-length instructions, overlapping register names, implicit operands, segmentation, a downward-growing stack, flags, and a separate port-I/O space. Its programmer's model is an ISA contract. The execution-unit/bus-interface split is one historical implementation of that contract.

Visible state and hidden machinery #

Execution Unit (EU) decode · ALU · effective offset · flags Bus Interface Unit (BIU) physical address · fetch · memory / I/O cycles Data registers AH │ AL = AX BH │ BL = BX CH │ CL = CX DH │ DL = DX Pointer and index registers SP BP SI DI FLAGS CF PF AF ZF SF · TF IF DF · OF Address state CS DS SS ES IP — next instruction offset six-byte instruction queue sequential prefetch while the bus is free offset / request operand / bytes
Program-visible registers cross the historical EU/BIU implementation boundary; software depends on their semantics, not on the drawing of the units.

Intel partitioned the original CPU into two cooperating units:

  • The Execution Unit (EU) decodes and executes instructions, operates the ALU, updates flags, and calculates effective offsets.
  • The Bus Interface Unit (BIU) forms physical addresses, fetches instruction bytes, and performs memory and I/O bus cycles.

The 8086 BIU has a six-byte instruction queue. When bus capacity is free, it fetches ahead while the EU executes earlier bytes. A memory operand or empty queue makes the EU wait for the BIU. A taken control transfer invalidates prefetched bytes because the sequential fetch address is no longer correct.

This is early overlap, not a promise that one instruction completes every clock. The ISA defines final visible state. Queue fill, bus cycles, and timing belong to the original microarchitecture.

Register groups #

Register Programmer-visible role Important implicit use
AX = AH:AL accumulator, general data multiply/divide, port I/O, many compact encodings
BX = BH:BL general data and base one of the memory-address bases
CX = CH:CL general data and count repeat, loop, and variable shift/rotate counts
DX = DH:DL general data high half of wide multiply/divide; variable I/O port number
SP stack pointer top of stack in SS
BP base pointer stack-relative data; defaults to SS for memory addressing
SI source index source of string operations, normally DS:SI
DI destination index destination of string operations, fixed to ES:DI on 8086
CS, DS, SS, ES segment bases code, ordinary data, stack, and extra/string destination
IP instruction offset next instruction within CS; not a general operand register
FLAGS status and control condition codes, single step, interrupt mask, string direction

The low and high bytes of AX, BX, CX, and DX are independently nameable. Writing AL changes only bits 7:0 of AX; writing AX changes both AH and AL. SP, BP, SI, and DI have no byte names in the original ISA.

FLAGS is both result and control state #

Flag Meaning Question it answers
CF carry/borrow Did unsigned arithmetic exceed the operand width?
PF parity Does the low result byte contain even parity?
AF auxiliary carry Was there a carry/borrow across bit 3, used by decimal-adjust operations?
ZF zero Is the result zero?
SF sign What is the high result bit?
OF signed overflow Is the mathematical signed result outside the representable range?
TF trap Should execution generate a single-step trap?
IF interrupt enable May maskable external interrupts be recognized?
DF direction Do string indexes increment or decrement?

CF and OF describe different interpretations of the same result bits. 0xFFFF + 1 overflows unsigned 16-bit arithmetic (CF=1) but is -1 + 1 = 0 in signed arithmetic (OF=0). 0x7FFF + 1 does not carry out of bit 15 (CF=0) but cannot be represented as a signed 16-bit result (OF=1).

Not every instruction defines every flag. Correct code asks the instruction reference which flags are written, preserved, or left undefined before branching on them.

Instruction execution crosses the partition #

Consider ADD [BX+SI+8], AX:

  1. The EU decodes the instruction bytes from the queue.
  2. It computes the 16-bit effective offset BX + SI + 8.
  3. The BIU combines that offset with the selected segment base and reads the word.
  4. The EU adds AX, produces a 16-bit result, and updates defined status flags.
  5. The BIU writes the result back to memory.

The syntax names one instruction. The machine performs address calculation, one or more bus cycles, an ALU operation, flag generation, and writeback. A register-register ADD avoids the operand bus cycles but has the same architectural arithmetic semantics.

8086 and 8088 share an ISA boundary #

The 8088 executes essentially the same 16-bit instruction set and exposes the same registers, but its external data bus is eight bits and its instruction queue is four bytes rather than six. A word transfer therefore uses different external bus behavior. Software compatibility does not imply identical throughput or board design.

This is a useful distinction:

  • ISA compatibility asks whether the same instruction bytes have the same visible meaning.
  • microarchitectural compatibility would require similar queues, execution resources, caches, and timing.
  • platform compatibility additionally requires memory maps, peripherals, firmware, ABI, and operating environment.

What persists in current x86 #

Current Intel processors retain the lower 16-bit register names and a real-address mode that implements the 8086 programming environment with extensions. Reset enters real-address mode. Later x86 adds wider registers, more segment registers, protected and long modes, paging, caches, speculative out-of-order execution, and many new encodings.

The useful legacy is therefore the state contract and encoding ancestry. The original EU/BIU block diagram is not a model of a current core.

Reading an unknown state dump #

Use this order:

  1. Determine the execution mode and operand/address size.
  2. Form the next instruction address from CS:IP in 8086 real mode.
  3. Identify implicit register roles for the current instruction.
  4. Separate effective offset from final physical address.
  5. Decode only the flags that the previous instruction actually defined.
  6. If control arrived through a call or interrupt, validate the stack image before blaming the register values.

The dump becomes understandable when each field is tied to the operation that owns it.

Sources

  1. docsThe 8086 Family User's Manualpdfnotes
  2. docsIntel 64 and IA-32 Architectures Software Developer's Manualpdf

Searches titles, aliases, headings, summaries, and full text.↑↓ move ↵ open esc close