我正在查看MSIL并注意到有很多nop指令。
MSDN文章说它们不执行任何操作,并且如果需要修补,它们用于填充空间。在调试版本中使用得比发布版要多。
我知道这些语句在汇编语言中用于对齐后面的指令,但为什么MSIL需要使用nop指令呢?
(编辑说明:被接受的答案是关于机器码NOP而不是最初问题所问的MSIL/CIL NOPs。)
我正在查看MSIL并注意到有很多nop指令。
MSDN文章说它们不执行任何操作,并且如果需要修补,它们用于填充空间。在调试版本中使用得比发布版要多。
我知道这些语句在汇编语言中用于对齐后面的指令,但为什么MSIL需要使用nop指令呢?
(编辑说明:被接受的答案是关于机器码NOP而不是最初问题所问的MSIL/CIL NOPs。)
NOP指令有几个用途:
nop
)在调试中的使用方式:它为基于行的标记(例如断点)提供了一个机会,在这些代码中,发布构建不会发出任何标记。
伙计!无操作指令太棒了!它是一条什么都不做,但消耗时间的指令。在遥远的旧时代,您会使用它在关键循环中进行微调,或更重要的是作为自修改代码的填充。
我曾在一家处理器公司工作了四年,他们使用NOP指令来确保前一个操作完成后再开始下一个操作。例如:
将值加载到寄存器(需要8个周期) nop 8 将1加到寄存器
这确保了在执行添加操作之前,寄存器具有正确的值。
NOP指令还可以用于填充执行单元,例如中断向量必须具有特定大小(32个字节),因为向量0的地址是0,向量1的地址是0x20等等,所以编译器在必要时会插入NOP指令。
虽然有些晚了50年,但还是来得及。
Nop指令在手动编写汇编代码时非常有用。如果您需要删除代码,则可以将旧的操作码替换为nop指令。
同样地,您可以通过覆盖某些操作码并跳转到其他位置来插入新代码。在那里,您放置被覆盖的操作码,并插入新代码。准备好后再跳回原来的位置。
有时候必须使用可用的工具。在某些情况下,这只是一个非常基本的机器码编辑器。
现在,随着编译器的出现,这些技术已经没有任何意义了。
他们可能会在调试时使用它们来支持编辑并继续。这为调试器提供了空间,以便替换旧代码而不更改偏移量等内容。
一种有些不正统的用法是 NOP-Slides,它们被用于缓冲区溢出漏洞。
其中一个经典用途是使您的调试器始终将源代码行与IL指令相关联。