Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly NASM rep nop作为暂停进行组装_Assembly_X86_Gdb_X86 64_Nasm - Fatal编程技术网

Assembly NASM rep nop作为暂停进行组装

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

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

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故意记录的行为吗?因此,如果一些早期的x86
cpu
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的主要用途(重复的事情)是不同的。