编码指令时cmpw %ax -5
对于 x86-64,从 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
那么哪个更好呢?
我在下面尝试了一些在线反汇编程序
https://onlinedisassembler.com/odaweb/
两者都可以反汇编到原点指令。但为什么
6683fb00
也可以使用和 663dfb
没有。
最佳答案
两种编码的长度相同,因此这无助于我们做出决定。
然而,正如@Michael Petch 所评论的,imm16
编码将导致 Intel CPU 上的解码器中的 LCP 停顿。 (因为没有 66
操作数大小前缀,它将是 3D imm32
,所以操作数大小前缀会改变指令其余部分的长度。这就是为什么它被称为 Length-Changing-Prefix stall 。AFAIK,你会在 16 位代码中获得相同的停顿以使用 32 位立即数。)
imm8
编码不会对我所知道的任何微体系结构造成问题,所以赞成它。 见 Agner Fog's microarch.pdf ,以及来自 x86 的其他链接标记维基。
值得使用更长的指令来避免 LCP 停顿。 (例如,如果您知道寄存器的高 16 位为零或符号扩展,则使用 32 位操作数大小可以避免 LCP 停顿。)
Intel SnB 系列 CPU 具有 uop 缓存,因此在执行之前不必总是重新解码指令。尽管如此,uop 缓存很小,所以值得。
当然,如果您正在为 AMD 进行调整,那么这不是一个因素。我忘了 Atom 和 Silvermont 解码器是否也有 LCP 档位。
回复:第 2 部分:663d
是 cmp ax, imm16
的前缀+操作码. 663dfb
不“工作”,因为它消耗了以下指令的第一个字节。当解码器看到66 3D
,它从指令流中获取接下来的 2 个字节作为立即数。
关于assembly - x86指令编码如何选择操作码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37611247/