在汇编语言中,为什么保存在段寄存器中的任何值都乘以10?我试图在很多书中找到答案,但我没有。为什么保存在一个段寄存器中的值乘以10?
回答
首先,汇编不是一种单一的语言,也不是一个单一的东西。你必须说出你正在谈论哪个架构,以便任何人给出正确的答案。
其次,段寄存器不总是乘以10。我甚至会说他们从来没有乘以10,因为10对二进制系统来说不是一个自然数。如果你问为什么,例如在x86架构中得到一个物理地址,CPU将segment寄存器乘以0x10(十进制数),并增加一个偏移量,答案是:因为设计者选择了这样的值。
接下来你会问为什么他们选择这个。一个16位的段寄存器可以保存从0到65535的值。乘以16将得到0到1048575之间的地址,即1MB。 1MB是一个很好的访问内存。
其他体系结构可能有不同的乘数,即使是非常数乘数也是如此。但他们很可能永远是2的幂。
为了理解设计决定,我们需要回到1974年。
那时我们没有现在的小型化,在一个包装中制造的很小。
1974年是英特尔刚刚推出8080芯片的一年,该芯片拥有16位地址总线,这意味着至多64 KiB内存是可寻址的。然而,8080主要有8位寄存器,所以程序员通常需要将两个寄存器配对以形成一个16位地址。
同时在1976年开始设计新芯片8086。设计人员意识到64 KiB内存太低,因此他们决定增加专用于内存寻址的引脚数量,但是芯片封装的引脚数量仍然存在很大的限制。
对于这款新芯片,他们解决了20位地址,或1 MiB的可寻址内存。
在考虑为什么20位我们进入的原因,影响的周期,我们需要考虑,其中包括,两个重要因素:
- 的引脚数量。它必须尽可能低。
- 寄存器的大小。你如何用16位数字编码20位数字?
16位是不够的,所以他们需要更多的位,最简单的解决方案将使用32位,配对两个寄存器。
但32位太过分了!
下一个明显的选择是24,16 + 8,因为它是8的倍数(一个字节)。
然而24位仍然太多。 根据Intel 8008 to 8086 by Stephen P. Morse et a, Pag. 17他们考虑了这个假设,但被拒绝。
如果他们不能有8的大小倍数,他们可能至少有4的倍数(半字节)。
所以他们解决了20位。
现在出现了一个问题:你如何使用16位数做20位数? 英特尔设计人员选择了众所周知的分段机制:其中一个数字(段)向左移4(乘以16或10h),然后再将它们相加在一起。
更直接的方法是直接从段寄存器的低半字节中取出地址的额外4位。
他们可能拒绝这个出于各种原因,例如:一个)它浪费)段B的12位)也许它不能重用任何ALU部件Ç它不允许地址别名。
这样或那样的选择,因此每个x86兼容的CPU都需要实现这种分段模型,这是历史遗留问题。
此模型自80286以来已经扩展,并且实际上已弃用x64处理器。
- 1. 为什么使用临时寄存器将值传递给段寄存器?
- 2. 为什么只有四个寄存器?
- 3. 为什么setjmp(3)不保存AMD64上的所有寄存器?
- 4. xmm寄存器的乘法
- 5. 在MIPS中将寄存器值乘以常数?
- 6. Verilog:将值保存在寄存器中(分配给相同的寄存器)
- 7. 为什么值被存储在寄存器0x605040c,而不是12?
- 8. 是什么使一个值不安全的存储在寄存器中?
- 9. 保存xmm寄存器的值
- 10. 为什么编译器将变量存储在寄存器中?
- 11. gcc为什么在读取时保存一个被调用者保存寄存器?
- 12. 为什么我们需要建议一个变量存储在寄存器中?
- 13. 乘法,乘法寄存器verilog
- 14. 为什么建立普通布尔MRSW寄存器需要2个寄存器?
- 15. MASM为什么不递减寄存器查找数组中的下一个值?
- 16. MIPS寄存器保存
- 17. 为什么24位寄存器?
- 18. Pthread段寄存器
- 19. 为什么SSE指令保留YMM寄存器的高128位?
- 20. 寄存器和临时寄存器有什么区别?
- 21. 如何将两个寄存器相乘并将它们存储在不同的寄存器中?
- 22. 为什么存储在寄存器中的数据有内存地址?
- 23. 一个实体被保存,另一个不存在 - 为什么?
- 24. intel 80386在哪里保存寄存器?
- 25. XMM寄存器值
- 26. 寄存器值8086
- 27. 汇编保持寄存器值?
- 28. 溢出一个寄存器
- 29. 为什么CPU寄存器像Garbage Collector的根一样行事?
- 30. PIC寄存器(%ebx)是做什么的?
你在谈论实模式编程吗?它们不乘以10.它们左移8位,因为它们最初是支持24位寻址的16位体系结构。 –