汇编语言: 什么是语义NOP?

8
我想知道汇编语言中的“语义NOP”是什么?
5个回答

5

指的是不是实际的nop,但不影响程序行为的代码。

在C语言中,下面的代码序列可以被认为是语义上的NOP:

{
    // Since none of these have side affects, they are effectively no-ops
    int x = 5;
    int y = x * x;
    int z = y / x;
}

1

它们是没有实际作用的指令,就像 NOP 一样,但占用更多的字节。这对于将代码对齐到缓存行边界非常有用。例如,类似于 lea edi,[edi+0] 的指令,需要 7 个 NOP 才能填满相同数量的字节,但只需要 1 个周期。


0
语义NOP是一组机器语言指令,它们完全没有作用或几乎没有作用(大多数指令会改变条件码),其唯一目的是混淆程序实际执行的操作。

0

执行代码但没有实现任何有意义的功能。这些也被称为“不透明谓词”,最常由混淆器使用。


0
一个真正的“语义nop”是一条指令,除了花费一些时间和推进程序计数器之外没有任何效果。例如,在许多不影响标志位的寄存器移动机器上,有许多将寄存器移动到自身的指令。例如,在8088上,以下任何一种都将是语义NOP:
  mov al,al
  mov bl,bl
  mov cl,cl
  ...
  mov ax,ax
  mob bx,bx
  mov cx,cx
  ...
  xchg ax,ax
  xchg bx,bx
  xchg cx,cx
  ...
请注意,除了“xchg ax,ax”之外,以上所有指令都是双字节指令。因此,英特尔已经宣布当需要一个单字节NOP时应使用“xchg ax,ax”。实际上,如果汇编“mov ax,ax”并对其进行反汇编,则会反汇编为“NOP”。
请注意,在某些情况下,指令或指令序列可能具有潜在的副作用,但仍然比通常的“nop”更可取。例如,在6502上,如果需要7个周期的延迟,并且堆栈指针有效但堆栈顶部值无关紧要,则使用PHP后跟PLP将使用仅两个字节的代码杀死七个周期。但是,如果堆栈顶部值不是一个备用的RAM字节,则该序列将失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接