16 位寄存器最多只能寻址 0xFFFF(65,536 字节,64KB)。当这还不够时,英特尔添加了段寄存器。
任何逻辑设计都会简单地将两个 16 位寄存器组合成一个 32 位地址空间,(例如0xFFFF : 0xFFFF = 0xFFFFFFFF
),但是不……英特尔不得不让我们感到很奇怪。
历史上,前端总线 (FSB) 只有 20 条地址线,因此只能传输 20 位地址。为了“纠正”这一点,英特尔设计了一种方案,其中段寄存器仅将您的地址扩展 4 位(理论上为 16 位 + 4 = 20)。
为此,段寄存器从其原始值左移 4 位,然后添加到通用寄存器中的地址(例如[es:ax] = ( es << 4 ) + ax
)。 注意:左移 4 位相当于乘以 16。
就是这样。以下是一些说明性示例:
;; everything's hexadecimal
[ 0:1 ] = 1
[ F:1 ] = F1
[ F:0 ] = F0
[ F:FF] = 1EF ; [F becomes F0, + FF = 1EF]
[ F000 : FFFF ] = FFFFF (max 20-bit number)
[ FFFF : FFFF ] = 10FFEF (oh shit, 21-bit number!)
因此,您仍然可以寻址超过 20 位。发生什么了?地址“环绕”,就像模数运算(作为硬件的自然结果)。所以,0x10FFEF
变成0xFFEF
。
你有它!英特尔雇佣了一些愚蠢的工程师,我们不得不忍受它。