| マシンコード |
|---|
| 一般的な概念 |
| 説明書 |

不正なオペコードは、未実装操作[ 1 ] 、意図しないオペコード[ 2 ]、または文書化されていない命令とも呼ばれ、CPUへの命令で、CPU の設計者や製造元によって公開された公式ドキュメントには記載されていないが、効果を持つものである。不正なオペコードは、MOS Technology 6502、Intel 8086、Zilog Z80など、1970 年代に設計された古い CPU では一般的だった。現代のプロセッサとは異なり、これらの古いプロセッサはトランジスタの割り当てが非常に限られており、そのため設計者はスペースを節約するために、無効なオペコードを検出してエラー ハンドラへのトラップを生成する回路を省略することがよくあった。これらのオペコードの多くは、CPU 内のトランジスタの配線の副作用として動作し、通常は結合されることが意図されていない CPU の機能を組み合わせてしまう。古いプロセッサと最新のプロセッサには、製造元によって意図的にプロセッサに組み込まれている命令もありますが、それらは公式仕様には記載されていません。
偶発的に発生する不正命令のほとんどは、役に立たない、あるいは非常に望ましくない影響(デバイスのクラッシュなど)をもたらしますが、中には特定の状況下で有用な機能を持つものもあります。 1970年代と1980年代のコンピュータゲームでは、このような命令が、特定の時間的にクリティカルなセクションを高速化するために悪用されることがありました。また、コピープロテクトの実装とクラッキングの間で続いていた争いにも、不正命令はよく利用されました。この分野では、不正命令は「隠蔽によるセキュリティ」の一形態であり、その秘密性は長くは続きませんでした。
不正命令の使用に伴う危険性は、メーカーがそれらの存在と機能を保証していないため、CPU内部の変更やCPUの新バージョンリリースによってそれらの命令が消失したり動作が変化したりする可能性があり、それらを使用するプログラムが新バージョンとの互換性を失う可能性があることです。例えば、古いApple IIのゲームの多くは、新しいApple IIcでは正常に動作しませんでした。これは、Apple IIcが不正オペコードを廃止した新しいCPUリビジョン( 65C02 )を使用していたためです。
80186、80286、68000などの後継 CPU には、広く知られ、使用されている不正なオペコードはありません。理想的には、CPU は、命令ストリームで未知のオペコードを見つけると、特定の例外や障害状態をトリガーするなど、明確に定義された方法で動作します。プログラムが以前に独自の例外/障害ハンドラを確立していない限り、オペレーティングシステムの例外または障害ハンドラは通常、障害の原因となったアプリケーションを終了します。その場合には、そのハンドラが制御を受け取ります。不正な命令を処理するもう 1 つのあまり一般的ではない方法は、時間と空間を占有する以外は何もしないように定義することです (CPU の公式のNOP命令に相当)。この方法は、 TMS9900プロセッサや65C02プロセッサなどで使用されています。あるいは、未知の命令をソフトウェアでエミュレートすることも可能である(例:LOADALL)、あるいは「新しい」擬似命令を実装することもできる。一部のBIOS 、メモリマネージャ、オペレーティングシステムは、これを利用している。例えば、V86タスクが基盤システムと通信できるようにするため、Windows NTVDMで利用されているBOP(「BIOS Operation」の略)がそうだ。[ 3 ]
インテルはそのような命令が存在しないことを保証するものの、ファジングなどの手法を用いた調査により、2018年という遅い時期にもx86プロセッサに膨大な数の未文書化命令が存在することが明らかになった。 [ 4 ]これらの命令の一部はプロセッサメーカー間で共有されており、公式仕様には記載されていないにもかかわらず、インテルとAMDは両社ともその命令とその目的を認識していることがわかる。その他の命令はメーカーや特定の製品ラインに固有のものである。x86の未文書化命令の大部分の目的は不明である。
現在、これらの命令の詳細は、主に古いシステムの正確なエミュレーションにおいて重要です。