我正在x86-64 NASM做一个项目并且遇到了指令: mov rdi, rdi 在我的教授写的编译器的输出中. 我已经搜遍了所有,但无法找到为什么需要它.它会影响旗帜还是我不明白的聪明之处? 为了给出
mov rdi, rdi
在我的教授写的编译器的输出中.
我已经搜遍了所有,但无法找到为什么需要它.它会影响旗帜还是我不明白的聪明之处?
为了给出一些上下文,它在相同的寄存器用sub递减之前就存在于一个循环中.
指令mov rdi,rdi只是一个低效的3字节NOP,相当于实际的NOP
指令.组装它,它会生成字节组合
48 89 ff mov rdi, rdi
这可以被认为是NOP,因为它既不影响标志也不影响寄存器.唯一的架构效果是将程序计数器推进到下一条指令.
使用(多字节)NOP将下一条指令与某个地址对齐是很常见的,一个流行的例子是对齐的跳转目标,尤其是在循环的顶部.
但在这种情况下,它似乎只是来自非优化编译器的代码生成工件,而不是用于有意填充.
与真正的nop相比,效率低下,因为它不会特别容易运行. (它的微架构效应在当前的CPU上是不同的).它通过RDI为依赖链添加了一个延迟周期,并使用ALU执行单元. (英特尔和AMD CPU都不能“消除”相同的,同样的并且在寄存器重命名阶段以零延迟运行它,仅在不同的架构寄存器之间运行.例如,mov rax,rdi可以和IvyBridge上的nop一样便宜Ryzen,如果你不介意破坏RAX.)
在您的情况下,您应该删除它(而不是用66 66 90(具有冗余操作数大小前缀的短NOP)或01 1F 00(长NOP)替换它,因为它不用于填充.