NASM 代表 nop 组装为暂停

St.*_*rio -2 x86 assembly gdb x86-64 nasm

考虑以下用 x86 汇编语言编写的函数

foo:
        rep
        nop
        ret
Run Code Online (Sandbox Code Playgroud)

使用 NASM 汇编代码并反汇编它,gdb我们有:

(gdb) disas foo
Dump of assembler code for function foo:
   0x0000000000000610 <+0>:     pause  ;pause ????
   0x0000000000000612 <+2>:     ret    
   0x0000000000000613 <+3>:     nop    WORD PTR cs:[rax+rax*1+0x0]
   0x000000000000061d <+13>:    nop    DWORD PTR [rax]
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)

它使用pause原始程序集中未提供的指令。为什么会这样?这是 NASM 故意记录的行为吗?那么如果一些早期的 x86cpu没有pause我们可以直接使用rep nop吗?

Ros*_*dge 5

与其说NASM将REP NOP组装成PAUSE指令,不如说GDB将分别构成REP前缀和NOP指令的F390字节解码为PAUSE指令。

这是因为 PAUSE 指令也被编码为F3 90. 这是 x86 CPU 有意记录的行为,因此没有 PAUSE 指令的 CPU 会将其视为 NOP。它与 NASM 或 GDB 没有任何关系,只是它们根据 CPU 文档汇编和反汇编指令。

  • 您不必通读手册。您可以仅查看[暂停本身的一页](https://www.felixcloutier.com/x86/pause),并看到它的编码为 F3 90,即“rep”和“nop”字节。无论您将其视为前缀还是编码的一部分,都只是语义。一个好的原则是具体胜过广泛:如果您发现一个声明说暂停是这样编码的,那么这可能是正确的,而不是代表前缀的一般描述,_特别是_因为代表的主要目的(重复的事情)是不同的。 (5认同)
  • @St.Antario:作为“pause”编码的一部分,它*不*充当“rep”前缀。 (3认同)