2016-08-23 51 views
2

8086使用16位指令,但RAM地址只保存8位CPU如何从RAM加载程序?它是否加载一个地址,然后检查指令是否需要1/2/3个字节(例如,将一个立即移动到一个8/16位寄存器),然后执行操作,或者我错误地认为一个RAM'空间'是16位大?从8086的RAM中加载程序

+0

RAM实际上是24位。这就是为什么它的段落与段寄存器加偏移量对齐。当你指定一个8位地址时,它假定段寄存器是基址。 –

回答

5

许多指令是多字节的,是的,这意味着它们跨越两个或更多的地址。

IIRC,8086的存储器总线是16位,所以它可以在一次操作中加载16位(两个相邻的地址)。您将字节可寻址内存与总线宽度相混淆。

它加载一个地址,然后如果所述指令需要1/2/3字节检查(例如移动即时到寄存器8/16位)

它不断地取指令字节到6字节缓冲区(一次2个字节,因为它是一个16位CPU,带有16位总线)。该缓冲区足够大以容纳最大允许的8086指令(不包括可能被单独解码的前缀IDK)。当它完成前面的指令时,它会查看缓冲区。请参阅下面的链接以获得更好的描述,但它可能会尝试将缓冲区解码为整个指令。如果它在找到指令结束之前碰到提取缓冲区的末尾,它会等到下一个提取循环完成并再次尝试。

另请参阅:8086 CPU architecture,这是“8086代码获取”的第一个命中。它确认提取和执行确实重叠,所以它以最基本的方式流水线化

TL:DR:它获取到一个缓冲区,直到它有一个完整的指令解码。然后它将任何额外的字节移到缓冲区的前面,因为它们是下一条指令的一部分。

我读过,通常指令取指是8086的瓶颈,因此对代码大小的优化几乎胜过其他任何东西。


流水线CPU不需要等待执行前面的指令就可以开始解码。现代CPU也有更高带宽的代码获取,因此他们有一个解码指令队列准备就绪(除了当分支搞砸了。)请参阅http://agner.org/optimize/以及标记wiki中的其他链接。


此外,一些非常常见的指令是单字节,如push r16

+2

我想我们可以进入我最爱的解码杂草[** The Assembly of Sect 3.3.7 **](https://courses.engr.illinois.edu/ece390/books/artofasm/CH03 /CH03-3.html#HEADING3-102)。这是解码的概述。 –

+0

非常感谢您的快速回复。 –

+2

8086上的预取队列只有6个字节,而指令长度没有限制。您可以使用尽可能多的冗余前缀,15个字节的限制与'386一起添加。没有冗余前缀,指令可能会超过6个字节。例如'mov [es:0],1234'长度为7个字节。但是,根本没有前缀,我不认为8086指令可以超过6个字节。我的猜测是前缀字节被单独解码,并且单独地像他们自己的指令一样。 –