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

标签 assembly x86-64 nasm

我正在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/

相关文章:

assembly - 64 位模式下的地址覆盖前缀

c++ - 在 amd64 模式下编译 (visual studio 2010)

winapi - Windows下如何用汇编语言编写hello world?

c++ - 如何从通用函数符号计算或指定COFF符号表的 "value"?

assembly - LEA 指令的替代语法

C 宏 - 如何将整数值转换为字符串文字

linux - 为什么 main() 函数的 argc 在 ESP+4 而不是 ESP+0?

c - ASM 调用约定

performance - AVX512中 "masked"存储的粒度是多少?

assembly - 汇编器字符输出