x86指令编码如何选择操作码

时间:2016-06-03 09:54:45

标签: assembly compiler-construction x86-64 disassembly

对于x86-64的编码指令cmpw %ax -5,来自Intel-instruction-set-reference-manual,我有两个操作码可供选择:

3D iw CMP AX, imm16 I Valid Valid Compare imm16 with AX.
83 /7 ib CMP r/m16, imm8 MI Valid Valid Compare imm8 with r/m16.

因此会有两个编码结果:

66 3d fb ff ; this for opcode 3d
66 83 f8 fb ; this for opcode 83

然后哪一个更好?

我在

下面尝试了一些在线反汇编程序

两者都可以反汇编到原点指令。但为什么6683fb00也有效且663dfb没有。

1 个答案:

答案 0 :(得分:5)

两种编码长度相同,因此无法帮助我们做出决定。

但是,正如@Michael Petch评论的那样,imm16编码将导致Intel CPU上的解码器中的LCP停顿。 (因为没有66操作数大小前缀,它将是3D imm32,因此操作数大小前缀会改变指令的 rest 的长度。这就是为什么它& #39; s称为Length-Changing-Prefix stall。AFAIK,您在16位代码中使用32位立即获得相同的停顿。)

imm8编码在我知道的任何微架构上都没有问题,所以非常喜欢它。请参阅Agner Fog's microarch.pdf以及{中的其他链接3}}标签维基。

值得使用更长的指令来避免LCP停顿。 (例如,如果您知道寄存器的高16位为零或符号扩展,则使用32位操作数大小可以避免LCP停顿。)

Intel SnB系列CPU具有uop缓存,因此在执行之前不必重新解码指令。不过,uop缓存很小,所以值得。

当然,如果您正在调整AMD,那么这不是一个因素。我忘记了Atom和Silvermont解码器是否也有LCP档位。

回复:第2部分:

663dcmp ax, imm16的前缀+操作码。 663dfb没有"工作"因为它消耗了以下指令的第一个字节。当解码器看到66 3D时,它会从指令流中获取接下来的2个字节作为立即数。