2010-02-05 41 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的備用字節,則序列將失敗。