为什么段寄存器中保存的任何值乘以10?

时间:2016-04-06 05:12:55

标签: assembly

在汇编语言中,为什么段寄存器中保存的任何值都乘以10?我试图在这么多书中找到答案,但我没有。

2 个答案:

答案 0 :(得分:3)

首先,汇编不是单一语言,实现也不是一件事。你不得不说出你正在谈论哪种架构让任何人给出正确答案。

其次,段寄存器不总是乘以10。我甚至会说它们从未乘以10,因为10不是二进制系统的自然数。

如果你问为什么,例如,在x86架构中获取物理地址,CPU将段寄存器乘以0x10(十进制16)并添加一个偏移,答案是:因为设计师选择了这样。

接下来你会问他们为什么选择那个。 16位段寄存器可以保存0到65535之间的值。乘以16可以得到0到1048575之间的地址,即1MB。 1MB是一个很好的内存来访问。

其他架构可能有不同的乘数,甚至是非常数。但他们很可能永远是2的权力。

答案 1 :(得分:2)

为了理解设计决定,我们需要回到1974年 那时我们没有现在的小型化,可以在封装中制造的引脚数量非常少。

1974年,英特尔刚刚推出8080芯片,这是一款带有16位地址总线的芯片,这意味着最多64 KiB的存储器是可寻址的。
然而,8080大多数是8位寄存器,因此编程器通常需要将两个寄存器配对以形成16位地址。

与此同时,1976年开始设计新的8086芯片 设计人员意识到64 KiB的内存太低,因此他们决定增加专用于内存寻址的引脚数量,但是芯片封装的引脚数仍然存在很大限制。
对于这个新芯片,他们确定了20位地址,或1 MiB的可寻址存储器 在考虑为什么20位我们进入原因 - 效应的循环时,我们需要考虑两个重要因素:

  1. 引脚数。它必须尽可能低。
  2. 寄存器的大小。如何使用16位数字生成20位数字?
  3. 16位是不够的,所以他们需要更多的位,最简单的解决方案就是使用32位,配对两个寄存器。
    但是32位太多了! 下一个显而易见的选择是24,16 + 8,因为它是8(一个字节)的倍数 然而,24位仍然太多了。 根据{{​​3}},他们考虑了这个假设,但被拒绝了 如果它们不能具有8的大小倍数,则它们至少可以具有4的倍数(半字节) 所以他们安顿了20位。

    现在出现一个问题:如何使用16位数字生成20位数字? 英特尔设计师选择了众所周知的分段机制:其中一个(段)向左移动4(乘以16或10h),然后再将它们加在一起

    更简单的方法是直接从段寄存器的低半字节中取出额外的4位地址。
    他们可能由于各种原因拒绝了这一点,例如: a)它浪费了段的12位 b)可能它无法重用任何ALU组件 c )它不允许地址别名。

    不管怎样,做出了选择,因此每个x86兼容的CPU需要实现这种分段模型,这是历史遗留。
    此模型自80286以来已经扩展,并且几乎不再使用x64处理器。