C も B も無かった1969年 ── Unix は、機械語のすぐ上の言葉で書かれた
第6回の終わりで「逃げ道(中間コード)の下には、結局アセンブリと機械がある」と言いました。いよいよそこへ降ります。舞台は1969年のベル研。C も B(第5・6回)も、まだ十分には無い時代です。Ken Thompson は、遊休状態の小さなコンピュータ PDP-7 を見つけ、そのアセンブリ言語だけで、カーネルもシェルもエディタも書き上げました。高級言語という梯子を1本も使わずに ── これが Unix の、剥き出しの出発点です。
直接のきっかけは、大きな失敗でした。ベル研は MIT・GE と組んで壮大なOS Multics を作っていましたが、進みが遅く、1960年代末に撤退します(この Multics 自体は番外編・系譜の最上流で扱います)。手持ちぶさたになった Thompson は、Multics 上で作った宇宙旅行ゲーム Space Travel を、遊んでいた PDP-7 へ移植しようとし ── そのついでにファイルシステムを作り、プロセスを作り、気づけばOSになっていました。当初はベル研の公式な予算も付いていません。
PDP-7 の上で、Thompson(のち Ritchie も)はアセンブリ言語で次々に書きました ── カーネル、コマンドインタプリタ(シェル)、エディタ、アセンブラ自身、そして小さなユーティリティ群。ここで階層ファイルシステム、プロセス、デバイスファイルといった、いまも Unix/Linux の背骨である概念が生まれています。すべて、機械語のすぐ上の言葉で。
「アセンブリで書いた」の意味を、はっきりさせます。機械が実際に実行するのは 機械語 ── ただの数値の列(オペコードとアドレス)で、人間にはまず読めません。アセンブリ言語は、その数値に人が読める名前を付けただけのもの。命令に lac(ロード)・add(加算)のようなニーモニックを、番地に start:・n: のようなラベルを与える。両者はほぼ1対1に対応します。
そして、その名前を数値へ機械的に置き換えるプログラムが アセンブラです。下の図で、アセンブリが機械語へ翻訳される様子を1行ずつ見てください。翻訳後の数字だけを見ると、意味がまるで読めなくなる ── それが「機械が見ている世界」です。
C・B・BCPL・中間コードは、どれも「もっと楽な言葉で書いて、翻訳してもらう」梯子でした。アセンブリは、その梯子のいちばん下の段。機械の命令そのものに名前を貼っただけで、もう「別のもっと楽な言語」に逃げる余地はほとんどありません。ここから下は、素の機械 ── 数値としての機械語と、それを動かす物理だけです。
梯子は尽きても、鶏と卵は消えません。アセンブリを機械語にするには、アセンブラが要る。ではその最初のアセンブラは、何が組んだのか? しかもPDP-7 Unix には、アセンブラ自身がアセンブリで書かれて含まれていました。やがて Unix は自分のアセンブラで自分を組み直せる(self-supporting)ようになります ── アセンブリ層での、最小の自己ホスティングです。でも「いちばん最初の1個」は、その輪の中では作れない(第0回)。下の図で、その輪と、輪の外に残る問いを見てください。
PDP-7 Unix はやがて1970年に PDP-11 へ移り(やはりアセンブリ)、そして第5回で見たとおり、1972〜73年に C で書き直されます。ここでシリーズの環がひとつ閉じます ── 第5回「C は B から育った」と、この第7回「最初の Unix はアセンブリ」が、1973年の C 化という同じ結び目でつながる。私たちは今、その結び目のさらに下、いちばん最初のアセンブラの出どころへ向かっています。
(1) 図1の命令・8進コードは、アセンブリと機械語の対応の感じを伝えるための簡略化した例で、実在の PDP-7 の命令表を厳密に再現したものではありません(PDP-7 は18ビット語の小さな機械で、lac/dac/tad/jmp などのニーモニックは実在します)。(2) 「アセンブリ→機械語はほぼ1対1」は基本的に正しいですが、疑似命令・マクロ・複数語命令など例外もあります。
(3) Unix 誕生の経緯(Multics 撤退→Space Travel→ファイルシステム→OS)は語り継がれる有名な流れですが、細部は資料により差があります。(4) 「梯子がここで尽きる」は言い回しで、実際にはアセンブリより下にも、マイクロコードなど機械内部の層が続くことがあります(第10回で扱います)。(5) 初期はアセンブル自体を別マシンで行っていました ── その話がまさに第8回です。
1969年、Multics から撤退したベル研で、Thompson は遊休の PDP-7 に Space Travel を移植するついでにファイルシステムを作り、それが最初の Unix になった(名は Kernighan の UNICS)。C も B もまだ無く、カーネル・シェル・エディタ・アセンブラ・ユーティリティは、すべてPDP-7 のアセンブリ言語で書かれた。ここで階層ファイルシステムやプロセスといった Unix の背骨が生まれている。
アセンブリは、機械語(人に読めない数値)に人が読める名前(ニーモニック・ラベル)を貼っただけの、いちばん薄い皮。それを数値へ置き換えるのがアセンブラだ。C・B・BCPL・中間コードという「楽をする梯子」は、ここで最下段まで降り切った。だが鶏と卵は残る ── 最初のアセンブラは、何が組んだのか? PDP-7 Unix はアセンブラ自身を含み、アセンブリ層で自己ホスティングするが、最初の1個は輪の外にある。次回、その答え ── 別のマシンでアセンブルし、紙テープで運んだクロス方式へ。
印刷 / PDF 化:⌘+P(Windows は Ctrl+P)。画面では図1の「▶ アセンブルする」でアセンブリ→機械語の翻訳を、図2で PDP-7 Unix の最下層の自己ホスティングを追えます。「答えを見る」で解答が開きます。