我正在x86-64 NASM中做一个项目,遇到了以下说明:
mov rdi, rdi
在我的教授写的编译器输出中。
我到处搜索,但是找不到为什么需要这样做的提法。它会影响标志,还是我不理解的聪明之处?
为了提供一些上下文,它存在于循环中,就在使用
sub
递减同一寄存器之前。
最佳答案
指令mov rdi, rdi
只是一个低效的3字节NOP,等效于实际的 NOP
指令。组装它,生成字节组合
48 89 ff mov rdi, rdi
可以将其视为
NOP
,因为它既不影响标志,也不影响寄存器。唯一的架构效果是使程序计数器前进到下一条指令。通常使用(多字节)
NOP
将下一条指令对齐到某个地址,一个流行的示例是对齐的跳转目标,尤其是在循环的顶部。但是在这种情况下,这似乎只是非优化编译器生成代码的产物,而没有用于有意填充。
与真正的
nop
相比,它效率低下,因为它不会被特殊情况下廉价地运行。 (它的微体系结构效果在当前的CPU上是不同的)。它通过RDI向依赖关系链增加了一个延迟周期,并使用了ALU执行单元。 (无论是Intel还是AMD CPU都不能“消除” mov same,same
并在寄存器重命名阶段以零延迟运行它,仅在不同的架构寄存器之间运行。例如,如果不这样做,mov rax,rdi
可以和IvyBridge +和Ryzen上的nop
一样便宜。介意破坏RAX。)在您的情况下,您应该删除它(而不是将其替换为
66 66 90
(带有冗余操作数大小前缀的短NOP)或01 1F 00
(长NOP),因为它没有用于填充。
关于assembly - 在x86-64中将寄存器移至自身会有什么好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55169234/