When Intel designed the original x86, the 8086 (and 8088 derivative), they included Segmentation to allow the 16-bit processor to access more than 16 bits worth of address. They did this by making the 16-bit addresses be relative to a given 16-bit Segment Register, of which they defined four: Code Segment (CS
), Data Segment (DS
), Extra Segment (ES
) and Stack Segment (SS
).
Most instructions implied which Segment Register to use: instructions were fecthed from the Code Segment, PUSH
and POP
implied the Stack Segment, and simple data references implied the Data Segment - although this could be overridden to access memory in any of the other Segments.
The implementation was simple: for every memory access, the CPU would take the implied (or explicit) Segment Register, shift it four places to the left, then add in the indicated address:
+-------------------+---------+
Segment | 16-bit value | 0 0 0 0 |
+-------------------+---------+
PLUS
+---------+-------------------+
Address | 0 0 0 0 | 16-bit value |
+---------+-------------------+
EQUALS
+-----------------------------+
Result | 20-bit memory address |
+-----------------------------+
This allowed for various techniques:
CS
, DS
and SS
all had the same value);CS
, DS
and SS
all 4K (or more) separate from each other - remember it gets multiplied by 16, so that's 64K).It also allowed bizarre overlaps and all sorts of weird things!
When the 80286 was invented, it supported this legacy mode (now called "Real Mode"), but added a new mode called "Protected Mode" (q.v.).
The important things to notice is that in Real Mode:
In other words... not very protected at all!