(since 1998/11)(更新 2004/02/26)

TNO:CASL入門[11]

情報系/IT系の広告を掲載しています。(広告一覧)
©Copyright 1998-2001,2003,2004 小野智章(小野情報設計)
無断転載を禁止します。
本ページは、「Rook」仕様に対応済みです。
CASL入門[目次]
CASL入門[索引]
CASL入門[10]
CASL入門[12]

(chapter11-page1)
11-1.繰り返しの終了と条件

 「JUMP」命令で、同じ命令を繰り返し実行することが出来ました。 しかし、先ほどのプログラムではいつまでたっても終わりません。
 繰り返しのことを「ループ」といい、 いつまでたっても終わらないループを 特に「無限ループ」と呼びます。 ループをある所まで繰り返した後で終わらせるには、 そのある所まで繰り返したことを プログラムで見つけ出す必要があります。

 次のプログラムは、2つの数を入力して、その積を表示します。
SAMPLE  START
  READ  
  ST  GR0,VAL1
  READ  
  ST  GR0,VAL2
  LAD  GR0,0 ;SUM=0
  LAD  GR1,0 ;COUNT=0
LOOP
  ADDA  GR0,VAL1;SUM+VAL1
  LAD  GR1,1,GR1 ;COUNT+1
  CPA  GR1,VAL2
  JNZ  LOOP ;IF COUNT≠VAL2
  WRITE  
  EXIT
VAL1  DS  
VAL2  DS  
  END
 「LAD GR1,0」は、 「LD GR1,GR0」としても同じ結果が得られます。 一般に「LD」を使った方がオブジェクト・プログラムが短く、 動作も速くなります。 しかしここでは、「0」を明示するために「LAD」を使いました。
 次の結果は、「」と「」を入力した場合の実行例です。
(chapter11-page2)
Input : GR0 = 5(0005)
Input : GR0 = 7(0007)
GR0=35(0023)
プログラムは、PR[001C;SAMPLE+28]が指定したEXIT命令で終了しました。

 新しい命令は「CPA」と「JNZ」です。 「CPA」命令は、レジスタの内容と 実効アドレスの指し示すアドレスの内容との比較を行います。 「JNZ」命令は、直前の比較の結果が「等しくない」時に、 「JUMP」命令と同様に実効アドレスをプログラム・レジスタに入れます。
 上のプログラムでは、GR1とVAL2の内容が等しくない間、 ループの部分を繰り返し実行することになります。 そして、等しくなったら、そのまま次の「WRITE」命令から実行を続けます。

 「CPA」命令の様な数値の比較をする命令を 比較命令と言います。 比較の結果はフラグ・レジスタという 特殊なレジスタに入れられます。 フラグ・レジスタは、FRと表記されることもあり、 Rookのレジスタ表示欄にも表示されています。 フラグ・レジスタは、 比較命令で指定したレジスタから実効アドレスの内容を引いた場合の、 その値が の どれであるかを示します。 (それぞれ、「>」「<」「=」と対応します。) 尚、実際には引き算は行われないので、 汎用レジスタの内容は変化しません。
 比較命令には「CPA」の他「CPL」命令があります。 「CPA」命令が算術値(2の補数表現)での比較であるのに対し、 「CPL」命令は論理値(16ビット非負整数)として比較します。
(chapter11-page3)
 指定レジスタ =(FFFF)16
 実効アドレスの内容=(0000)16
  CPAの結果 = (−1)−0=−1=負
  CPLの結果 = 65535−0=65535=正
 指定レジスタ =(0000)16
 実効アドレスの内容=(FFFF)16
  CPAの結果 = 0−(−1)=1=正
  CPLの結果 = 0−65535=−65535=負

 プログラム・レジスタの内容を変える動作は、 分岐(またはジャンプ)と言います。 また、「JUMP」命令や「JNZ」命令の様な分岐動作をする命令を、 分岐命令(またはジャンプ命令)と言い、 他に「JMI」命令などがあります。
