4.4 Segmentation, Physical Addresses, and Endianness
The 8086 has 16-bit registers, so one register can directly encode only 65,536 different values. Yet the processor exposes a 20-bit address bus and can address byte locations, or 1 MiB.
It bridges those widths with segmented addressing.
Segment plus offset forms a physical address
A memory reference uses two 16-bit quantities:
- a segment value, which selects a base in units of 16 bytes;
- an offset, which selects a byte relative to that base.
The original 8086 forms the bus address with:
Multiplying by 16 is the same as shifting left by four binary bits, or appending one hexadecimal zero.
For 1234H:0010H:
A segment base is aligned to a paragraph, the 8086 term for a 16-byte unit. The segment value is not itself the physical base; it must first be multiplied by 16.
Default segment-offset partnerships
| Activity | Usual pair | Meaning |
|---|---|---|
| Instruction fetch | CS:IP | Code Segment plus Instruction Pointer |
| Most data access | DS:effective offset | Data Segment plus an instruction-computed offset |
| Stack access | SS:SP or SS:BP | Stack Segment plus stack pointer/base |
| String destination | ES:DI | Extra Segment plus Destination Index |
These defaults reduce how much an instruction must encode. Some instructions allow a segment override, and exact effective-address rules are introduced with the instruction set.
Overlap and 20-bit wraparound
Segments can overlap. 1000H:0020H and 1001H:0010H both form physical 10020H:
Therefore segment:offset notation is not a one-to-one name for a physical byte.
The largest untruncated sum is greater than 20 bits. On the original 8086, FFFFH:0010H calculates 100000H, but the chip has address pins only A19 through A0. The exposed low 20 bits are 00000H, so the address wraps. Later PC compatibility introduced the A20 topic; this section's rule is specifically the original 8086 bus behavior.
Lab 1 — construct, compare, and wrap addresses
Adjust segment and offset values while every hexadecimal step updates. Missions cover ordinary composition, overlapping logical addresses, the highest address, and original-8086 wraparound.
Check your understanding
Bytes have an address order
Memory is byte-addressed: each address names one 8-bit cell. A 16-bit word therefore occupies two adjacent addresses.
The 8086 is little-endian:
- the low-order byte is stored at the lower address;
- the high-order byte is stored at the next address.
Storing word 1234H beginning at address 1000H produces:
| Address | Stored byte | Role in the word |
|---|---|---|
1000H | 34H | low byte |
1001H | 12H | high byte |
Reading that word reconstructs 12H × 100H + 34H = 1234H. Endianness changes byte order in memory; it does not turn the register value into 3412H.
Even and odd word addresses
The 8086 has a 16-bit data bus organized as two byte banks. A word beginning at an even address can transfer both bytes in one aligned bus cycle. A word beginning at an odd address crosses an aligned word boundary, so the original 8086 needs two bus cycles.
This is a performance distinction, not an invalid-address rule. The word at 1001H is legal; it is simply split across the boundaries 1000H–1001H and 1002H–1003H.
Lab 2 — repair a little-endian memory layout
Store, decode, swap, and directly edit adjacent memory cells. One mission deliberately presents reversed bytes; another places a word at an odd address and exposes the bus-cycle consequence.
Check your understanding
A three-step memory checklist
1. Form the address: shift the segment left four bits, add the offset, and retain the original 8086's low 20 bus bits.
2. Determine the width: a byte uses one memory cell; a word uses two adjacent cells.
3. Lay out the bytes: on the 8086, put the low byte at the lower address.
You can now connect an instruction stream, programmer-visible registers, FLAGS, and physical memory. The next chapter can build on this machine state to explain how 8086 instructions encode and execute useful work.