Ste*_*eve 5 compiler-construction assembly x86-64 disassembly
当cmpw %ax -5x86-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.
Run Code Online (Sandbox Code Playgroud)
所以会有两个编码结果:
66 3d fb ff ; this for opcode 3d
66 83 f8 fb ; this for opcode 83
Run Code Online (Sandbox Code Playgroud)
那么哪一个更好?
我在下面尝试了一些在线反汇编程序
两者都可以反汇编到原点指令.但为什么6683fb00也有效,有效663dfb.
两种编码长度相同,因此无法帮助我们做出决定.
但是,正如@Michael Petch评论的那样,imm16编码将导致Intel CPU上的解码器中出现LCP停顿.(因为没有66操作数大小前缀,3D imm32所以操作数大小前缀会改变指令其余部分的长度.这就是为什么它被称为长度变化前缀失速 .AFAIK,你会得到相同的在16位代码中停止使用32位立即数.)
该imm8编码不引起我所知道的任何微架构的问题,所以它的青睐. 请参阅Agner Fog的microarch.pdf以及x86标签wiki中的其他链接.
使用更长的指令来避免LCP停顿是值得的.(例如,如果您知道寄存器的高16位为零或符号扩展,则使用32位操作数大小可以避免LCP停顿.)
Intel SnB系列CPU具有uop缓存,因此在执行之前不必总是重新解码指令.不过,uop缓存很小,所以值得.
当然,如果你正在调整AMD,那么这不是一个因素.我忘记了Atom和Silvermont解码器是否也有LCP档位.
663d是前缀+操作码cmp ax, imm16. 663dfb不起作用,因为它消耗了以下指令的第一个字节.当解码器看到时66 3D,它从指令流中获取接下来的2个字节作为立即数.
| 归档时间: |
|
| 查看次数: |
525 次 |
| 最近记录: |