为什么偏移量是 16 位?

逆向工程 部件 登记
2021-07-07 14:27:06

有人告诉我,segment:offset成对用于表示 20 位。段被移位 4 位,值加上偏移量成为物理地址。在 32 位系统上我不必再担心了,但我仍然很好奇。

  1. 为什么偏移分配为 16 位,而不是 4 位?
  2. 多个虚拟地址对应一个物理地址没有问题吗?
1个回答

您指的是上个世纪 80 年代初。8086 体系结构使用这种寻址 20 位物理内存的方式,当时是巨大的 1(一!)MByte,或“一百万字节的内存”,正如 Intel 在 /1/, p.2-7 中所称。

这些“逻辑地址”,正如英特尔在 /1/ 中所称,主要有两个用途:

  1. 这个segment:offset 方案背后的一个想法是拥有大小为64kB 的段,可以在可用的20 位地址空间(8086) 的任何地方(在16 字节边界处)使用,使这些段独立于物理地址。英特尔在 /1/, p2-8 中写道:

“分段使构建可重定位和可重入程序变得容易。......(重定位意味着能够在几个不同的内存区域中运行相同的程序,而无需更改程序本身的地址)......”

  1. 另一个想法是将内存的不同逻辑部分分隔在不同的段中。主要识别的内存区域是:代码、数据。Stack 和 Extra(后者例如用作数据传输的目的地)。因此,段寄存器被相应地命名为 CS、DS、SS 和 ES。这些名称一直存在到今天(在 32 位世界中)。后来添加了 FS 和 GS 段寄存器,用于操作系统的特定区域。

因此,为了回答您的第一个问题,不能使用 4 位而不是 16 位的偏移量来构建每个 64kB 的段,以便在必要时重新定位。64kB 段大小是 16 位系统(如 8086)中的“自然”值。

关于您的第二个问题,如果不小心处理重叠段,例如当代码和数据重叠时,重叠段当然可能会出现问题。但英特尔明确希望段可以以最可能的方式重叠,通过赋予它们相同的值,允许在只有 64kByte 内存的系统中使用这种分段架构。

根据英特尔 (/1/, p.2-8) 的说法:“在内存总量为 64K 字节或更少的系统中,可以将所有段寄存器设置为相等并具有完全重叠的段。”

/1/:iAPX 86、88、168 和 188 用户手册,程序员参考,英特尔 1983