举个例子:x86_64 CPU读取128位指令。
据我所知,这只是x86处理器中发生的事情。 否则,不可能例如将64位数字添加到64位寄存器(操作码将占用几位+ 64位,数字> 64)。
我想知道的是指令中的位数限制以及如果指令大于位数(数据总线)则如何读取指令。 此外,我也知道大多数RISC CPU都使用固定大小的指令,所以如果你直接传递一个数字操作数,那么指令的大小是否会加倍?
答案 0 :(得分:6)
x86_64 CPU读取128位指令
这不会发生,最大指令大小定义为15个字节。您可以构建更长的指令,但它们将无效。
您不需要16个字节来获取一个采用64位立即数操作数的指令。只有一些x64指令甚至可以在第一时间执行此操作,例如mov r64, imm64
,其编码为REX.W B8+r io
,因此为10个字节。几乎所有64位x64指令立即采用符号扩展的更短的立即数,8或32位。
在RISC ISA中,通常不可能立即像字大小一样大,你必须分两步在寄存器中构造大值或从内存加载它们。但x64,就像它的x86根一样,绝对不是RISC。
我怀疑这个问题(部分)是由逐个来自数据总线的指令的心理形象所激发的,这对于MIPS等很好,但是具有可变长度的指令,没有像x86那样的对齐要求你不能这样做 - 不管你选择什么样的块,它可能(并且很可能)通过一些指令切割。因此,在最简单的视图中,解码是具有缓冲区的状态机,解码第一条指令并将其从缓冲区中删除,在有空间时填充更多字节(当然现在它更复杂)。
答案 1 :(得分:4)
这不是现代CPU的工作方式,但数据总线比最长的指令更窄并不是一个问题。
例如,8086必须处理比其16位数据总线宽的指令编码,没有任何L1缓存来隐藏这种影响。据我了解,8086只是将字(16位)读入解码缓冲区,直到解码器立即看到整个指令。如果有一个剩余的字节,它将移动到解码缓冲区的前面。下一个insn的指令读取实际上与刚刚解码的指令的执行同时发生,但是代码获取仍然是8086中的主要瓶颈。
因此CPU只需要一个与最大允许指令(不包括前缀)一样大的缓冲区。这是6 bytes for 8086,这正是8086's prefetch buffer的大小。
“直到解码器看到整个指令”是一种简化:8086分别解码前缀,并“记住”它们作为修饰符。 8086缺少后续CPU的15字节最大总insn长度限制,因此您可以fill a 64k CS segment with repeated prefixes on one instruction)。
现代CPU(如Intel P6和SnB系列)至少以16B块从L1 I-cache中获取代码,并实际并行解码多个指令。 @ Harold很好地涵盖了你的其余部分。
另请参阅Agner Fog's microarch guide以及x86标记wiki中的其他链接,详细了解现代x86 CPU的工作原理。