
2026/05/23 21:11
80386 マイクロコードのディスアセムブリ結果
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Ken Shirriff、Daniel Balsom、Smartest Blob、nand2mario、およびGloriousCow を含む協力チームが、Intel 80386 プロセッサの完全なマイクロコードを成功裏に復号化し、x86 アーキテクチャ分析における画期的な成果をもたらしました。Shirriff によって提供された高分解能 ROM 写真(94,720 ビットで、8086 の 10,752 ビットよりも多い)に対して、高度な画像処理、神経ネットワーク、および自動化を用いて、チームはパターンを特定することでμ-オプスを再構築し、読み取り順序を決定し、特定のフィールドを復号化するようマイクロコードをアセンブラしました。重要な発見の一つとして、80386 は各命令について正確に 1 つのマイクロオペレーションを実行し、「不要なコード」は存在しない点が挙げられます(これに対し、先行モデルまたは現代のプロセッサでは 1 つの命令に対して複数の内部ステップを使用したり、異なるデコードロジックを持ったりすることがあります)。CPU の ROM には 80386 で 215 つの独自のエントリポイントが設定されており(これは 8086 の 60 と比較)、複雑なタスクの処理、乗算や除法等のハードウェア加速アルゴリズムを含んでいます。特に注目すべきは、マイクロコードに初期バージョン(具体的には XBTS/IBTS)に存在する命令が含まれておらず、旧型モデルの破棄された命令との間に不一致が見られることです。また、分析ではアドレス空間のエッジにおける 4 バイトアクセスの最終バイトに対して IO 権限処理が誤って成功する可能性があるセキュリティ上の欠陥も発見されました。さらに、マイクロコードには ICE ハードウェアとの対話を扱うルーチンが含まれています。現在、すべての詳細フィールド、サブルーチン、および共有コードは x86 マイクロコードリポジトリ(具体的には
fields.txt)を介して公開されており、コンピュータサイエンス教育およびハードウェア理解の進展に貢献しています。発見内容は「computer」と「hardware」のカテゴリに分類されました。本文
80386 マイクロコード解析プロジェクト:高解像度画像からデシミュレーションへ
プロジェクトの背景と挑戦
マイクロコード解析の世界には大きな進化がありました。
-
初期の状態
- ケン・シュリッフ(Ken Shirriff)氏が公開された 8086 デシミュレータの成功を受け、80386 のマイクロコード ROM に関する高解像度画像を共有してくださいました。
- しかし当時は解析を開始しませんでした。
-
着手しない理由
- データの圧倒的規模
- 8086 マイクロコード:約 10,752 ビット
- 80386 マイクロコード:約 94,720 ビット(8086 の約 9 倍)
- このサイズ差により、ビットラクトなどのツールを使ったコード変換は極めて手作業(tedious)であり、非現実的な負荷となりました。
- 不明な方針
- 8086 では特許文書や一部のコードスニペットによる枠組みが示されており、探索が可能でした。
- 一方、80386 は完全なブラックボックスであり、巨大な二進データの中で解析対象を見つける手がかりが不足していました。
- データの圧倒的規模
画像からマイクロコードへ:AI との協働
数日後、コミュニティでの対話を通じてプロジェクトは動き始めました。
-
議論の流れ
- Discord などでお話しした際、「高解像度画像からのマイクロコード抽出」について触れました。
- 私の見解:「画像変換は完了しているが、二進データへの変換および人間可読なマイクロコードへの解釈は難しすぎる」。
- これは一種の挑戦として受け取られ、短期間で成果が上がりました。
-
技術的アプローチ
- 画像処理技術とニューラルネットワークを組み合わせる。
- 人間の支援による自動化も併用して検出・クロスチェックを行う。
- 結果として、画像から抽出した二進データスライムの正解が導き出されました。
マイクロコード構造の解明
デシミュレーション自体は依然として複雑な課題でしたが、段階的に解明が進みました。
-
パターン認識と再配置
- 複数のパターンを発見し、以下のような規則性を把握しました。
- μ-オペランドの軸: μ-オペランドそのものと、そのビット構成を分離して理解する。
- 順序性: チップには未使用の μ-オペランドブロックが存在しており、これが読み取り順序の手がかりとなった。
- フィールド分割: μ-オペランド内のビットをどのように区切ったか(ソース/宛先レジスタなど)を特定した。
- 複数のパターンを発見し、以下のような規則性を把握しました。
-
8086 の教訓との比較
- 2 クロックサイクルの ALU 演算:
- 80386 は ALU 演算を 2 サイクルで可能にする設計でした。
- マイクロコードもこれを反映し、第 1 サイクルに両オペランドを読み込み、第 2 サイクルで出力を転送する処理になっていた。
- フィールドの役割: 8086 の知見から、「ソースレジスタ」と「宛先レジスタ」の 2 つのフィールドがあることを推測し、これが正しいと判明した。
- 2 クロックサイクルの ALU 演算:
-
ルールの発見
- 規則的なパターンの検出: 命令終了を示す特定のパターンを発見(この推測は正解)。
- 全体像の可視化: ケン氏による回路線や論理ゲートの追跡画も貢献。
- 分岐構造の理解:
- 一部の要素を理解すると、類似構造を持つ他のマイクロコード断片の意味も把握できるようになった。
- デコーディングブロック(複数の小さい PLAs で構成)と保護検査用 PLAの解読も進展。
-
命令とマイクロコードの関連付け完了
- やがて 386 命令とマイクロコード断片を正確にマッピングでき、状況は大幅に明朗化しました。
ハードウェアアクセラレーションによる高速化
80386 は 8086 よりも遥かに高速です(1 クロックあたりの処理速度)。
-
実装の違い
- 多数のトランジスタ投入により、多くのアルゴリズムが本質的に**「ハードウェアアクセラレーション」**に置き換えられました。
- したがって、80386 のマイクロコードのうち相当な割合は、これらのアクセラレータを設定する目的だけで使用されています。
-
解析の中心となった領域
- 特に以下のアクセラレータとのインターフェース理解が重要でした。
- 乗算・除算ハードウェア
- バレルシフタ
- 保護検査ユニット
- 特に以下のアクセラレータとのインターフェース理解が重要でした。
マイクロコードエントリーポイントの詳細
マイクロコードには、驚くほど多くの異なる命令が実装されています。
-
エントリーポイントの数
- 80386: $2^{15}$ (32,768) のエントリーポイント。
- 8086: $2^6$ (64) と比較して大幅増加。
-
増加の理由 状況に応じて処理ルーチンが異なるためです:
- 新しい命令の追加
- オペランドの種類(レジスタかメモリーか)
- モード(リアルモードかプロテクトモードか)
プレフィックスの有無REP
-
ファイル情報
- 詳細は
ファイル(サブールーチンおよび共有コードを含む)に記載。fields.txt - 注意: 上位レベルのルーチンサイズ自体は参考にならず、多くのルーチンは短期間で共有ルーチンにジャンプするためです。
- 注意: エントリーポイントごとの対応オペコード数も単独では意味がなく、命令デコーダーは「他の情報」も使い分けて決定しているためです。
- 詳細は
例外と「ジャンクコード」の存在について
すべての処理がマイクロコードによって行われているか確認しました。
-
未実装命令の有無
- 結果:一つもありません!
- 80386 は常に μ-オペランドを実行しており、すべての命令に対してマイクロコードが存在します(現代の CPU とは異なります)。
-
「ジャンクコード」の分析
〜0x849
のルーチン(デシミュレータでは「unused?」とマーク)には関連エントリーポイントが一つもありません。0x856- 動作類似性:
ルーチン(PAGE_FAULT
-0x8e9
)と非常に似ています。0x8f5- エラーコードにページングユニットからの最終エラーコードを設定。
- 中断コード
を発生させる。0x0e
- 差異: このルーチンは CR2 レジスタではなく、フォルトした線形アドレス値をセットします。
-
設計思想
- 例外なく、すべてのマイクロコードは CPU の文書化された動作を実装するように設計されています(ICE ハードウェア用などは未文書化の動作)。
隠れた機能とセキュリティ上の発見
マイクロコードには文書化されていない機能やイースターエッグが存在する可能性について考えました。
-
検証環境の限界
- 実機の 386 を使った検証環境を持たないため、確定的な答えを持っていません。
-
重大なセキュリティバグの発見(推測)
- 特定の保護モード OS で利用されていた IO パーミッションビットマップ処理に恐るべきバグを発見しました。
- 問題の詳細:
- 4 バイト幅のポートアクセス時、マイクロコードは権限チェックを行う。
- しかし、チェック対象は最初の 3 アドレスのみ。
- 結果、プロセスが許可された領域の境界付近でアクセスが行われた場合、最終バイトだけが誤って成功する。
- これにより、OS が意図しないユーザー可視なハードウェアレジスタへのアクセスが可能となる。
-
このバグの特徴
- 極めてニッチな問題であり、デシミュレーションなしでは見過ごされやすかった。
- この欠陥が 40 年以上も気づかれずに残っていることは稀。特定の CPU バージョンでのみ発生したか、私の理解が不完全で正当な挙動だった可能性もある。
- 裏付け: このマイクロコードは初期バージョンではなく、
やXBTS
命令の兆候が見つからないため。IBTS
さらに深く学ぶには
-
学習資料
- デシミュレーションファイルの詳細説明から始めてください。
-
ダウンロード先
- GitHub の x86 マイクロコードリポジトリ。
- 推奨順序:
(他のファイルの説明)parts.txt- 直ちにデシミュレーションへ移行したい場合は
microcode_10.txt
クレジット
このプロジェクトの成功に貢献した方々への謝辞:
- Daniel Balsom (GloriousCow)
- Smartest Blob
- nand2mario
- Ken Shirriff