实模式内存寻址中的段和偏移量是多少?

nar*_*tra 12 memory x86 assembly operating-system real-mode

我正在读关于内存寻址的内容.我读了关于段偏移然后关于描述符偏移的内容.我知道如何计算实模式下的确切地址.这一切都没问题,但我无法理解究竟是什么偏移?到处都读到:

在实模式下,寄存器只有16位,因此最多只能寻址64k.为了允许寻址更多内存,地址קד是从segment*16 + offset计算的.

在这里我可以理解第一行.我们有16位,所以我们可以解决最多2 ^ 16 = 64k.

但这第二行是什么?细分代表什么?为什么我们将它乘以16?为什么我们添加偏移.我只是无法理解这个偏移是什么?有人可以解释我或给我链接吗?

cHa*_*Hao 17

当英特尔正在构建8086时,机器中有超过64KB的有效案例,但它无法使用32位地址空间.那时候,甚至一兆字节都是一大堆内存.(还记得臭名昭着的引语"640K应该对任何人来说都足够了吗?"这实际上是一个错误翻译的事实,当时,1MB非常.)"gigabyte"这个词在未来15到20年内不会被普遍使用,并且在那之后的5到10年内它不会像RAM一样.

因此,他们没有实现如此巨大的地址空间以至于"永远不会"被充分利用,而是实现了20位地址.他们仍然使用16位字作为地址,因为毕竟这是一个16位处理器.上面的单词是"段",下面的单词是"偏移".然而,这两个部分相当重叠 - "段"是一个64KB的内存块,起始于(segment) * 16,而"偏移"可以指向该块内的任何位置.为了计算实际地址,您将地址的段部分乘以16(或将其左移4位......相同的事物),然后添加偏移量.当你完成后,你有一个20位的地址.

 19           4  0
  +--+--+--+--+
  |  segment  |
  +--+--+--+--+--+
     |   offset  |
     +--+--+--+--+
Run Code Online (Sandbox Code Playgroud)

例如,如果段为0x8000,偏移量为0x0100,则实际地址为((0x8000 << 4) + 0x0100)== 0x80100.

   8  0  0  0
      0  1  0  0
  ---------------
   8  0  1  0  0
Run Code Online (Sandbox Code Playgroud)

尽管如此,数学很少是整齐的 - 0x80100可以用几千个不同的片段来表示:偏移组合(4096,如果我的数学是正确的).

  • @cHoa:分段偏移架构的原因实际上是一个实用的.8086旨在增强和取代8008,8080和8085处理器.这些都是8位处理器.段偏移寻址允许为这些较旧的8位处理器编写的汇编语言在新的16位处理器上运行而无需修改.见:http://en.wikipedia.org/wiki/Intel_8086 (5认同)
  • 因为英特尔决定将两个16位数字转换为20位数字."偏移"是地址中最有用的部分(因为"段"实际上指的是太粗粒度),所以你*在某处添加**... (4认同)
  • 即便如此,这也是一种痛苦;因为 8086 只给你两个段寄存器来真正玩,你最终会花费相当多的代码只是将段寄存器交换到每个操作的位置。出于同样的原因,您不想对所有事情都使用“巨大”模型——它很容易比它的价值更麻烦。 (2认同)

GJ.*_*GJ. 13

在x86实模式内存下,物理地址为20位长并且是calcolated:

PhysicalAddress = Segment * 16 + Offset
Run Code Online (Sandbox Code Playgroud)

另请参阅:实模式内存管理