在汇编语言中,为什么段寄存器中保存的任何值都乘以10?我试图在这么多书中找到答案,但我没有。
答案 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位地址。
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处理器。