在8086中从RAM加载程序

yan*_*erg 2 assembly processor cpu-architecture x86-16

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

Pet*_*des 5

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

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

它是否加载一个地址,然后检查指令是否需要1/2/3字节(例如,将一个立即数移到寄存器8/16位)

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

另请参阅:8086 CPU架构,这是"8086代码获取"的第一个命中.它确认了获取和执行是否重叠,因此它以最基本的方式进行流水线操作.

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

我已经读过,通常指令获取是8086的瓶颈,所以优化代码大小几乎超过了其他所有东西.


流水线CPU不必等待执行前一条指令就可以开始解码.现代CPU也有很多高带宽码取,所以他们的解码指令准备去(除非分支搞砸.)见队列http://agner.org/optimize/在等环节标签维基.


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

  • 我想我们可以在我最喜欢的[**The Assembly of Assembly Sect 3.3.7**]中找到解码的杂草(https://courses.engr.illinois.edu/ece390/books/artofasm/CH03/ CH03-3.html#HEADING3-102).这是解码的概述. (2认同)
  • 8086上的预取队列只有6个字节,而指令长度没有限制.您可以根据需要使用尽可能多的冗余前缀,使用'386添加15字节限制.没有冗余前缀,指令可能超过6个字节.例如`mov [es:0],1234`长7个字节.但是,没有前缀我不认为8086指令可以超过6个字节.我的猜测是前缀字节分别单独解码,就像它们自己的指令一样. (2认同)