C=A+Cこれに対して、アセンブラ言語ではレジスターを通して加算の処理が必要である。先ほど と同じことをするためには、
LD GR1,A ;アドレスAの内容を汎用レジスターGR1にコピー ADDA GR1,B ;GR1 <- GR1+ B ST GR1,C ;GR1の内容をアドレスCにコピーと書かなくてはならない。加算に限らず、あらゆる演算や処理にレジスターが関わってくる。
コンピューターというものは、メモリーにあるデータをレジスターにコピーして、CPUで 処理して、メモリーにコピーすることを繰り返しているにすぎない。高級言語を用いたプ ログラムでは、それが見えないように隠しているのである。そうすることによりプログラ マーの負担を減らしており、その分コンパイラーが頑張っている。アセンブラー言語の場 合、CPUの動作そのものを記述する必要があるため、メモリーの処理とかレジスターの動 作をその都度書く必要があり、プログラマーは大変である。大変な分、高級言語よりも高 速でメモリーが少なくて動作するプログラムを作ることが可能となる。
if(a<b){ c=b-a; }else{ c=a-b; }と書けばよい。ここで、if文の括弧の中の演算を制御式と言う。高級言語は、人間 が使っている言葉とほとんど同じで、プログラムが簡単に書ける。
しかし、アセンブラーでは、こんなに簡単ではない。そもそも、if文がないため、 それに変わるテクニックを使わなくてはならない。機械語命令を組み合わせて、高級言語 のif文と同じことをするのである。かなりプログラムは面倒であるが、その分コン ピューターのハードウェアー(特にCPU)は簡単になり、高速の動作が可能になる。
アセンブラー言語でifの様な制御文を実現するためには、次のようにする。
教科書の[例題2]では、次のようにしている。
ADDA GR1,B ;GR1=GR1+B 結果の状態がフラグレジスターにセット JOV L1 ;OF(オーバーフローフラグ)が1ならラベル1へ JUMP L2 ;無条件でラベルL2へ
教科書の例では偶数か奇数か判断するために、最下位ビットをマスクを用いて検査してい る。ここで用いるマスクパターンは、最下位ビットを調べれば良いので、 0000000000000001となっている。 のばあい、それは なので
データの調べたいビットは、マスクにより指定している。このように、調べたいビットを しているデータマスクという。要するに、お面(マスク)で顔の一部を隠すように、興味の ないビットを隠しているのである。
先の例でも分かるが、ANDを使ったマスク処理の場合、マスクは興味の対象のビット を1、どうでも良いビットを0にする。そうすると、興味のないビットは全てゼロとなり、 重要なビットは変更されない。先の場合、ある特定の1ビットの状態が分かれば良かった ので、マスク処理後、直ぐにフラグレジスタZFを見た。もう少し複雑な場合は、こ れではだめである。特定のビットパターンを調べたい場合について考える。例えば、
このようなビットパターンを調べる場合、2つの手順が必要であろう。
まずは、ANDを使う方法である。調べたいデータはGR0に格納されているとする。
;これ以前は省略 AND GR0,A ;マスク CPL GR0,B ;ビットパターンの比較 ;このあたりも省略 A DC #0F0F ;マスク B DC #0A0C ;ビットパターンの定義同じ様なことが、ブール代数の双対の原理2により、ORを使ってもできる。そのほかにも、いろい ろな方法が考えられる。
この場合、プログラムのデータ領域にアクセスする事を考える。ラベルAやBは 簡単で、ラベル名を示せば良い。ラベル名はアドレスを示すからである。問題は、結果を 格納する領域である。このアドレスは、3つ続いて確保されているが、先頭だけANS とラベル名がある。残りの2つの表し方である。これらのアドレスは、ANS+1と ANS+2である。ANSのアドレスにオフセットの値を加算するのである。
プログラムで使うメモリーのアドレスは、ANS+オフセットで、オフセットは、 0,1,2とすれば良い。論理和の結果をANS+0、論理積の結果をANS+1、論理 和の結果をANS+2に格納する。プログラムでは、オフセットの0,1,2をGR2 に入れておき、
ST GR1,ANS,GR2と書く。演算の結果(GR1)の値が、ANSにオフセット値(GR2)を加えたアド レスに格納される。
ここで、使っているGR2のように、1つずつ値が増加するものをカウンターと呼ぶこ とがある。これを使うためには、
同じことを2進数で行う。これがコンピューターによる乗算である。先ほどと 同じ計算( )を行う。これを2進数で表現すると、
今回の問題の用に分数の場合でも、
(1) |
LAD GR1,0 ;演算の結果を入れる。初期化 LD GR2,A ;Aの内容をGR2へ SRA GR2,1 ;右へ1ビットシフト ADDA GR1,GR2 ;1ビットシフトした結果を加算 LD GR2,A ;Aの内容をGR2へ SRA GR2,2 ;右へ2ビットシフト ADDA GR1,GR2 ;2ビットシフトした結果を加算 ST GR1,KOTAE ;演算結果をKOTAEに
教科書のように
(2) |
LOOP LAD GR2,1,GR2 ;繰り返し処理の始まり 省略(いろいろな処理) SKIP CPA GR1,GR2 ;繰り返し処理終了のためのフラグの設定 JPL LOOP ;GR1-GR2>0の場合、LOOPへ
CASL IIの場合、サブルーチンと言う別プログラムは、CALL命令を使って呼び出す。 サブルーチンでの処理が終わると、RET命令により、呼び出し元へ戻る。教科書の例 では、次のようにしている。
CALL SAIDAI ;サブルーチンSAIDIの呼び出し 省略 SAIDAI LAD GR1,-1,GR1 ;サブルーチンでの処理の始まり 省略 RET ;サブルーチンでの処理の終わり(呼び出し元へ)
サブルーチンは別プログラムではあるが、メモリーやレジスターなどは共有されることに 注意が必要である。
教科書のプログラムの内容は、
DATA DC 1,5,6,8,9 LAST DS 0 ;数列の最終アドレス+1とするのである。こうすると数列の先頭のアドレスはDATAで、最終アドレスは LAST-1で示すことができる。
そのような理由で、整数(0〜9)の値に#0030を加えれば文字コードに 変換できる。いろいろな方法が有るが、教科書では次のようにしている。
OR GR3,MOJI ;#0030を加算 MOJI=#0030
この文字コードと整数の対応を見ると、文字コードの最後の4ビットが整数に対応してい ることが分かる。この4ビットを取り出すのは簡単で、マスク処理を行えば良い。教科書 では、汎用レジスターGR3に文字を入れて、それをマスク処理して、整数に変換して いる。つぎのようにである。
AND GR3,=#000F ;マスク処理 最後の4ビットを取り出して、整数化
最後に、先頭の負号の確認を行う必要がある。先頭の文字が負号な らば、ラベルMINUSへ処理が移すために、教科書では次のようにしている。
CPA GR3,='-' ;先頭の桁の処理 先頭をGR3に入れて'-'と比較 JZE MINUS ;マイナスの時は分岐 GR3が'-'ならばMINUSへ
そして、マイナスの場合は絶対値の処理が必要で、-1倍すればよい。それは2の補数にす ればよく、ビット反転と1加算すると実現できる。1との排他的論理和(XOR)を計算す ることにより、ビット反転はできる。教科書のプログラムでは、-1倍は次のようにしてい る。
MINUS XOR GR0,=#FFFF ;ビット反転 ADDA GR0,=1 ;+1加算