英特尔设计原始的x86、8086(和8088派生产品)时,它们包括分段功能,以允许16位处理器访问价值16位以上的地址。他们通过使16位地址相对于给定的16位段寄存器来做到这一点,他们定义了四个:代码段(CS),数据段(DS),额外段(ES)和堆栈段(SS)。
大多数指令隐含了要使用的段寄存器:指令是从代码段中体现出来的,PUSH并POP隐含着堆栈段,而简单的数据引用隐含了数据段-尽管可以覆盖该段以访问其他任何段中的内存。
实现很简单:对于每次内存访问,CPU都会使用隐式(或显式)段寄存器,将其向左移动四个位置,然后添加指示的地址:
+-------------------+---------+ Segment | 16-bit value | 0 0 0 0 | +-------------------+---------+ PLUS +---------+-------------------+ Address | 0 0 0 0 | 16-bit value | +---------+-------------------+ EQUALS +-----------------------------+ Result | 20-bit memory address | +-----------------------------+
这允许各种技术:
允许代码,数据和堆栈都可以相互访问(CS,DS并且SS都具有相同的值);
保持代码,数据和堆栈彼此完全分开(CS,DS以及SS所有4K(或更多)彼此分开-记住它乘以16,即64K)。
它还允许奇异的重叠和各种奇怪的事情!
发明80286时,它支持此传统模式(现称为“实模式”),但添加了一个新模式,称为“保护模式”(qv)。
需要注意的重要事项是在实模式下:
只需将正确的值放入段寄存器并访问16位地址,即可访问任何存储器地址。
“保护”的程度是允许程序员出于不同的目的而将不同的内存区域分开,并使其更难以意外写入错误的数据,同时仍然可以做到这一点。
换句话说...根本不是很受保护!