フラグ・レジスタの内容と分岐動作の一覧
分岐命令フラグ・レジスタの内容動作
オーバ・フロー
JMI××負の時だけ、分岐
JZE××0の時だけ、分岐
(JMZ)×負、0の時、分岐
JPL××正の時だけ、分岐
JNZ×負、正の時、分岐
(JPZ)×0、正の時、分岐
JUMP常に、分岐
JOVオーバ・フローの時だけ、分岐
「×」は、分岐動作をしません。
「○」は、分岐動作をします。
「−」は、分岐動作に影響しません。
CASLIIには、JMZ命令とJPZ
命令は存在しません。他の分岐命令の
組合せで、同じ動作をさせます。
 JOV命令の動作の項にある「オーバ・フロー」については、 次の章で説明します。
 尚、旧CASLでは、JPL命令とJOV命令が無く、 JPZ命令が存在していました。

(chapter11-page4)
11-2.フラグ・レジスタの変化

 実は、フラグ・レジスタは比較命令以外でも変化します。 例えば、「SUBA」命令の引き算の結果でも、 フラグ・レジスタの内容が変わります。
フラグ・レジスタの内容が変化する命令
  命令群 命令
 比較命令 CPA,CPL
 算術演算命令 ADDA,SUBA
 論理演算命令 ADDL,SUBL
AND,OR,XOR
 シフト命令 SLA,SRA,SLL,SRL
 ロード命令 LD
 尚、旧CASLでは、ロード命令(LD)ではなく、 ロード・アドレス命令(LEA;現LADに相当)でフラグが変化していました。
 フラグ・レジスタを変化させる命令の内、 「CPA」「CPL」は汎用レジスタは変化せず比較のみです。 その他の命令では、変化した汎用レジスタの値の2の補数表現での正・負・0と、 演算による「オーバ・フロー」の有無が、 フラグ・レジスタに入ります。 尚、「オーバ・フロー」が設定されている時には、 Rookのレジスタ表示欄には「(OV)」と表示されます。
 「オーバ・フロー」とは、 演算結果が有効な値の範囲を越えている、 つまり演算結果が正しくないという意味です。 その範囲は、 算術演算では−32768〜32767、 論理演算では0〜65535の範囲です。 ただし、「LD」、「AND」、「OR」、「XOR」と比較命令では、 汎用レジスタには常に有効な値が設定されるので、 オーバ・フローは発生しません。 又、シフト命令では、シフト動作の最後に追い出されたビットが1である時のみ、 オーバ・フローが発生したと見なされます。
 「オーバ・フロー」は、 汎用レジスタの16ビットに入りきらず、 追い出された17番目のビットと見なすことも出来ます。 CASLII以外のシステムでは、次の処理に持ち越されるビットということから、 「キャリー(桁上がり)」と呼ばれることもあります。

 先ほどのプログラムを、書き換えてみましょう。
SAMPLE  START
  READ  ;SUM
  ST  GR0,VAL ; =VAL
  READ  ;COUNT
LOOP 
  SUBA  GR1,ONE ;COUNT−1
  JZE  LEND ;IF COUNT=0
  ADDA  GR0,VAL ;SUM+VAL
  JUMP  LOOP ;LOOP
LEND 
  WRITE  
  EXIT
VAL  DS  
ONE  DC  
  END

(chapter11-page5)
 「SUBA」命令で繰り返し数(GR1)を1づつ減らしています。 GR1が減って行って0になると、フラグ・レジスタも0を表す様に成ります。 そして、次の「JZE」命令で、ループの部分の後ろへ分岐することになります。
   SUBA  GR1,ONE ;COUNT−1
   JZE  LEND ;IF COUNT=0

ONE  DC  
 ループ部分全体では、GR1が0になるまでGR1を1づつ減らしながら 繰り返す、ということになります。 更に言い替えると、(GR1)回繰り返すということです。 (厳密には、「ADDA」命令の部分は、(GR1−1)回の繰り返しになります。)
 途中の「ADDA」命令でもフラグ・レジスタは変化しますが、 「JZE」命令を実行する時点では その変化は無効になっていることに注意して下さい。

 さて、このソース・プログラムは後ほど利用することになりますから、 「2-3章」に示す方法によって、 ファイルとして保存しておいて下さい。

CASL入門[目次]
CASL入門[索引]
CASL入門[10]
CASL入門[12]
学習室
トップ・ページへ

質問・ご意見等、お待ちしております。
小野智章(小野情報設計) 
Mail to Mail連絡先
©Copyright 1998-2001,2003,2004 小野智章(小野情報設計)
無断転載を禁止します。