あけまして、おめでとうございます。 天変地異の大地震や、飛行機などの事故があり、素直に喜べない年明けになってしまいましたが、今回は、PDP−11のアドレッシング・モードと分岐命令について記します。
PDP-11が、良いコンピュータだったと言われる一つの理由は、番地指定様式が、よく考えた設計になっていたということがあると思われます。PDP-11の番地指定方法は8種類あり、八つの内部レジスタと組合せで、64パターンの指定方法がありますが、いきなり、64パターンを理解するのは大変です。木村泉先生はとりあえず、3つの番地指定方式を覚えてくださいと書いています。
主に、オペランドのところに、出てきますが、初めての機械語で出てきた37以外に、27、0nの方式を使えるようにしましょう。
27ですが、イミーディエイト(immediate)命令ともいい、機械語の直後にデータがあるよという意味になります。
1000 062737
1002 0010
1004 1010
1000 番地に ADD 命令に続いて、 2737を書き込み、 1002番地に 0010、1004番地に 1010と置いて、1000番地の命令を実行すると、 1010番地の値と0010(十進の 8)を加えて、結果を 1010番地に書き込みます。
0nですが、 nは0から7までの八つのレジスタが指定できます。例えば、値をコピーする命令(MOV命令)である 01に続いて、012701という機械語は、次にある16ビットのデータをレジスタの1(r0)に書き込みます。この命令は、レジスタの初期化によく使われます。
次に、分岐命令(Branch命令)について述べます。通常、プログラムカウンタは、2づつ増加して、次に実行すべき命令の番地を指します。コレだけたと、同じ命令を100回繰り返す場合、同じ命令を100個並べることになります。途中で、実行の流れを変える命令があると、このようなループは、短く描けるようになります。このような目的で次に実行すべき番地を変更するのに、使われる命令が、分岐命令です。PDPー11の分岐命令は、今までの命令と異なったフォーマットを持っています。オペレータが8ビット、オフセット8ビットの構造を持っています。オフセット部分で、プログラムカウンターの値をどのように変化させるかを指定しています。
例えば、
1010 000410
という命令があったとすると、
0004は、BR命令と言って無条件で、分岐(飛ぶ)命令です。飛び先は 1032番地になります。番地の計算は、次の通りです。1010番地の機械語命令を取り込んだ直後は、プログラムカウンタ(PC)は1012番地を指しています。これにオフセット10に2をかけた20を加えて、新しい番地1032がPC に入り、1032番地の命令が実行されます。注意すべきは、分岐命令の起点は、命令の番地ではなく、次に実行するはずの番地であることです。オフセットを2倍する理由は、PDP-11の命令は偶数番地にしかないので、そのまま使うと奇数のオフセットは無駄になってしまいます。オフセットを2倍すれば、奇数のオフセットも命令のある番地を指すことになるので、無駄が出ないということでしょう。8ビットのオフセットで、±256番地の前後の飛び先を指定することができます。8進数で8ビットは3桁で表すと正の整数は、0から200まで、負の整数は300から377まで、3桁目の400から777までは、オペレータの種類によって、3桁目が変わってしまします。アッセンブラでプログラムする場合は、アッセンブラが、計算してくれるので、問題ないのですが、機械語を手で書く(ハンドアッセンブル)場合は、計算が厄介です。
そこで木村先生は、8ビットのオフセットのうち最上位の2ビットを諦めて、6ビットのXX(8進2桁でオフセットを表し、前方へ飛ぶときは2進11の8進法では、3をオペレータに加えて、2の補数でXXを表現する工夫をしています。こうすると、飛べる範囲は、64の2倍の128番地に狭くなってしまいますが、紙と鉛筆で機械語を組み立てる時に、計算が、うんと楽になります。
分岐(BRANCH)命令には、必ず分岐するBR命令と、フラグの状態で分岐する命令があります。参照するフラグはZ(演算の結果が0の時立つ)、N(結果が負の時に立つ)、V(オーバフローの時に立つ)、C(くり上がりがある時にたつ)どの条件で分岐(飛ぶ)かは、表の通りです。
C(キャリーは)V(オーバーフロー)どちらも、桁あふれを表しますが、Cの方は、符号を考えない場合に16ビットの収まらない結果出た場合で、Vは、符号がついている16ビットの演算で、桁あふれが出た場合にセットされます。符号付きの整数で、16ビットで表せる最大の値は、77777(7が五つ、十進で、32,767これに1を加えると、10000(0が五つで、2の補数で解釈すると十進変換で、-32768になります。 このような場合、Vフラグがセット(立ちます)されます。Cは単に16ビットに演算結果が収まらなくなった時にセットされます。
ちなみに、オーバーフローがなぜVなのかというと、Oにすると、0と紛らわしいので、避けたんじゃないかと思われます。
ちなみに、符号ありの分岐命令は、大小の比較を、2の補数(負の数あり)で比較するのに対して、符号なしの分岐命令は、単に2進数の大小で比較するとの違いで、主に、前者は、数学的な比較、後者は、番地の大小比較に使われます。
最後まで、読まれた方はお疲れ様でした。次は、(ターミナルテレタイプの入出力の巻につづく)