我最近了解到,nop指令实际上是xchg eax, eax……它所做的基本上是与自身交换eax

就CPU而言,交换实际上发生了吗?

评论

一次它做到了,它不再是NOP。

@DCoder是什么意思?

阅读我链接到的页面。在某些AMD的x64处理器中存在一个错误,该错误实际上执行了xchg EAX,EAX ...在x64模式下,大多数32位指令将其操作数的高332位清零,而该指令也是如此。

@DCoder 32bit怎么样。仍然有意义吗?

它对32位没有任何影响。

#1 楼

有几条指令,取决于编译器可以使用。 xchg eax, eax是字节码90。这是一条合法指令,占用单个处理周期。此外,还有其他几条指令可以代替xchg eax, eax

lea eax, [eax + 0x00]    byte code 8D 40 00
mov eax, eax             byte code 89 C0


由于所有这些指令的长度都不相同,因此编译器选择了以下指令之一:适当的版本取决于对齐要求。
关于编译器的选择,有几点建议:


GAS(GNU汇编器,由GCC使用)x86 NOP操作可以在函数i386_align_code()中找到。 br />同样,对于LLVM,它位于X86AsmBackend :: writeNopData()中


评论


但它们可能不如xchg那样“像NOP”。除此之外,记录的多字节NOP是设置的“ 0f 1f / 0”。

–彼得·弗里
2013年6月20日19:16

唯一的其他nop指令是0F 1F / 0,在支持的CPU上为NOP r / m16和NOP r / m32。根据Intel doc(第4-163页),在x86-64中它可能需要3到9个字节。因此,即使可以使用mov eax,eax和其他替代方法,它也比真正的nop不利,因为它阻塞了CPU管道,并且缺少在nop指令中实现的其他硬件优化。

–ahmd0
18年5月17日在21:45

#2 楼

简短的回答是“是”。实际上,如果您直接通过生成机器语言操作码进行实验,您会发现有一系列有效的NOP操作,所有这些操作都需要一个处理器周期来执行。从技术上讲不是“记录在案”的,您会发现它非常接近0x90,


br />

评论


我不认为这是真的。我认为非EAX需要更多的周期(3个而不是1个),并且我认为所有XCHG版本实际上将x86_64上的高阶32位设为0。 stackoverflow.com/a/25053039/124486

–埃文·卡洛尔(Evan Carroll)
18-2-6在1:41