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加算