鏡の中の鏡 — Assembler is written in Assembler.

Mac OS Mavericks に様々な開発ツールを組込みながら,ソフトウェアの導入がいまはなんと簡単になったことか,と年寄りじみた感慨に襲われる。インストーラをダブルクリックして起動し,あとは基本的に「OK」をクリックし続けさえすれば,導入は完了する。ベンダ製品はもちろん,いまやオープンソース・ソフトウェアでさえそうなっている。Windows やら,Mac やら,現代のコンシューマ向けパーソナルコンピュータ OS(オペレーティング・システム)で計算機(恐ろしく昭和な言葉であるが)に馴れそめた人は,最初からこれが当たり前のことである。

しかし,大型汎用機(メインフレーム)ないし UNIX ワークステーションで計算機人生をはじめた者にとっては,ソースコード(人間が書いた命令の記述群)からバイナリ(コンピュータ上で実行可能なプログラム形式)を生成するところからソフトウェアとの付き合いがはじまるのが通例であった。ここではコンパイラ(翻訳器)とリンカ(編集器)が必須であった。

動かす計算機向けにすでに出来上がった実行バイナリをコピーして完了,というのが時間の節約になる。導入のために調べものや事前作業をしなければならないなんて,愚の骨頂だともいえる。昔の計算機はあるソフトウェアひとつ入れ込むのに,前提ソフトウェアの調整・導入手順の確認など七面倒な事前準備をしなければならなかった。「これ」を使いたいのになんで「あれ」も「それ」もやらさせられるんじゃ? 時間の無駄,ホントくだらない。

それは間違いのない真理なのだが,ソフトウェアを一から作り出すことを叩き込まれると,計算機の鏡の中の鏡の国が見えて来て,不思議な思いに駆られるようになる。「アセンブラはアセンブラで書かれています」— このジョークのような響きをもつ逆説の真理がわかるようになる。

アセンブラなんて古典ギリシア語みたいな言語での例はやめよう。かつて FreeBSD(UNIX ライクな高機能のオープンソース OS)で Java を利用しようとして,Sun Microsystems 社(いまは Oracle 社に吸収されてしまった)の JDK: Java Development Kit を導入しなければならないとき,このアーカイブをダウンロードして,Java コンパイラやらクラスライブラリやら JavaVM(ヴァーチャルマシン)やらを,ユーザ自らが生成しなければならなかった。

自分の計算機で動く Java を得るため,Java パッケージを解凍し,所定のディレクトリ下で make を投入する。javac not found のエラーメッセージが出ていきなり躓く。つまり — javac(Java ソースコードを読んで,Java 実行形式クラスを生成する Java コンパイラ)がありません。これからまさに javac その他もろもろを得たいがためにこの作業をやっているのに,javac がないのは当たり前やんけ。これ,要するに,Java を入れるために Java が必要だということなのである。

20140128-asm-screen.png

こういう目に遇うと,計算機という鏡の中の鏡の世界に迷い込んだ不思議な気分に襲われるのである。じゃ,その,必要とされる Java を入れようとすると,また javac がありませんと罵られることになりはしないか? 実際は,すでに実行形式が整った機能的に劣る旧バージョンを別にコピーして動くようにしておいて,この旧バージョンを使って自分の計算機に最適化された新しいバージョンを「作る」のである。

そう,こうして,システム構築の中核を荷なうソフトウェアは,親が子を生むことでレゾン・デートルが受け継がれて行くという人間的真実を秘めているのである。ソフトウェアのなかには,この一連の「創造」行為を意図してか,プログラムの生成に make world と入れさせるものがある(FreeBSD OS そのもののコンパイルに他ならぬ)。

大型汎用機は現在でも初期導入において,最低限の機能だけの旧バージョン OS を組込んでから,そのアセンブラを用いて新 OS のモジュールをアセンブルすることで,目的とする OS を構築する。思い出す……

一台時価五十億円の最新鋭大型計算機が顧客電子計算機室に搬入される。オープンリール磁気テープをデッキにセットする。これには一世代旧いバージョンの OS が格納されている。テープの先頭には己自身を計算機のメモリに読み込むプログラムが書き込まれていて,最初の小さいコードを実行すると芋づる式にプログラムが読み込まれ,実行されて,旧バージョンの OS が起動する。

次に,別の磁気テープ装置にマウントした新 OS 製品テープから,旧 OS の力を使って,新 OS 本体を磁気ディスクに格納する。続いて,あらかじめ新 OS 用に用意した,入出力装置情報その他の,アセンブラ言語で書いた定義文・数千枚のカード(その多くは先輩方が書いて,いやパンチして,プロジェクトで引き継がれて来たもの。落っことして散らかしてしまったら並べ直すのがたいへんだ)をカードリーダにセットし,システムコンソールからリーダを起動して,それらを読み込ませる。カタカタカタ... と機関銃のような轟音が轟く。旧 OS がカードに記録されたコードをアセンブルし,新 OS のモジュールとリンケージ(結合)し,顧客独自の稼働可能な新 OS を生成する。アセンブラのエラーが出る度に SE は寿命を縮めることになる。JOB NORMALLY ENDED — よっしゃ。

最後に,旧 OS をシャットダウンし,IPL ロード・デバイス・アドレスを新 OS が格納されたディスクに変更して,システムを起動する。新 OS が厳かに起動する。この一連の作業をシステムゼネレーションと称するのだが,私はこれを王位継承作業と呼んでいた。もちろんいまはオープンリール磁気テープ装置やカードリーダ装置なんて使わないようになったが,デバイスが変わっただけで導入の考え方は変わらない。

ある電子メールソフトウェアの説明書には「バイナリ生成で問題に遭遇したら xxx@yyy.zzz.com まで電子メールにてお問い合わせください」に類したことが平気で書かれていた。メールを使いたいから入れとんのに,メールソフトウェアのコンパイルで困ったらメールせよとはどういうこっちゃ。

Java を得るために Java を入れる。OS を入れるために旧い OS を入れる。メールソフトを入れようとしてうまくいかないので作者にメールする。昔の計算機使いはこういう逆説的堂々巡りに馴れていた。

このように,ソフトウェアを自分でコンパイル(あるいはアセンブル)・リンクして構築すると,鏡の中の鏡を覗いたときのような,じつに不可思議な循環性の感覚に幻惑させられるものである。JDK モジュールのコンパイルは一晩かかった。どれだけ多くの英知と労力を Sun Microsystems 社がこれに投入したかが痛いほどわかったものである。