首先,为什么编译器会插入这些
nop
?它们似乎没有任何对齐目的。其次,带有相对寻址参数的
nop
是什么?其十六进制为0F 1F 40 00
。查看http://ref.x86asm.net/,这似乎是一条称为“ hintable NOP”的指令,但是我很难找到有关它的相关信息。下一条指令从
....C3
开始,并且是真实/有效的指令(即不是nop
或任何道德上与nop
等效的东西)。#1 楼
这些是多字节nop
指令。 来自http://www.felixcloutier.com/x86/NOP.html
说明
该指令不执行任何操作。它是一个单字节或多字节的
NOP,它占用指令流中的空间,但不影响机器上下文,除了EIP寄存器。
字节格式的NOP在具有以下模型编码的处理器上可用:
多字节NOP指令不会更改
寄存器的内容,并且不会发出内存操作。在非64位模式和64位模式下,指令的
操作相同。
操作
一字节NOP指令是别名助记符。对于XCHG(E)AX,
(E)AX指令。
不支持多字节NOP指令。
该指令的内存操作数形式允许软件创建一个“ no operation”字节序列作为一条指令。对于需要多字节NOP的情况,建议的操作
(32位模式和64位模式)为:
+---------+--------------------------------+------------------------------+
| LENGTH | ASSEMBLY | BYTE SEQUENCE |
+---------+--------------------------------+------------------------------+
| | | |
| 2 bytes | 66 NOP | 66 90H |
| | | |
| 3 bytes | NOP DWORD ptr [EAX] | 0F 1F 00H |
| | | |
| 4 bytes | NOP DWORD ptr [EAX + 00H] | 0F 1F 40 00H |
| | | |
| 5 bytes | NOP DWORD ptr [EAX + EAX*1 + | 0F 1F 44 00 00H |
| | 00H] | |
| | | |
| 6 bytes | 66 NOP DWORD ptr [EAX + EAX*1 | 66 0F 1F 44 00 00H |
| | + 00H] | |
| | | |
| 7 bytes | NOP DWORD ptr [EAX + 00000000 | 0F 1F 80 00 00 00 00H |
| | H] | |
| | | |
| 8 bytes | NOP DWORD ptr [EAX + EAX*1 + | 0F 1F 84 00 00 00 00 00H |
| | 00000000H] | |
| | | |
| 9 bytes | 66 NOP DWORD ptr [EAX + EAX*1 | 66 0F 1F 84 00 00 00 00 00H |
| | + 00000000H] | |
+---------+--------------------------------+------------------------------+
#2 楼
关于第一个问题,当编译器有兴趣对齐其后的代码时,NOP
是由编译器发出的,通常是因为该代码是跳转的目标(如循环),并且将其与段落对齐是有益的( 16字节边界)或缓存行(32字节边界)。换句话说,这样做是为了提高性能。
评论
Nitpick:该表出现在Intel的官方参考资料中(除非我的记忆欺骗了我,否则描述非常相似)。也许最好将OP指向该点。
–杂件
16年2月9日在9:28
@Jongware:链接的站点是从英特尔文档生成的
–伊戈尔·斯科钦斯基♦
16年2月9日,12:53