Whirlwindのアセンブラ
目次
アセンブラ用の表記
1952年4月、アセンブル作業をコンピューター自身によって行わさせることができないか、という議論が始まります。
最初の書類では、ここまでに作られた「ハンドアセンブル用の」アセンブラリストを分析し、記述方法などを論考しています。
最終的にどのようにアセンブラが作られたのかはわかりませんが、52年10月に書かれたプログラムは、コンピューターで処理することが前提のような書かれ方をしています。アセンブラの開発に成功したのでしょう。
当初は、扱いやすくするために全命令を2文字で、というように考えられたようです。
どうも、この時に p 擬似命令も変更を受けたようです。1文字しかないし、空白が入ったり入らなかったりでは扱いにくいので、「ri」という正式な命令に昇格します。
そう、別ページで書いた謎の命令、ri は p の代わりをする命令だったのです。データを置くのが役割なので、命令バイナリは 00000 。
ri の由来は…想像ですが、 Register Immediate(値を格納)とかかな?
しかし、アセンブラの都合で 32個しか作れない WWI の命令を使ってしまうのももったいない話です。
自動アセンブラ、というものが作れるかどうかもわからず模索していた期間を過ぎ、実際にアセンブラが動き始めてみると、わざわざ WWI の命令を使う必要がないように思えてきたようです。
そこで、アセンブラに「p 擬似命令」が、正式に擬似命令として取り入れられました。この時には、命令はスペースで区切るのを前提に、3文字命令も作られていました(シフト命令は当初2文字だったが、後に3文字に拡張された)。
命令は「2文字」という決まりはすでに無くなっており、p が1文字であることを今更問題にする必要もなかったのです。
アセンブラが作られた 1952 年は、周辺機器の接続方法も整理され、ごちゃごちゃしていた WWI の周辺が整理されていった時期です。
アセンブル作業が機械で行えるようになると、当然表記も、アセンブラの求める方法に統一されていきます。
書き変わる可能性のある命令は、アドレス部分に ---- という表記が使われるようになりました。以前のような ( ) 表記ではありません。
もっとも、明示的にこれを使わず、 0 と書く人も多かったようですが。
データ埋め込みは先に書いたように、一時的に ri が、最終的には p が使われるようになりました。ただし、以前のように空白を入れない表記方法は見られなくなりました。
小数点表記も、新たな表記法が取り入れられています。先頭を + - の記号から始めた場合は、10進数の固定小数点を使えたようです。
ただ、この表記法はあまり見かけないもので、固定小数点の整数部分のビット幅がどうなっているのか、などの詳細はわかりません。
ハック!
アセンブラあるところにハックあり…
というわけでもありませんが、自己書き換えも当たり前で、メモリは小さかったこの時代、現代の目から見るととんでもない「ハック」がいたるところにみられます。
もっとも、「ハック」という言葉が出てきたのはもう少し後の時代。場所は WWI と同じく MIT だったので、名前が付けられていないだけで、このころから文化は始まっていたのかもしれません。
まず、先ほど、初期のアセンブラプログラム例のところで書いた「ハック」についてです。
もっと「端的に」表現された例が、サブルーチン集の8ページ目にあるので、そちらを示します。
18行目で、19行目の内容を読み込んでいます。そして、19行目は「flexowriter で印刷」を意味する、 qp 命令です。つまり、ここでは「命令は、自分自身を印字する」ということをやっています。
ここでも、1ページ目の例と同じく、左端に手書きで縦線が加えられています。つまり、ハックである目印です。
qp 命令は、アドレスを必要としない特殊な命令です。アドレスが必要な命令では、たとえ「144 行目」を意味する 144r を指定したとしても、実際のアドレスがどこになるかはわかりません。しかし、qp命令では「144」を指定すれば、アドレス部分に「確実に」 144 が入ります。この、qp が特殊な命令である、ということが、ハックの条件の1つめ。
ところで、実はここは「128」を指定すべき部分です。
どうやらパラメータはビットマップで、一部のビットは「無視」されたようです。そのため、144 を指定すると、128 とまったく同じ動作をする模様。とはいえ、144 を指定するのは「保証外」の行為。この、144 指定で 128 の文字セットを使えた、というのがハックの条件の2つめ。
qp 命令は、アドレス部分に指定された数値とともに、アキュムレータの値も使用します。この時、アキュムレータ全体を対象にするのではなく、下位 6bit のみが使われます。
WWI の命令セットは 16bit で構成されますが、命令は上位 5bit に入り、アドレス部分が下位 11bit に入ります。もし、命令をアキュムレータに入れて下位 6bit を取り出すとしたら、それはアドレス部分が使用される、ということになります。
この、qp はアキュムレータの下位 6bit しか使用しない、というのが、ハックの条件の3つめ。
最後に、非常に頻繁に使われる「キャリッジリターン」つまりは改行の文字コードは、パラメータ 128 を指定した時の、文字コード 144 でした。これは、先に書いた「144 は 128 と同じ動作」という、144 とたまたま同じ数値です。これがハックの条件の4つめ。
この4つの条件を組み合わせれば、qp 144 命令に自分自身を印刷させると、パラメータ 128 で文字コード 144 を印字することになり、キャリッジリターンが可能である、ということになります。
すべてのデータをメモリに準備しないとならない WWI では、本来「144」という数値をメモリ上のどこかに準備しておかねばなりません。ところが、このハックによりそのデータは不要となり、1word 短縮することができます。
しかし、ハックはハックです。注意しないと大変なことになります。もし、144 という指定を見た人が「この指定はおかしい。128 に直さねば」なんて考えたら…
左側に記された縦線は、「ここはハックであるから書き変えないように」と注意を促すためのものだったのです。
また、同様の手法で、136 を指定すると「スペース」を印字できたようです。こちらは、サブルーチン集12ページ目で使われています。
ついでにもう一つ。懐かしいテクニックを見つけたので記しておきます。
Z80 ではよく見たテクニックを、はるかご先祖様の WWI でも使っていたようです。
…興味のある人は、サブルーチン集の PDF を取得後、16ページから始まるプログラムをご覧ください。ソースコードは興味ある人以外が見てもつまらないので、ここでは解説のみを行います。
詳細なことはさておき、このプログラムはメモリに準備された文字列を印字するプログラムです。
印字されるデータの長さは定まっておらず、最後は 0 で終わっています。
さて、問題はその「文字列」の先頭アドレスをサブルーチンに渡す方法。
アキュムレータに入れて渡す、とかではないのです。「サブルーチン呼び出しを行う命令の、次のアドレスに、文字列の先頭アドレスを用意せよ」となっています。
ということは、サブルーチンから戻ったら「データの中」で暴走してしまうのでは…?
ここがよくできたところで、「戻り先」には、データの位置を考慮した次のアドレスが使われます。
ta 命令で「サブルーチン呼び出し実行時のプログラムカウンタ」を取り出せるので、それを戻り先アドレスとしてだけでなく、サブルーチンに引き渡す値としても使っているのですね。
これ、サブルーチン自体を「拡張された命令」だと考えた場合、2word で1命令を形成する「不定長ワード命令」を実現していることになります。固定長が当然の時代に、なんて現代的!
…もっとも、これは現代から見ていえる後知恵で、当時はそんな風に考えていなかったでしょうけどね。
以上、アセンブラの文法の説明と、よく使われるハックについて解説しました。
興味がある人は、アセンブラで書かれた各種ルーチンを解読してみましょう。
自己書き換えを多用した、スパゲッティでわくわくする世界が待っています。
参考文献 | |||
WHIRLWIND SUBROUTINE SPECIFICATION | 1952 | MIT | |
Automatic Assembly of Programs | John W. Carr III | 1952 | MIT |
Group 51 Subroutine Library | W. Lone | 1952 | MIT |