
2026/09/13 21:30
なぜ x86 の未定義命令が「ud2」と呼ばれるのか。なぜ「2」なのか。
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
インテルは、ソフトウェア開発における長年にわたる不安定さを解消するため、信頼性の高いアーキテクチャ定義外のメソッドとして
ud2 命令を導入しました。以前、x86 アーキテクチャには公認の未定義命令が存在しなかったため、開発者は到達不可能なコードを示すために 0F FF (ud0) や 0F B9 (ud1) などのバイトシーケンスに依存していました。しかし、インテルは後に 0F FF の動作を変更し、例外を発生させる代わりにランダムな操作を実行するようになりました。この変化はヒラムの法則(未文書化された挙動が実装の詳細が無警告で変更される際に壊れる)の例証です。また、古いシーケンスは命令の実行が例外によって中断される前に一部だけデコードされていたため、メモリのページ境界でアクセス違反を引き起こすことができましたが、パラメータ付きでない(2 バイトの命令であり、パラメータを持たない)ud2 は使用されないデコードされたレジスタをなくすことでこれらの問題を完全に回避します。ベテランの開発者であるレイモンドは「The Old New Thing」において、ud2 の導入は開発者が危険な工作回法を放棄し、予見可能な非対応命令例外によってアプリケーションが失敗するのではなく、偶発的なコードの実行やメモリエラーによるクラッシュを防ぐ一貫性のある堅牢なソリューションを採用することを迫ると述べています。本文
x86 アーキテクチャの ud2
命令:なぜ「無効なオペコード」例外に特化したか
ud2コンパイラが生成するコードや、意図せず API データを誤って操作してクラッシュを引き起こすソフトウェアを検討する際、
という命令に出会うことがあります。この命令とはどのようなものでしょうか。ud2
ud2
の役割と目的
ud2- 未定義な命令: x86 アーキテクチャ上で正式に未定義であり、必ず**「無効なオペコード」例外**を引き起こします。
- 到達不可能なコードのマーカー: コンパイラは未使用のコード領域に
を挿入し、「ここには決して到達しない」とマークするために使用します。ud2- もし何らかの原因でその領域に制御が飛ぶ場合、ランダムな命令実行(ダンプや不測の挙動)ではなく、意図的にクラッシュさせます。
- 例:
でマークされた関数が誤ってリターンした際、コンパイラは直後に[[noreturn]]
を挿入します。これによりプログラムが次の関数へ制御を渡すのではなく、即座にクラッシュします。ud2
「ud2」という名前の由来と歴史的背景
初期の状況:未定義命令の欠如
- 当初、x86 アーキテクチャにはアーキテクチャ上で明確に未定義の命令は存在しませんでした。
- そのため、「無効なオペコード」例外を確実に引き起こすバイトシーケンスを探す動きがありました。
2 つの候補と争い
: このシーケンスを実行すると「無効なオペコード」例外が発生することが発見されました。0F FF- デコーダ側では 2 つのパラメータ(レジスタ宛先・ソース)を持つ命令として解釈されましたが、実際には使用されず、例外発生前の処理はありませんでした。
: こちらも同様の特性を持つことが発見されました。0F B9- 派閥の形成: 「0F FF」信奉者と「0F B9」信奉者が形成されましたが、互いの手法はどちらも機能しており争う必要はありませんでした。
ヒュラムの法則による問題発覚
- インテルが次世代プロセッサを開発する過程で、
が無効なオペコード例外を引き起こさなくなる可能性や、ランダムに動作したり新しい命令として扱われたりするリスクが発見されました。0F FF- これにより、依存していたプログラムが動作停止する事例が発生しました。
- ヒュラムの法則: 「十分な数のユーザーが存在すれば、すべての観測可能な振る舞いに対して、何らかの人が依存している」。
- 同じく
についても同様の問題が発覚しました。0F B9
公式な解決策:ud2
の誕生
ud2- 信頼できる方法で「無効なオペコード」例外を誘発したいという要望が明確になったため、インテルはこれらを正式に承認しました。
という名前の命令を永続的に無効として定義し、サポートするようになりました。ud2
命名の理由
後付けでの命名ルールに基づいています:
版 →0F FFud0
版 →0F B9ud1- 残りの未定義オペコード →
ud2
ud2
の技術的な利点
ud2- パラメータ不要:
はパラメータを持たない2 バイトの命令です。ud2- したがって、ランダムなソースアドレスや宛先アドレスをデコードして使用する必要がありません。
- 一貫性の保証:
- デコード領域が非存在ページにまたがる場合、
やud0
のようにアクセス違反(Segmentation Fault)が発生するリスクがあります。ud1
は動作が一貫しており、アーキテクチャ上**「無効なオペコード」例外が発生することが保証**されています。ud2
- デコード領域が非存在ページにまたがる場合、
- 古くからの不具合の回避:
- 一部の古いプロセッサでは、
をデコードした時点でチェックせず直ちに例外を起こす仕様があり、ページの境界などで挙動が不安定(例外とアクセス違反が混在)なことがありました。0F FF
はこのような不具合に悩まされることなく安全です。ud2
- 一部の古いプロセッサでは、
著者紹介
- レイモンド氏: Windows の進化に 30 年以上関わってきた経験を持つ技術者です。
- 活動拠点: 2003 年にウェブサイト『The Old New Thing(旧なるもの)』を開始し、現在は書籍『The Old New Thing』(アディソン・ウェズレイ 2007 年)でも知られています。
- SNS: Windows Dev Docs のツイッターアカウントなどで活躍中。