NOP
電腦科學中,NOP或NOOP(No Operation或No Operation Performed的縮寫,意為無操作)是匯編語言的一個指令,一系列編程陳述式,或網絡傳輸協定中的表示不做任何有效操作的命令。
NOP機器指令
有的電腦指令集包含一條指令,其主要目的是不改變任何程式可訪問的暫存器,處理器狀態標誌或主記憶體,而且可能需要特定的時鐘周期來執行。在其它指令集中,NOP是用執行一條具有運算元,具有相同效果的指令來模擬的(例如SPARC處理器推薦使用sethi 0, %g0
模擬NOP)。
NOP指令通常用於控制時序的目的,強制主記憶體對齊,防止管線化災難,佔據分支指令延遲),或是作為預留位置以供程式的改善(或替代被移除的指令)。在某些情況中,NOP指令會產生副作用;例如在摩托羅拉 68000處理器中,NOP操作碼會產生管線化同步[1]。
下表顯示了部分CPU架構上NOP指令的特徵:
CPU架構 | 助憶碼 | 字長 | 操作碼 | 備註 |
---|---|---|---|---|
Intelx86系列CPU | NOP
|
1; i686中為1–9 | 0x90; 0x0f 0x1f [2] | x86 CPU上的NOP指令實質上是XCHG EAX, EAX(操作碼同為0x90)--無任何作用的指令。 |
Intel 8051 / MCS-51系列 | NOP
|
1 | 0x00 | |
MIPS | NOP
|
4 | 0x00000000 | |
MOS科技 65xx | NOP
|
1 | 0xea | 65C02處理器發佈時,之前多數的無效指令都被定義成了具有不同字長和需時的NOP指令。 |
PowerPC | NOP
|
4 | 0x60000000 (ori r0,r0,0 的擴充操作碼)
|
NOP代碼
NOP有時可以描述函數或一系列編程陳述式的作用,若部分沒有作用(也可以稱為冗餘代碼)。常見的編譯器最佳化的作用就包括檢測和去除這樣的代碼。
下面是一個起NOP作用的C語言陳述式的例子(評判標準在於陳述式是否影響程式輸出,而非編譯器是否為陳述式產生代碼):
i+1;
(該陳述式執行了一個加法,但結果被丟棄。)
C語言中最簡單的NOP塊被稱為空陳述式;其只包括一個分號。(標準沒有要求編譯器在這個例子中生成NOP指令;通常這個陳述式會直接為編譯器所忽略。)
;
雖然空陳述式自身沒有用處,但在某些情況下可以啟動預留位置的作用,例如在迴圈中:
while (ReadChar() != '\n')
;
以上代碼一直呼叫ReadChar
函數,直到函數返回一個\n(NL,新行)字元。
Python中的pass
陳述式不會產生作用,可以作為NOP使用。它的主要目的是保證語法正確,由於Python的縮排敏感語法。
NOP協定命令
許多協定,比如telnet,包含NOP指令,該指令允許客戶端可以在不會引起其它操作的情況下向伺服器請求回應。NOP指令可以用於檢測連接是否斷開,或伺服器是否可以響應操作。下列協定中包含NOOP指令(不完全列表):
注意:與其它協定不同,IMAP4的NOP命令允許客戶端響應伺服器傳送由其它客戶端反應的操作資訊。
雖然大多數telnet和FTP伺服器用OK或+OK回應NOOP指令,有的程式設計師在對客戶端的回應中加入了特別的內容。例如MINIX的ftpd
守護行程會以以下訊息回應NOOP:[3]
200 NOOP to you too!
破解
NOP通常在破解軟件時有特殊用途,例如檢查序列號,特定硬件或軟件需求,加密狗等的軟件。這是通過更改函數和/或子程式以跳過安全檢查,直接返回期望的檢測值實現的。由於大多數安全檢查子程式中的指令會被廢棄,它們會被NOP所代替。
安全問題
NOP操作碼可以被用於組成一個NOP slide,允許在指令指標值未定義時執行代碼,例如緩衝區溢位導致棧上的函數返回地址被更改。
參見
參考文獻
- ^ Motorola 68000 Programmer's Reference Manual (PDF). [2010-09-18]. (原始內容存檔 (PDF)於2015-09-24).
- ^ Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual. [2007-07-13]. (原始內容存檔於2007-07-02).
- ^ ftpd.c. [2009-01-22]. (原始內容存檔於2009-01-16).