計算機科學中,NOPNOOPNo OperationNo 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指令,有的程序員在對客戶端的回應中加入了特別的內容。例如MINIXftpd守護進程會以以下消息回應NOOP:[3]

200 NOOP to you too!

破解

NOP通常在破解軟件時有特殊用途,例如檢查序列號,特定硬件或軟件需求,加密狗等的軟件。這是通過更改函數和/或子程序以跳過安全檢查,直接返回期望的檢測值實現的。由於大多數安全檢查子程序中的指令會被廢棄,它們會被NOP所代替。

安全問題

NOP操作碼可以被用於組成一個NOP slide,允許在指令指針值未定義時執行代碼,例如緩存溢出導致棧上的函數返回地址被更改。

參見

參考文獻

  1. ^ Motorola 68000 Programmer's Reference Manual (PDF). [2010-09-18]. (原始內容存檔 (PDF)於2015-09-24). 
  2. ^ Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual. [2007-07-13]. (原始內容存檔於2007-07-02). 
  3. ^ ftpd.c. [2009-01-22]. (原始內容存檔於2009-01-16).