我正在查看MSIL并注意到有很多nop指令。
MSDN文章说它们不执行任何操作,并且如果需要修补,它们用于填充空间。在调试版本中使用得比发布版要多。
我知道这些语句在汇编语言中用于对齐后面的指令,但为什么MSIL需要使用nop指令呢?
(编辑说明:被接受的答案是关于机器码NOP而不是最初问题所问的MSIL/CIL NOPs。)
我正在查看MSIL并注意到有很多nop指令。
MSDN文章说它们不执行任何操作,并且如果需要修补,它们用于填充空间。在调试版本中使用得比发布版要多。
我知道这些语句在汇编语言中用于对齐后面的指令,但为什么MSIL需要使用nop指令呢?
(编辑说明:被接受的答案是关于机器码NOP而不是最初问题所问的MSIL/CIL NOPs。)
在软件破解领域,一种经典的解锁应用程序的方法是使用NOP(无操作指令)来修补检查密钥、注册、时间期限等内容的代码行,使其不起作用,并继续启动应用程序,就像已经注册了一样。
我也看到过在修改自身代码以混淆其功能作为占位符的NOP(非操作指令)(非常古老的副本保护)。
它们允许链接器用较短的指令(短跳转)替换较长的指令(通常是长跳转)。NOP占用了额外的空间,代码不能被移动,否则会阻止其他跳转的工作。这发生在链接时,因此编译器无法知道长跳转还是短跳转更合适。
至少,这是它们传统用途之一。
.NET编译器会对MSIL输出进行对齐吗?我认为这可能有助于加速访问IL的速度...另外,我的理解是它被设计成可移植的,并且某些其他硬件平台需要对齐访问。
我学习的第一个汇编语言是SPARC,所以我熟悉分支延迟槽。如果你不能用另一条指令来填充它,通常是你原本要放在分支指令上面的指令或者在循环中增加计数器,那么你就使用NOP。
我不熟悉破解,但我认为使用NOP覆盖堆栈是常见的做法,这样你就不必精确计算恶意函数的起始位置。
我使用NOP指令来自动调整进入ISR后累积的延迟时间。非常方便,可以精确控制时序。