【问题标题】:NASM rep nop assembles as pause [duplicate]NASM rep nop 组装为 pause [重复]
【发布时间】:2020-02-21 10:53:33
【问题描述】:

考虑以下用 x86-assembly 编写的函数

foo:
        rep
        nop
        ret

使用 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.

它使用了原始程序集中没有出现的pause 指令。为什么它会这样工作?这是 NASM 有意记录的行为吗?所以如果一些早期的 x86 cpus 没有pause,我们可以只使用rep nop

【问题讨论】:

  • 是的,Intel 选择了rep nop 作为pause 的编码,所以它可以在不检查CPU 支持的情况下使用;较旧的 CPU 将其解码为 nop。阅读手册暂停。 felixcloutier.com/x86/pause
  • @PeterCordes 手动输入rep 甚至没有指定它与nop 一起使用。正是可以在INS、OUTS、MOVS、LODS和STOS指令中添加REP前缀,在CMPS和SCAS指令中可以添加REPE、REPNE、REPZ和REPNZ前缀。 所以这就是我将 rep nop 视为 NASM 的一个功能的原因。
  • @PeterCordes 此外,有人指出 F3H 前缀为以下指令定义,其余未定义:F3H 为字符串和输入/输出指令的 REP/REPE/REPZ。 F3H 是 POPCNT、LZCNT 和 ADOX 的强制前缀。没有提到nop
  • 有人删除了我的第二条评论,IDK 为什么。我说当我用谷歌搜索rep nop pause 时,链接的副本是第一个命中,它充分说明了这种情况。无论如何,rep 不是nop 的有效前缀,这就是为什么它被不将其识别为另一条指令编码的一部分的 CPU 忽略。以F3 作为强制前缀的指令列表并不详尽;它缺少 tzcntpause,并且还用作 HLE 的 xrelease prefix(同样是因为无法识别它的 CPU 会忽略它)。
  • 你告诉 NASM 输出一个 REP 前缀字节,即值为 0xF3 的字节,后跟一个 NOP 操作码字节,即值为 0x90 的字节。您告诉 NASM 输出字节序列F3 90,这就是它所做的。 NASM 在任何时候都没有考虑这是否是一个有效的指令序列。它没有将 rep nop 从无效指令序列更改为有效指令序列。它只是碰巧是一个,无论你是否愿意。

标签: assembly x86 gdb x86-64 nasm


【解决方案1】:

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

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

【讨论】:

  • 但令人担忧的是,rep 未指定与nop 一起使用:rep docs。确切地说,F3H 前缀是为以下指令定义的,为其余指令定义的: F3H 作为 REP/REPE/REPZ 用于字符串和输入/输出指令。 F3H 是 POPCNT、LZCNT 和 ADOX 的强制前缀。
  • @St.Antario:作为pause 编码的一部分,它充当rep 前缀。
  • @BeeOnRope 前缀应用的细节在手册中是模糊的。但是通过手动 VOL 搜索,我没有发现如果前缀没有与指令一起使用,那么它会被忽略。此外,lock 也是 nop 的无效前缀,但明确指出,如果遇到 lock nop,则会引发 #UD
  • 您不必通读手册。您可以只查看 one page for pause itself 并看到它被编码为 F3 90,即“rep”和“nop”字节。无论您将其视为前缀还是只是编码的一部分,都只是语义。一个好的原则是具体胜过广泛:如果你发现一个语句说暂停是这样编码的,这可能是正确的,而不是对代表前缀的一般描述,尤其是,因为主要目的rep 的(重复的东西)不同。
猜你喜欢
  • 1970-01-01
  • 2018-06-23
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2018-09-08
  • 1970-01-01
相关资源
最近更新 更多