Assembly NASM rep nop作为暂停进行组装
考虑以下用x86汇编编写的函数Assembly NASM rep nop作为暂停进行组装,assembly,x86,gdb,x86-64,nasm,Assembly,X86,Gdb,X86 64,Nasm,考虑以下用x86汇编编写的函数 foo: rep nop ret 使用NASM组装代码,并使用gdb将其分解,我们有: (gdb) disas foo Dump of assembler code for function foo: 0x0000000000000610 <+0>: pause ;pause ???? 0x0000000000000612 <+2>: ret 0x
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.
(gdb)disas foo
函数foo的汇编程序代码转储:
0x0000000000000610:暂停;暂停????
0x0000000000000612:ret
0x0000000000000613:nop字PTR cs:[rax+rax*1+0x0]
0x000000000000061d:nop DWORD PTR[rax]
汇编程序转储结束。
它使用原始程序集中未显示的
暂停
指令。为什么会这样?这是NASM故意记录的行为吗?因此,如果一些早期的x86cpu
s没有pause
,我们可以使用rep-nop
?将rep-nop组装成pause指令与其说是NASM,不如说是GDB解码分别构成rep前缀和nop指令的F3
和90
字节作为pause指令
这是因为暂停指令也被编码为
F3 90
。这是x86 CPU有意记录的行为,因此不带暂停指令的CPU会将其视为NOP。它与NASM或GDB没有任何关系,只是它们根据CPU文档组装和反汇编指令。是的,英特尔选择了rep nop
作为pause
的编码,因此它可以在不检查CPU支持的情况下使用;较旧的CPU将其解码为nop
。请阅读手册中的暂停@PeterCordes对rep
的手动输入甚至没有指定要与nop
一起使用。REP前缀可以精确地添加到INS、OUTS、MOV、LODS和STOS指令中,REPE、REPNE、REPZ和REPNZ前缀可以添加到CMPS和SCAS指令中。因此,这就是我将rep nop
视为NASM的一个功能的原因。@PeterCordes此外,还指出F3H前缀是为以下指令定义的,其余指令未定义:F3H作为rep/REPE/REPZ表示字符串和输入/输出指令。F3H是POPCNT、LZCNT和ADOX的必填前缀。它没有提到nop
。有人删除了我的第二条评论,IDK为什么。我说,当我在谷歌上搜索rep nop pause时,链接的副本是第一次点击,它充分解释了这种情况。无论如何,rep
不是nop
的有效前缀,这就是为什么CPU会忽略它,而CPU不会将其识别为另一条指令编码的一部分。将F3
作为强制前缀的指令列表并非详尽无遗;它缺少tzcnt
和pause
,并且还用作for-HLE(同样是因为无法识别它的CPU忽略了它)。您告诉NASM输出一个REP前缀字节,即值为0xF3的字节,后跟一个NOP操作码字节,即值为0x90的字节。您告诉NASM输出字节序列F3 90
,所以它就是这么做的。NASM在任何时候都没有考虑这是否是一个有效的指令序列。它没有将rep
nop
从无效指令序列更改为有效指令序列。不管您是否有意,它只是碰巧是一个。但问题是,rep
未指定与nop
一起使用。显然,F3H前缀是为以下指令定义的,其余指令未定义:F3H为REP/REPE/REPZ,表示字符串和输入/输出指令。F3H是POPCNT、LZCNT和ADOX的必填前缀。@St.Antario:作为pause
编码的一部分,它不是rep
前缀。@BeeOnRope前缀应用程序的详细信息在手册中不清楚。但是在手动卷中搜索时,我没有发现如果前缀没有与指令一起使用,那么它就会被忽略。此外,lock
也是nop
的无效前缀,但明确指出,如果遇到lock nop
,则会引发#UD
。您不必查看所有手册。您可以查看just,并看到它被编码为F3 90,即“rep”和“nop”字节。无论你认为这是一个前缀还是只是编码的一部分只是语义。一个很好的原则是,具体胜于广泛:如果你发现一个语句说暂停是这样编码的,那么这可能是正确的,而不是对rep前缀的一般描述,特别是因为rep的主要用途(重复的事情)是不同的。