世界を動かす技術を、日本語で。

80386マイクロコードの逆アセンブル

概要

  • 80386マイクロコード 抽出と解析の過程を解説
  • 8086との比較 や技術的な困難点の紹介
  • マイクロコードの構造 や命令エントリ数の詳細
  • 未公開バグ や隠し機能の可能性について言及
  • リソース や学習方法、協力者への謝辞

80386マイクロコード抽出と解析の経緯

  • Ken Shirriffから 80386マイクロコードROMの高解像度画像 の提供
  • 8086のマイクロコード(10752ビット)に比べ、 80386は94720ビット の大容量
  • 特許資料や既知の情報がない ため、解析の難易度が非常に高い状況
  • Discord上でGloriousCowやSmartest Blobらと議論、 画像処理・ニューラルネットワーク・人力自動化 を駆使してバイナリ抽出に成功
  • バイナリから μ-op(マイクロオペレーション)配列とビットフィールド の構造を特定
    • 未使用μ-opブロックの存在やALU操作のサイクル数からフィールド分割を推測
    • 命令終端パターンの発見
  • Ken Shirriffの協力により ダイ上の配線や論理構造 も解析

80386マイクロコードの構造と特徴

  • デコーディングROMから215個のエントリポイント
    • 8086の60個と比較し大幅増加
    • 新命令追加、オペランド種別(レジスタ/メモリ)、CPUモード(リアル/プロテクト)、REPプリフィックスの有無で分岐
  • 各エントリポイントが複数命令やルーチンを共有
    • 命令デコーダが単なるオペコード以外も参照
  • 全命令がマイクロコードで実装
    • 8086や現代CPUと異なり、80386は常にμ-opを実行
  • 未使用または不明なルーチン
    • 0x849~0x856のルーチンはエントリポイントなし、PAGE_FAULT処理と類似
    • ICE(In-Circuit Emulator)ハードウェア対応のルーチンも存在

80386の高速化とアクセラレータ

  • 多くの命令がハードウェアアクセラレータ によって処理高速化
    • 乗算・除算回路、バレルシフタ、保護テストユニットとのインターフェース解析が重要
  • 8086ではマイクロコードで実装されていたアルゴリズムが 80386ではハードウェアで処理

バグ・隠し機能・未公開仕様

  • I/Oパーミッションビットマップのバグ の可能性
    • 4バイトI/Oアクセス時、先頭3バイトのみ許可ビットをチェック
    • 境界アクセスで不正にハードウェアレジスタへアクセス可能なケース
    • 非常に稀なバグであり、バージョン依存や解析誤認の可能性もあり
  • XBTS/IBTS命令の非サポート (デコーダ内のみ痕跡あり)
  • 現時点で 明確な隠し命令やイースターエッグは未確認

マイクロコード解析の学習方法・リソース

  • githubのx86 microcodeリポジトリ でダウンロード可能
    • parts.txtでファイル構成を把握
    • microcode_10.txtで分解済みマイクロコード本体を参照
  • 解析の進め方
    • μ-opのパターンやフィールド構造の理解
    • 命令デコーダや保護テストPLAとの関連付け

謝辞・参考情報

  • 協力者 :Daniel Balsom(gloriouscow)、Smartest Blob、nand2mario、Ken Shirriff
  • 公開日 :2026年5月23日
  • カテゴリ :computer、hardware
  • フィード :RSS 2.0対応

Hackerたちの意見

俺にとって、これがHacker Newsのピークだね。こういう投稿を理解するために大学で難しいコースを受けたことを嬉しく思ってる。2015年にHNがこの思考を刺激してくれたのも良かった。今は低レベルプログラミングの知識をあんまり活かしてないけど、毎回意識が豊かになる感じがする。それってすごくいい気分だよね。大学に行けない人には、nand2tetris.orgをおすすめするよ。

ゲートから自分のマイクロプロセッサを作るのは、マイクロコードの設計やプロセッサの仕組みを理解するための簡単な方法だよ。でも、RISCやTransputerみたいなシンプルな古い設計を勉強するのも悪くない。80386はその逆で、古い悪い設計と互換性を持たせようとしたせいで、余計に複雑になってる。チップ設計を学ぶのに大学に行く必要なんて全然ないよ。アラン・ケイのトークをいくつか見たり、Bitsaversのコンピュータ設計を見たりするのがいいスタートポイントだと思う。俺たちは、ゲートレベルの設計をチップ上のトランジスタにシミュレーションして変換する、FPGAよりも簡単な方法を作ったんだ(2026年に200ドル以下で)。これをMorphle Logicって呼んでる。最終的には、最大で最速で最も安いスパコンのウェハースケール統合を作るようになるよ。

nand2tetrisはマイクロコードをカバーしてる/使ってるか知ってる?

