为什么x86 nopl指令采用操作数?

Rou*_*per 13 x86 assembly x86-64

为什么noplx86可执行文件中的指令采用操作数?不要只是做,好吧,什么都没有?

nopl 0x0(%rax)

sup*_*cat 7

许多处理器的二进制指令集具有多种表示功能相同的指令的方式.例如,原始ARM指令集包含使​​用表格的任何值加载R0的指令,b << n其中b值为0到255,并且n是0到24之间的偶数.如果想要加载值为256的R0,则可以加载与加载它的指令1<<8,或者一个可以使用的指令4<<6,16<<464<<2.加载这些不同值的指令都具有不同的二进制编码,即使所有四个指令具有相同的效果.

某些编译器的汇编程序不遗余力地提供一种代码应该使用哪些看似相同的指令的方法.虽然这通常并不重要,但有时可能需要避免在一段代码中使用某些字节值,或者有时候对一段代码中的某些字节的修改应该具有特定的效果.例如,前述ARM指令中的8位用于指定值b.如果代码b用值12 覆盖上述指令之一的部分,则加载到R0中的值将取决于使用了哪四个原始指令; 它可以是0x0C00,0x0300,0x00C0或0x0030.

尽管8x86的汇编器通常不能明确区分所有可能的指令编码,但是可能存在一些能够指定应该在指令中包括哪些字节值的上下文可能是有帮助的.例如,处理异常的一种方法是在发生异常时进行例行检查,返回地址处的指令是否是某种特定形式的NOP,如果是,则将其操作数解释为数据结构的地址持有与例外相关的信息.实际上,支持异常的大多数8x86语言都使用其他处理异常的方法,但上述方法会使获取和执行长NOP所需的时间减慢正常的函数返回,

  • 虽然如此,但在这种情况下,更有用的是操作数更改指令的长度,如注释中重复链接中的 [nrz 的答案](http://stackoverflow.com/a/12564044/) 所示。 (3认同)