2010-02-05 65 views

回答

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; 
} 
0

语义NOP是具有在所有或几乎没有影响没有影响机器语言指令的集合(大部分的操作变化条件代码),其唯一目的是混淆程序实际正在做的事情。

0

代码执行但没有任何意义。这些也被称为“不透明的谓词”,最常用的是obfuscators

1

它们是不起作用的指令,如NOP,但占用更多的字节。用于获取与高速缓存行边界对齐的代码。一个像lea edi [edi + 0]这样的指令就是一个例子,需要7个NOP来填充相同数量的字节,但只需要1个周期而不是7个。

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斧,斧”是两个字节指令。因此,英特尔声明,当需要一个字节的NOP时,应该使用“xchg ax,ax”。确实,如果组装“mov ax,ax”并拆卸它,它将会拆解为“NOP”。

请注意,在某些情况下,指令或指令序列可能具有潜在的副作用,但仍然比通常的“nop”更令人满意。例如,在6502上,如果需要7个周期的延迟并且堆栈指针有效但堆栈顶部的值不相关,那么PHP和PLP将仅使用两个字节的代码来杀死7个周期。如果栈顶值不是RAM的备用字节,则序列将失败。