再訂正・NOP命令の誕生
以前に「最初の NOP 命令は PDP-1 に搭載された」という記事を読み、PDP-1 の元となった TX-0 にはすでに搭載されている、という記事を書きました。
すると、それ以前の IBM 704 には既にあった、という指摘を頂きました。
再調査して IBM 701 で搭載されているが、おそらく考案したのは先に開発が始まった IBM 702 、という訂正記事を書きました。
さて、恥ずかしながら再訂正。
訂正記事を書いた際に、IBM 701 の前に作られている SSEC という機械式計算機(と、その時には思っていましたが違ってました)が気になっていましたが、その時には資料が見当たりませんでした。
その後、ふと気づいて別の方向から調査したら資料を見つけ、調査すると NOP が存在しているではありませんか。今回書いた一連の記事(マーク1とSSEC)は、この調査の派生物に過ぎません。
今回はまず、調査から明らかになった SSEC の NOP 命令について考察します。
その後、SSEC の話題の締めくくりです。
目次
IBM - SSEC(別記事)
高速化のために(別記事)
SSEC のプログラム方法(別記事)
SSECの周辺装置(別記事)
ハーバード・マーク1
SSEC とハーバード・マーク1は、IBM が連続して作成した「自動計算機」です。
一般的に、構造も非常に似ている、とされています。
調査したら全然違いましたが、思想的に似ているのはある程度事実。
そこで、SSEC に NOP があるのであれば、マーク1には無いか調査する必要がありました。
実は、マーク1に NOP が無いことは、以前に資料を見つけて確認済みでした。
でも、今回構造や動作詳細など、綿密に調べ直しました。
タイガー計算機は知っているから「あれを電気で回している」程度に考えていたら、かなり違っていて、大規模にする工夫がありました。
(知りたい人は詳細書いてあるから読んでね)
さて、マーク1には NOP はありませんが、「何もしない」命令はあります。
マーク1の命令は、 8bit で表現されるデータを、3つで命令を与える「三つ組」構造です。
送信元と送信先と、修飾語、の3つ。
現代の CPU のように、3つ目は「命令」ではありません。
マーク1には明示的な命令は無く、データの転送経路を記述するだけです。
歯車計算機なので、転送すれば、転送先と足されます。
「修飾語」によって符号を逆にすれば引かれます。
転送経路に乗算器があれば乗算になりますし、プリンタがあれば印字されます。
転送こそが命令のすべてであり、明示された命令語は不要な構造です。
但し、内部的な状態を変化させるだけ、ということはありますから、転送とは無関係に修飾語を使うこともあります。
では、転送も修飾語も、何も使わなければどうなるか。
これは、「何もしない」という動作になります。
マーク1の操作マニュアルには、様々なプログラムの例が載っていますが、意味的な区切りごとに「空白の行」を入れることで、理解を助けるようになっています。
空白行についての言及は特にないのですが、言及がないことが「何もしなかった」ことを物語ります。
ただ、空白行であっても他の転送と同じ処理時間はかかったようです。0.3秒と、結構長いです。
そのため、操作マニュアルの最期の方に載っている「実用例」では、空白行が一切入らなくなります。
意味が理解できるようになったら、もう速度を低下させる意味区切りは入れない方がよい、ということのようです。
先に書いたように、マーク1には「命令」は存在せず、データの流れとその際の修飾語があるだけです。
そのため、実は「すべての命令に」特に名前が与えられていません。
名前が存在しているのは、データの送受信先として存在している、様々な演算回路です。
対数 (LOG) を求める回路には、Log In Out という名前が与えられていたため、これを LIO と呼びます。
じゃぁ、LIO という命令があるのかと言えばそうではなく、存在するのは「LIO に対する送受信」だけです。
全ての送受信も修飾も存在しない時、動作する回路は一切なく、これに対する名前はありません。
これがおそらく、NOP が存在していなかった理由でしょう。
SSEC の NOP
対してSSEC です。
SSEC には、明示された NOP があります。
SSEC の命令は「10進数2桁」で表現され、アセンブラに相当するものは存在しないため、ニーモニック(NOP のような短縮語)はありません。
しかし、特許書面の中では、No Operation を意味する場面や、信号線の名前など、いたるところに No Op の記述がみられます。
つまり「No operation」を、「No Op」とする表記は、すでに存在することになります。
マーク1では「何もしない」なら名前は必要ではありませんでしたが、SSEC では名前が付けられたのです。
では、この間に何があったのでしょう?
「命令」の誕生
マーク1では、プログラムとはデータの流れを示すことであり、命令ではありませんでした。
それに対し、SSEC では、入力2つを処理して出力に送る、というのが基本です。
ここで重要なのが「処理」内容の明示で、これを命令によって示しています。
実は、命令とは「データをどの回路に送るか」を示しているにすぎません。
乗算を行いたい場合、マーク1では「乗算器に1つ目のデータを送り、2つ目のデータを送り、結果を取り出す」と3段階で処理していました。
これを SSEC では「入力2つと結果保存先、処理は乗算」のように、まとめて示しただけです。
マーク1がマイクロ命令で指示を出していたのを、SSEC はマクロ命令になった、と考えてもよいかもしれません。
同時処理
SSEC は、2つの命令を同時に読み込みます。
紙テープは遅いため、2つの機器を同時動作させて高速化しているのです。
ここで問題が起きます。
全てのプログラムが、偶数の命令数で処理が完結するわけではありません。
もし、奇数の命令数になってしまった場合、2つの命令を同時に読み込む形式では問題が起こります。
話は簡単で、「何の影響もない」命令をどこかに挟み込み、偶数に揃えればよいだけです。
このために、何の影響もない命令が必要となります。
マーク1では、データの流れを記述するだけでしたから、何もしたくない時は「何も指定しない」、つまり空行でした。
SSEC では、命令は2桁の 10進数で示します。BCD なので 8bit です。
ここを 00 にしたときが No Op となっています。
つまりは、穴が開いていない、空行と同じような意味合いです。
ちなみに、命令解釈前にデータ部分が解釈され、準備されます。
この際、使用バス部分に何も示さない( 0 を書いた)場合は、そのデータ部分は無視され何もしない、と明示されています。
データ部分を書いて準備を行わせておきながら、命令に No Op を与えたらどうなるか…
これはわかりませんが、おそらく何もしないでしょう。
データ準備に時間がかかる場合、無駄に速度を低下させることになります。