
2026/05/17 3:16
『Halt and Catch Fire』
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
「Halt and Catch Fire」(以下 HCF)という用語は、標準的なリセット操作では回復できない状態に CPU を停止させるマシンコードを指します。この項書の語源の一端は、特定の無効なオペコードを検出すると磁気コアメモリへのアクセスを継続的に実行し、結果として IBM System/360 が過熱して文字通り火を引くようになったことにあります。1977 年に BYTE マガジンに掲載されたジェリー・ウーラー(Gerry Wheeler)の『未文書化された M6800 インストラクション』では、Motorola 6800 のオペコード $9D および $DD がチップをハードウェアカウンタのように振る舞わせることを指摘しており、メモリを順次読みながらリセットまでカウントし続ける効果を表すこととしてウーラーは「Halt and Catch Fire」という助覚語(mnemonic)を考案しました。他のエンジニアも独自の愛称を使用しており、例えばデイヴィッド・J・アガンス(David J. Agans)はオペコード DD を「Drop Dead」インストラクションと呼んでいました。1985 年の IEEE アーティクルでは、内部で HACOF という愛称を持つ不正な MC6800 オペコードについても言及されており、これは顧客が RAM のスキャンを許可して修理コストを支払わせないようにする機能として利用されていました。技術的には、これらのオペコードはプログラムカウンタを無限に増やし続けながらメモリードアウトを発行し、初期システムでは不安定なビデオハードウェアにより視覚的な「ノイズ(snow)」として現れる場合があります。現代の分析では、カウントパターンの開始前に短い遅延が観察されることが示されています。Motorola を主要な例としましたが、類似の振る舞いは 6502 の不正なオペコードにも存在し、後にファズジングによって発見された Pentium(F00F)および最新の x86 プロセッサでも確認されています。「Halt and Catch Fire」はかつて、「EPI」、「DC」、「CRN」などの他のプログラミング界のユーモアに基づく 3 文字の助覚語と並んで集められていました。現在、研究者や愛好家はこれらの文書化されていないオペコードをスキャン、実験室的測定、歴史的研究を通じて引き続き調査しており、これは高レベルの抽象化が存在しても、生なマシンコードが潜在的なシリコン上の問題を露呈させ得、それが機能特性へと転換する可能性があるか、あるいはセキュリティ脆弱性を引き起こす可能性もあることを示唆しています。
本文
私は AM チャンネルの番組『Halt and Catch Fire(停止して火をつける)』をご覧になったことがなく、長らくその題名のみを知っていて内容を知らなかったものでした。しかし、その作品には何故かプログラミング界のジョークに通じる雰囲気がありました――やや大げさであり、少し不気味で、不思議なほど正確なのです。すると、 Ternyata その番組はまさに 1980 年代から 1990 年代のコンピュータ業界を描いたものでしたが、「Halt and Catch Fire」というフレーズ自体は番組よりもはるかに古く、エンジニアリング界隈で広まっていたユーモアとして起源がありました。
「Halting and Catching Fire」の意味
コンピュータ分野における「Halt and Catch Fire」(通称:HCF)は、一般化して CPU が一切の有用な動作を停止させられ、再起動(電源投入によるリセットなど)を行わないと復旧できないようなマシンコードの状態を表すために用いられるようになりました。文字通りの意味で言えば、マシンを「停止」させるのです。「火をつける」という部分は冗談ですが、思っているほど大げさなものではありません。例えば IBM システム/360 を挙げましょう。ある無効な操作指令 opcode に遭遇すると、磁気コアメモリ内の特定のアドレスを絶えずアクセスしようとし、結果として非常に高温となり、実際に炎上したとのことです。
時が経つにつれ、HCF は未文書化または無効な opcode によってプロセッサがロックされる状態、意図的なテストモードで疑似的停止を引き起こすもの、そして実際のハードウェアバグなど、あらゆる種類の問題の総称としても使われるようになりました(例えば、初期の Pentium チップには特定の不合法指令を入力するとプロセッサが永久に止まってしまう「F00F バグ」という問題もありました。この後でさらに詳しく触れたいと思います)。
このフレーズは、3 文字の組立式助記語(例:ADD、CMP、JMP など)を使うという業界慣習をきっかけにして生まれました。その後、HCF を筆頭に、私自身が特に気に入っている以下のような他のジョークも様々なメディアを通じて広まりました:
- EPI: Execute Programmer Immediately(プログラマーを即座に実行せよ)
- DC: Divide and Conquer(分割統治で解決せよ)
- CRN: Convert to Roman Numerals(ローマ数字に変換せよ)
モトローラ 6800 の話
もともと「Halt and Catch Fire」は単なる冗談に過ぎましたが、やがて現実のものとなりました。
モトローラ 6800 プロセッサには 256 ビットの単一バイト opcode が存在しますが、その全てのビットパターンが文書化された指令に対応しているわけではありません。誤って別のパターンを指定すると、シリコンが「解釈する」通りの挙動を示します――時には何も起きないだけの場合もあれば、時として重大な影響を与えることもあります。
Gerry Wheeler 氏が『BYTE』誌に寄稿した Undocumented M6800 Instructions(未文書化された M6800 の指令) という記事は、1977 年 12 月号(Vol. 2 No. 12)、テクニカル・フォーラム欄の 46 ページから 47 ページに掲載されました。Wheeler 氏はモトローラの公式資料を基に、文書化された opcode は 197 つである一方、残りの 59 ビットパターンについては公式の説明が存在しないことを指摘します。これらのうちいくつかは NOP(何もしない指令)のように振る舞い、いくつかは条件コードレジスタを変化させますが、Wheeler 氏自身もその当時は「解読不能」と述べている部分もあります。特に危ないという 2 つのバイト($9D と $DD)については、彼が「Halt and Catch Fire」と命名したと明言しています。なお、「これらの助記語は当然ながら私が付けたものです」とも述べています。
実際ハードウェア上で起きていることは、この部分では通常のフェッチーデコードー実行エンジンとして振る舞うことができなくなるということです。プログラムカウンターは継続的に進み、アドレス線がメモリを Hardware カウンタのように順次走査して読み出し命令を発行し続けます。割り込みはこの自己破壊的なループを止めることはできません;抜け出すためにはリセットか電源サイクルが必要です。Wheeler 氏の元の文章こそが価値のあるため、要約ではなくそのまま引用します:
この指令を実行した際、その内容を確認するにはオシロスコープを用いるしかありません。ユーザー目線のところでは、マシンは停止し、再起動を試みるほとんどすべての試みを拒否します。アドレスバスのインジケータランプがある方々は、プロセッサがメモリの全領域を非常に高速に順次読み出し始めていることに気づくでしょう。つまり、アドレスバスが 16 ビットのカウンターに変化していることになります。しかしプロセッサは、自分が何を読んでいるかに一切注意を払いません;ただ読み続けるのです。
「火をつける」という部分については、「まあ、ほぼそうなっています」と付け加えています。IBM のシステムでは実際に炎上したケースがあったようですが、モトローラ 6800 においては同様の現象は見られなかったようです。
『BYTE』誌以外でも、同じ opcode ファミリーには他のニックネームが付けられました。David J. Agans 氏は Debugging(2002 年刊) で、DD を自身のチームが「Drop Dead(死に堕ちる)」指令と呼んでいたと回想しています。これは同様のバス・ウォーキングトリックですが別名であり、エンジニア達が意図的にこれを活用した理由として、「オシロスコープ上でアドレス線とクロック線が綺麗で、正方波を循環しているから」ですと説明されています。
多くのマシンは単に「フリーズする」と感じられるのみです。少なくとも一部の初期の 6800 マイコンでは、神経質なメモリマッピングビデオシステムにおいて、このパターンが可視的な「ノイズ(スノー)」として現れることもあり得ます。Ben Z 氏の『Sphere News』記事は深く掘り下げるのに適した素晴らしい穴であり(ビデオ RAM アービテーション、タイミング、CRT アーティファクトなどについて)、読む価値があります。
数年後、モトローラのエンジニアリングチームも同じ問題についてさらに論文を執筆しました。IEEE Design & Test (1985) に掲載された Daniels と Bruce 氏は、顧客が発見した MC6800 の無効 opcode について記述し、内部では「HACOF」とニックネームされていたものでプログラムカウンターが無限に増分してしまいリセットまで止まらないと説明します。また信じ難い事実についても触れています:製品エンジニアリング部門は起動時の RAM スキャンを迅速に行う方法が必要としていたのに、この挙動がすでにそのような機能を提供していることに気づき、除去する費用を支払う代わりにそのまま保留してしまったというのです。つまり Bob Ross の言葉で言えば、これは「幸せな偶然」だったと言えます。
さらに最近では、実際に MC6800 をハードウェア上で稼働させ、過去の雑誌やウィキペディアのスキャン画像に頼らず実測を行ってみました。Doc TB 氏のラボ記事には興味深い詳細が記載されています:opcode がフェッチされた後、アドレス線が有名な高速カウントパターンに入るまで数十ミリ秒程度の遅延があり、同様のアイデアの slower なバージョンやグルーミングなバリエーションを持つ他の未文書化 opcode も存在します。
モトローラ以外の話
モトローラだけがこの問題を抱えた近代的プロセッサではありません:ロックされる 6502 の無効 opcode、Pentium F00F バグ(その時代の皆さんにはお馴染みかもしれません)、一部のアーキテクチャでは永久に到達不可能な割り込み待ちをする指令ペア、そして現代の x86 フジング会話で巨大プロセッサ内部でもまだ見つかる無効状態などが挙げられます。
基本的には、フジングによってランダムまたは予期せぬデータを実際にプロセッサへ設定することで、脆弱性やバグを特定しようとする試みです。驚くべきことに、これは非常に効果的な戦略であり、プロセッサだけでなく、あらゆる種類のソフトウェアにも適用可能です。
「停止して……そして終了」
この歴史的研究は面白かったものです――実際には「火をつける」という部分に関しても、予想以上に見知らぬ深層があり、さらに多くの側面が明らかになりました。多くのソフトウェアがスタックを上昇するにつれ、我々は 10,000 フィート上空の視点からハードウェアを見失いやすくなります。結局のところ、それは単に間違える可能性があるように導線されたシリコンの集合体に過ぎません。
私が知っていることは、このフレーズは使って置けないほど良いものだということです――将来的なプロジェクト(あるいは企業)が「HCF」という略語を使用するのを期待してください。
参考文献と追加情報
暇つぶしのために、出典および更多信息へのリンクをいくつかお付けします:
- Gerry Wheeler, "Undocumented M6800 Instructions," BYTE誌 1977 年 12 月号
- David J. Agans, Debugging: The Nine Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems (AMA, 2002), p.77
- Ben Z, "Sphere News: Halt and Catch Fire!"
- RetroComputing StackExchange #15289
- Doc TB, "Investigating the HCF instruction on Motorola 6800"
- Wikipedia: Halt and Catch Fire (computing)