在x86-64中将寄存器移至自身会有什么好处

时间:2019-03-14 18:02:22

标签: assembly x86-64 nasm

我正在x86-64 NASM中做一个项目,遇到了以下说明:

mov rdi, rdi

在我的教授写的编译器输出中。

我搜索了所有内容,但是找不到为什么需要这样做的提及。它会影响标志,还是我不理解的聪明之处?

要提供一些上下文信息,它会在循环使用sub递减同一寄存器之前出现。

1 个答案:

答案 0 :(得分:7)

指令mov rdi, rdi只是一个低效的3字节NOP,等效于实际的NOP指令。组装它会生成字节组合

48 89 ff       mov rdi, rdi

可以将其视为NOP,因为它既不会影响标志也不会影响寄存器。唯一的架构效果是使程序计数器前进到下一条指令。

通常使用(多字节)NOP将下一条指令对齐到某个地址,一个流行的例子是对齐的跳转目标,尤其是在循环的顶部。

但是在这种情况下,这似乎只是非优化编译器生成的代码的产物,不是用于故意填充。


与真正的nop相比,它效率低下,因为它不是特殊情况下可以更便宜地运行。 (它的 micro 建筑效果在当前CPU上是不同的)。它通过RDI向依赖关系链增加了一个延迟周期,并使用了ALU执行单元。 (英特尔和AMD CPU都无法“消除” mov same,same并在寄存器重命名阶段以零延迟运行它,仅在不同的架构寄存器之间运行。例如,mov rax,rdi可以和{{ 1}},如果您不介意破坏RAX,可以在IvyBridge +和Ryzen上使用。)

在这种情况下,您应该删除它(而不是将其替换为nop(带有冗余操作数大小前缀的短NOP)或66 66 90(长NOP),因为它没有被用于填充。