Assembly 为什么段寄存器中保存的任何值都要乘以10?
在汇编语言中,为什么保存在段寄存器中的任何值都要乘以10?我在很多书中都试图找到答案,但我没有。首先,汇编不是一种单一的语言,实现也不是一件单一的事情。您必须说出您所谈论的体系结构,以便任何人都能给出正确的答案 第二,段寄存器并不总是乘以10。我甚至可以说它们永远不会乘以10,因为10不是二进制系统的自然数 例如,如果您询问为什么在x86体系结构中要获得物理地址,CPU会将段寄存器乘以0x10(16位十进制数),并添加一个偏移量,答案是:因为设计者选择了这样做 接下来你会问他们为什么选择这个。16位段寄存器可以保存0到65535之间的值。将其乘以16,得到的地址从0到1048575,即1MB。1MB是一个很好的内存访问量Assembly 为什么段寄存器中保存的任何值都要乘以10?,assembly,Assembly,在汇编语言中,为什么保存在段寄存器中的任何值都要乘以10?我在很多书中都试图找到答案,但我没有。首先,汇编不是一种单一的语言,实现也不是一件单一的事情。您必须说出您所谈论的体系结构,以便任何人都能给出正确的答案 第二,段寄存器并不总是乘以10。我甚至可以说它们永远不会乘以10,因为10不是二进制系统的自然数 例如,如果您询问为什么在x86体系结构中要获得物理地址,CPU会将段寄存器乘以0x10(16位十进制数),并添加一个偏移量,答案是:因为设计者选择了这样做 接下来你会问他们为什么选择这个。1
其他体系结构可能有不同的乘数,甚至是非常数乘数。但是它们很可能永远是2的幂。首先,汇编不是一种语言,实现也不是一件事。您必须说出您所谈论的体系结构,以便任何人都能给出正确的答案 第二,段寄存器并不总是乘以10。我甚至可以说它们永远不会乘以10,因为10不是二进制系统的自然数 例如,如果您询问为什么在x86体系结构中要获得物理地址,CPU会将段寄存器乘以0x10(16位十进制数),并添加一个偏移量,答案是:因为设计者选择了这样做 接下来你会问他们为什么选择这个。16位段寄存器可以保存0到65535之间的值。将其乘以16,得到的地址从0到1048575,即1MB。1MB是一个很好的内存访问量
其他体系结构可能有不同的乘数,甚至是非常数乘数。但它们很可能永远是2的幂。为了理解设计决策,我们需要回到1974年。
当时我们没有现在的小型化,封装中可以制造的引脚数量非常少 1974年是英特尔刚刚推出8080的一年,8080是一种具有16位地址总线的芯片,这意味着最多64千字节的内存是可寻址的。
然而,8080大部分是8位寄存器,因此程序员通常需要将两个寄存器配对以形成16位地址 与此同时,1976年开始设计新芯片8086。
设计人员意识到64千字节的内存太低,所以他们决定增加专用于内存寻址的管脚数量,但是芯片封装的管脚数量仍然有很大的限制。
对于这个新芯片,他们决定使用20位地址或1个MiB的可寻址内存。
当考虑为什么20位进入一个因果循环的时候,我们需要考虑两个重要的因素:
但是32位太多了
下一个明显的选择是24,16+8,因为它是8的倍数(一个字节)。
但是24位还是太多了。 根据研究,他们考虑了这个假设,但被拒绝了。
如果它们的大小不能是8的倍数,则至少可以是4的倍数(一个半字节)。
所以他们决定买20比特 现在出现了一个问题:如何用16位数字生成20位数字? 英特尔设计师选择了众所周知的分段机制:在将两个数字相加之前,将其中一个数字(分段)左移4(乘以16或10小时) 更直接的方法是直接从段寄存器的低半字节获取额外的4位地址。
他们可能出于各种原因拒绝了这一点,例如:a)它浪费了段的12位b)可能无法重用任何ALU组件c)它不允许地址别名 不管怎样,我们都做出了选择,因此每个与x86兼容的CPU都需要实现这个细分模型,这是一个历史遗留问题。
该型号自80286以来一直在扩展,实际上已不推荐用于x64处理器。为了理解设计决策,我们需要回到1974年。
当时我们没有现在的小型化,封装中可以制造的引脚数量非常少 1974年是英特尔刚刚推出8080的一年,8080是一种具有16位地址总线的芯片,这意味着最多64千字节的内存是可寻址的。
然而,8080大部分是8位寄存器,因此程序员通常需要将两个寄存器配对以形成16位地址 与此同时,1976年开始设计新芯片8086。
设计人员意识到64千字节的内存太低,所以他们决定增加专用于内存寻址的管脚数量,但是芯片封装的管脚数量仍然有很大的限制。
对于这个新芯片,他们决定使用20位地址或1个MiB的可寻址内存。
当考虑为什么20位进入一个因果循环的时候,我们需要考虑两个重要的因素:
但是32位太多了
下一个明显的选择是24,16+