Share to: share facebook share twitter share wa share telegram print page

NOP

NOP(ノップ)あるいは NOOP(ノープ)とは no operation (何もしない)を意味する。プログラミングやネットワーク通信と言ったコンピュータ関連の技術用語として使用される。

機械語

機械語において NOP は多くの命令セットで用意されている命令である。プロセッサはこの命令を読みとると文字通り「何もせず」[注釈 1]プログラムカウンタインクリメントのみを行う 。それ自身では何の意味も持たない命令ではあるが、

  • 外部機器や他のプログラムとの同期のタイミングを取るための時間稼ぎ
  • ジャンプ命令のジャンプ先の指標
  • 後で命令を追加する予定の場所にダミーとして置く
    • たとえば遅延スロットにとりあえず置く、あるいは置ける命令がない時に置く
    • VLIWなどのようなアーキテクチャでは、より積極的にNOPが必要である
  • NOPスレッドによる命令ポインタの制御
  • ワンチップマイコンPROMでは、0x00か0xffのどちらか「上書き可能なほう」で潰すと NOP になるようにしておくと、再利用に便利

などの用途で使用される。

規則的に命令を決めた結果、何の意味も持たない命令(同一レジスタでの移動、次の番地へのジャンプ)が出来たのでそれをNOPとすることもあれば、専用の命令として用意されることもある。

歴史

1950年代のEDSACにおいて既に、NOP に相当する命令は設計者らには認識されていた(コード 'X' であるが、何もしないという命令は命令でないと考えたためか命令一覧では省かれていることがあり、文字コード一覧に命令も添えてある表のほうで確認できる(EDSACでは文字コードオペコードを一致させていた))。

TMS9900は規則的なパターンのためにできた無意味となる場合をNOPとした例である。

x86では、命令の並びからは XCHG AX, AX に当たる部分がNOPであり、8086に始まる16ビット時代には内部的にはそのまま動作していたものもあったと思われる。しかし80386以降の後にIA-32と呼ばれるような高性能プロセッサになってくると、「AXレジスタを操作する」という意味には並列化の邪魔になるなど弊害が現れるため、AXの参照を伴わない真にNOPであるという解釈が明確化された。さらにAMD64では、32ビットと64ビットの調整のために作られた「暗黙のゼロ拡張」という仕様により、64ビットレジスタRAXに対し、32ビット操作で XCHG EAX, EAX に相当する動作をした場合は、64ビットのうち上位32ビットがリセットされなければならないため、特別扱いであるNOPだと再定義された。

幾つかの例

幾つかのCPUについて機械語コードを示す。英語版には更に多くの例がある。

CPU名 NOPの機械語コード(16進数)
Z80 00H[1]
6800 $01[2]
6502 $EA[3]
IA-64 IA-32
90H                        
66 90H                     
0F 1F 00H                  
0F 1F 40 00H               
0F 1F 44 00 00H            
66 0F 1F 44 00 00H         
0F 1F 80 00 00 00 00H      
0F 1F 84 00 00 00 00 00H   
66 0F 1F 84 00 00 00 00 00H

[4]

V850 0x0000[5]
AVR 0x0000[6]
MIPS 0x0000 0000[7]

高水準言語

NOPという表現はしばしば、何も起こさないような関数やコードを指して使われることがある (この場合冗長コードと呼ばれることもある)。コンパイラ最適化では、このようなコードを検出し、削除する(オブジェクトサイズの削減といった直接的な効果があり、コードキャッシュが無駄に使われるのを回避するという副次的効果もある)。

プログラミング言語の構文によっては、何もないことが許されないため、NOPのようなものが必要な場合がある。次に例を示す。

Python

Pythonにおける、何の効果も持たない pass文 (pass statement) は、NOPに似ている。pass statementは、Pythonの特徴的なインデントを使用する構文の都合上、記述したいことが何もなくても、何か記述が必要な場合に使われる。たとえばクラスの定義には何かブロック本体が必要であるので、とにかくクラスを存在させたいだけ、といった場合にその本体として pass と書く。 たとえば、次のようになる。

class Foo(Bar): # クラスを継承する
  pass          # (再)定義すべき内容は何もない

通信プロトコル

いくつかの通信プロトコルでは、NOP や NOOP というコマンドを備えている。このコマンドを送信した場合、具体的に何かが起こるわけではないがサーバからの応答は返ってくる。プロトコルによっては特別なメッセージや情報を返すものもある。このコマンドは主にサーバとの接続が切断されていないか、あるいはトラフィックの増大等の理由でサーバからの応答が遅れていないかを調べる目的で使用される。

NOP もしくは NOOP コマンドを備えている主な通信プロトコルとして以下のものがある。

  • FTP - NOOP コマンド
  • SMTP - NOOP コマンド
  • POP3 - NOOP コマンド
  • TCP - TCP オプションでオプション番号 1 が No-Operation(何もしない)を意味する
  • Telnet - NOP コマンド

脚注・出典

  1. ^ ただし何もしないという処理を「実行」するのには、そのクロック数の時間が掛かる。コメントが実行時間に影響を与えないのとは異なる。
  1. ^ Z80 Instruction Set”. p. 180. 2021年1月15日閲覧。
  2. ^ THE ESSENCE OF THE 6800 MICROPROCESSOR”. p. 204. 2021年1月15日閲覧。
  3. ^ 6502 Opcodes”. 2021年1月15日閲覧。
  4. ^ Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, M-U”. intel. p. Vol.2B 4-169 Table 4-12. Recommended Multi-Byte Sequence of NOP Instruction. 2021年1月15日閲覧。
  5. ^ ユーザーズ・マニュアル V850E/MS1TM, V850E/MS2TM 32ビット・シングルチップ・マイクロコンピュータ アーキテクチャ編”. renesas.com. p. 95. 2021年1月15日閲覧。
  6. ^ Atmel AVR Instruction Set Manual”. atmel. p. 131. 2021年1月15日閲覧。
  7. ^ MIPS Programmer’s Reference Manual”. p. 24. 2021年1月15日閲覧。
Kembali kehalaman sebelumnya