我试图了解由编译器完成的x64
程序集优化。
我在Windows 8.1上使用Release
IDE将Visual Studio 2008 SP1
构建为一个小型C ++项目。
其中一行包含以下汇编代码:
B8 31 00 00 00 mov eax,31h
0F 1F 44 00 00 nop dword ptr [rax+rax]
这是屏幕截图:
据我所知,
nop
本身就是do nothing
,但是我从未见过像这样的操作数。有人可以解释它的作用吗?
最佳答案
在此页上其他位置的comment中,Michael Petch指向web page,它描述了Intel x86多字节NOP操作码。该页面上有一张有用的信息表,但不幸的是HTML乱七八糟,所以您无法阅读它。这是该页面上的一些信息,并且该表以可读的形式显示:
多字节NOP http://www.felixcloutier.com/x86/NOP.html
一字节NOP指令是XCHG(E)AX,(E)AX指令的别名助记符。
多字节NOP指令在受支持的处理器上不执行任何操作,并在不支持多字节NOP指令的处理器上生成未定义的操作码异常。
指令的存储器操作数形式允许软件创建一条“无操作”的字节序列作为一条指令。
对于需要多字节NOP的情况,建议的操作(32位模式和64位模式)为:[我的编辑:在64位模式下,写入rax
而不是eax
。]
Length Assembly Byte Sequence ------- ------------------------------------------ -------------------------- 1 byte nop 90 2 bytes 66 nop 66 90 3 bytes nop dword ptr [eax] 0F 1F 00 4 bytes nop dword ptr [eax + 00h] 0F 1F 40 00 5 bytes nop dword ptr [eax + eax*1 + 00h] 0F 1F 44 00 00 6 bytes 66 nop word ptr [eax + eax*1 + 00h] 66 0F 1F 44 00 00 7 bytes nop dword ptr [eax + 00000000h] 0F 1F 80 00 00 00 00 8 bytes nop dword ptr [eax + eax*1 + 00000000h] 0F 1F 84 00 00 00 00 00 9 bytes 66 nop word ptr [eax + eax*1 + 00000000h] 66 0F 1F 84 00 00 00 00 00
Note that the technique for selecting the right byte sequence--and thus the desired total size--may differ according to which assembler you are using.
For example, the following two lines of assembly taken from the table are ostensibly similar:
nop dword ptr [eax + 00h]
nop dword ptr [eax + 00000000h]
这些仅在前导零的数量上有所不同,并且某些汇编程序可能很难禁用始终对最短字节序列进行编码的“有用”功能,这可能使第二个表达式不可访问。
对于多字节NOP情况,您不需要此“帮助”,因为您需要确保您实际上获得了所需的字节数。因此,问题在于如何指定mod和r / m位的精确组合,最终以所需的disp大小结尾-但仅通过指令助记符即可。这个主题很复杂,当然超出了我的知识范围,但是Scaled Indexing,MOD+R/M和SIB可能是一个起点。
现在,据我所知,您只是在想,如果发现通过指令助记符来强制或不加强汇编程序的合作是困难的或不可能的,那么您始终可以将
db
(“定义字节”)作为简单的替代方法,那就是um ,保证能正常工作。
关于visual-studio - x64汇编指令“nop dword ptr [rax + rax]”有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43991155/