nand2tetrisを何回かやったけど、各抽象レベルでシンプルさを重視してるんだよね。それ自体が素晴らしい教訓で、インスピレーションにもなったけど、マイクロコードみたいなものは省略されちゃうんだ。大学(1990年代)では、CSの学位の一環としてEEのクラスを受けたんだけど、8086のようなCPUがどう作られるかを学んだんだ。nand2tetrisに似てるけど、各パートを課題にするわけじゃなかった。マイクロコードの仕組みもカバーしてて、内部プログラムカウンタが制御ワードのテーブルをステップして、ビットがCPUの各制御可能な部分を直接操作するんだ。先生が事前に作ったシミュレーターで実装する命令を各自もらったよ。(私はDEC、デクリメントを担当した。)ある意味、nand2tetrisの命令はマイクロコードみたいなもんだね。命令のビットがハードウェアを直接制御して、最初のビットで2つの命令タイプを選ぶから、命令ごとに1ステップのコードしかないんだ。マイクロコードの場合は、命令が任意の数のマイクロコードステップを持てるのとは違ってね。ベン・イーターの8ビットCPUをブレッドボードで作る動画シリーズでは、オペコード(命令の4ビット)とステップカウンタで制御ワードを決めるROMがあるんだ。ROMは、十分に複雑な論理ゲートでできることを代用してる。ハードウェア面での次のステップとして、電子機器に触れてトラブルシューティングする経験が得られるから好きなんだ。ただ、16バイトのRAMしかないのが残念で、nand2tetrisのような高レベルの抽象を構築するのは難しいんだよね。でも、その時点で(私は)もっと良い設計でやり直すか(PCBに載せる)、6502プロジェクトに進むべきだね。それでタイマー、CPU、ROM、RAM、I/O、UARTなどをまとめて考えて、すでにそれらが一緒になっているマイコンに進むのもありだね。論理ゲートからCPUがどう作られるかに興味がある人は、チャールズ・ペッツォルドの『Code』を読むといいよ(進行が遅いけど、最近更新された)。またはダニー・ヒリスの『Pattern on the Stone』もおすすめ(こっちは早い)。追記:『Code』(第2版)を確認したら、4ビットのサイクルカウンタとハードロジックゲートを使って、各サイクルで何をするかを決めてるんだ。でも、ロジックの一部にはダイオードの配列を使ってる。これってマイクロコードと考えられるのかな?[0] 別のCSクラスでは、もっと高度な(パイプライン)CPUを扱う授業もあったけど、自分で作れるって感じの低レベルではなかった。

これを解読するためのブラックボックス分析はめっちゃ難しいけど、同時にすごく楽しくてやりがいがある。素晴らしい仕事だね。

...彼らは80386のダイの高解像度画像を取得して、そこからマイクロコードを抽出するのが面白いだろうと言ってた。高解像度画像からマイクロコードを再構築するプロセスを誰か説明してくれない?すごく興味があるんだけど、そのプロセスはどうなってるの?出力は何かのVerilogみたいなもの?プロセスにはトランジスタを一つ一つ認識して回路をモデル化することが含まれてるの?こんなことが可能だなんて、すごく魅力的だよね…

マイクロコードはROMに入ってるよ。1と0で見た目が違う普通の構造なんだ。

これがNintendo 64のロックアウトメカニズムのチップをデレイヤリングしてる動画だよ。かなり詳しくて、いろんな方法を説明してる。https://youtu.be/HwEdqAb2l50?si=VFLed64PZvpCHfy1

画像を見てみて。[1] > 上の写真はマイクロコードROMの一部を示している。顕微鏡で見ると、マイクロコードROMの内容が見えて、各位置のトランジスタの有無に基づいてビットを読み取ることができる。 [1]: https://www.righto.com/2020/06/a-look-at-die-of-8086-process...

抽出プロセスにちょっと関わったから、ここで少し話せるよ。最初のステップは、マイクロコードアレイの行と列の交差点で、ビットのx,yの位置をマークすることなんだ。それから、それを0か1に分類しなきゃいけない。見た目で区別できて、1はトランジスタの存在とポリシリコンの隙間で表現されるんだ。インテルのマイクロコードの特性上、0がはるかに多いと仮定できたから、トランジスタがあれば1ってわけ。色のしきい値を使って自動的に作業を行うツールもあるけど、ここではあまりうまくいかなかった。モザイクがぼやけてたり、ほこりが入ってきて偽の1ビットができちゃったりしたからね。代わりに、抽出したビット領域を0と1に分類するために畳み込みニューラルネットワークを訓練したんだ。それを元のモザイクに50%の不透明度で白と黒の四角として重ねた。で、結果をエラーがないか確認するのに数日間、長くて退屈な時間を費やしたよ。最終的に生の2Dビット配列ができたんだけど、次のステップはそのビット配列からマイクロコードワードを抽出することだね。

数日前にreenigneのブログをチェックしたんだ。「うーん、2020年以降何も投稿されてないな。まあいいや。」彼のブログが33年前に遡るのを見るのは特に楽しいね。

ヒットカウンターのインクリメントが、投稿のインスピレーションだったのかもね。

マイクロプログラミングを基礎から説明している素晴らしい本があるよ: https://www.amazon.com/Computation-Structures-Optical-Electr... 無料のPDFが見つけやすいよ。

これをエミュレーターに入れたら、Linuxがブートするかな?

nand2marioがそれを使ってVerilog実装を作ったんだ。今はDOOMが動いてるけど、ちょっと面倒な保護モードの部分があって、フルオペレーティングシステム(DOS以外)は動かせないんだよね。バグはそのうち解決されると思うけど。

ちなみに、元のARMは全くマイクロコードを使ってなかったんだよね。

でも、彼らの純粋さは商業的な利益をもたらさなかった。

これはすごい逆アセンブルだね。実際のマイクロコードの実装を見ることで、これらの古いプロセッサが複雑な操作をどう処理していたのかがわかるようになる。

OpenFletcher[1]がそんな画像を取得できるか気になるな。 [1]: https://openflexure.org/projects/microscope/

あれ、絶対作るつもり!

関連: z386: オリジナルマイクロコードを基にしたオープンソース80386 https://news.ycombinator.com/item?id=48248014