(since 1998/11)(更新 2012/02/19)

TNO:CASL入門[16]

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


16-1.マクロ

 この章の内容は、 学習に便利な様に、Rookに追加した機能と 追加計画のある機能についてのものです。 追加計画分については、現在は実現出来ていません。 又、実現形態も変更になる可能性があります。

 「READ」「 WRITE」「IN」「OUT」「EXIT」 「RPUSH」「RPOP」は、 マクロとして定義されている命令です。 マクロを定義すると、それ以降のソース・プログラム中で、 その定義した命令を使用出来る様になります。

 マクロ定義の方法は、CASLIIの仕様には規定されていません。 Rook独自の仕様として、追加予定です。
 前述の予め決まっているマクロの定義は、 Rookでは、アセンブラ内部に記録されています。 その一部を、プログラム中でマクロ定義をする場合の形式で、 実例として示します。
   MACRO  OUT
  PUSH  %0;Str−Adr
  PUSH  %1;Len−Adr
  SVC  #0100
  MACROEND
 
  MACRO  IN
  PUSH  %0;Str−Adr
  PUSH  %1;Len−Adr
  SVC  #0102
  MACROEND
 
  MACRO  WRITE
  PUSH  %0;Reg−No
  SVC  #0104
  MACROEND
 
  MACRO  READ
  PUSH  %0;Reg−No
  SVC  #0106
  MACROEND
 
  MACRO  EXIT
  SVC  #0200
  MACROEND
 
  MACRO  RPUSH
  PUSH  0,GR1
  PUSH  0,GR2
  PUSH  0,GR3
  PUSH  0,GR4
  PUSH  0,GR5
  PUSH  0,GR6
  PUSH  0,GR7
  MACROEND
 
  MACRO  RPOP
  POP  GR7
  POP  GR6
  POP  GR5
  POP  GR4
  POP  GR3
  POP  GR2
  POP  GR1
  MACROEND
 「MACRO」〜「MACROEND」がマクロ定義で、 それぞれ「MACRO」命令のオペランドがマクロ命令となります。
 この様にマクロを定義しておくと、 アセンブル時にマクロ命令がマクロ定義の内容で置き換えられます。 (ソース・プログラム自体は、元のままです。) 例えば、ソース・プログラム中で「OUT A,B」と記述すると、 そのマクロ命令を次の様に置き換えて、アセンブルします。
  PUSH  ;Str−Adr
  PUSH  ;Len−Adr
  SVC  #0100
  POP  GR0
  POP  GR0
 マクロ定義中の「%0」「%1」が、 「OUT」命令のオペランド「A」「B」で 置き換えられていることに注意してください。

 さて、今まで見てきたプログラムは、 「EXIT」マクロ命令で終了していました。 しかし、「EXIT」命令は、以前のCASLには存在しましたが、 本来のCASLIIの仕様では廃止されたマクロ命令です。 本来のCASLIIの仕様によるならば、 あなたの作ってきた様なプログラムは、 「EXIT」命令ではなく「RET」命令で終了します。 即ち、プログラムはサブルーチンとして作成しておき、 OSや他のプログラムなどからサブルーチンとして呼出され、 「RET」命令で呼出した所へ戻るのです。 (Rookでは、このOSへの戻りアドレスは、 「RET」命令でのみアクセス可能で、 「POP」命令では読み出せません。)
 本システムで残しておいた「EXIT」マクロ命令は、 定義内容を「RET」命令にしておくことも出来たのに、 「SVC」命令で実現されています。 その理由は次の章で説明します。


16-2.SVC

 「READ」「 WRITE」「IN」「OUT」「EXIT」は、 「SVC」命令を使って、マクロとして定義しています。
 「SVC」は「スーパバイザ・コール」を省略した語で、 コンピュータの種類によっては「OSコール」と呼ぶ場合もあります。 「スーパバイザ」とは、監視するプログラムという意味で、 「OS」と同義語と考えて良いです。
 「SVC」命令は「OS」の機能を呼出す命令で、 「CALL」命令と同様に、 呼出した「SVC」命令の次の命令のアドレス(とその他の情報) をスタックに積んだ後、 指定された「OS」機能のプログラムの実行を開始します。 その機能のプログラムの実行が終了した後は、 「CALL」命令と同様に、 スタックに積まれている呼出した「SVC」命令の次の命令のアドレスへ戻り、 「SVC」命令の続きから実行を続けます。

 「EXIT」命令は「SVC」命令を使ったマクロでした。 このため、スタックに戻りアドレスが入っていて、 「EXIT」命令のあったアドレス、 即ちプログラムの終了アドレスが分かります。 又、プログラムの間違いによってスタックに積み残しがある場合も、 「RET」命令で終了する場合と異なり暴走することなく、 直接OSに処理を引き継ぐことが出来る様になっています。

 「CALL」命令では、サブルーチンを呼出す時、 実効アドレスでサブルーチンを指定していました。 「SVC」命令でも、呼出す「OS」機能の種類を指定するために、 実効アドレスを使用します。 しかし「SVC」命令で指定する実効アドレスは、 呼出す機能のプログラムのあるアドレスそのものではありません。
 「SVC」命令の実効アドレスには、 OSの呼出し可能な機能の内の、何番目であるかを指定します。 これを、OS、あるいはCPUのハードウェアによって、 実際のプログラムのあるアドレスに変換して、 実行を開始するのです。 これは、OSが改訂されて、 使用するOS機能のプログラムのアドレスが変っても、 呼出し方を変えなくても良い様にするためです。
(ただしCASLIIの仕様で決まっている訳ではないので、 「SVC」命令の実効アドレスがそのまま、 プログラムのあるアドレスになっている場合も有り得ます。)


16-3.NOP

 「NOP」命令は何もしない命令です。
 何もしない命令では、有っても意味が無いと考えるかも知れません。 しかし、実行すると時間が経過します。 これによって、ある時間の経過を待ちたい時に、ループの中などで使用します。

 又、「NOP」命令には、ラベルを付けることが出来ます。
 複数の意味を持ったアドレスなど、 1つのアドレスに複数のラベルを付けたいことが有ります。 しかし、CASLIIの本来の仕様では、 ラベルは命令のある行にしか付けられません。 (Rookでは、ラベルのみの行が可能です。) 「NOP」命令にラベルを付ければ、時間経過以外の余分な動作が無いため、 実質的に1つの処理に複数のラベルを付けることが可能となります。
  :  :  :  :
  JPL  PLUS
  JZE  ZERO
  CALL  PRINTM;PRINT ’−’
  CALL  NEGATE;VAL=−VAL
ZERO  NOP
PLUS  CALL  PRINTVAL
  :  :  :  :
 尚、「DS」命令でも領域確保語数を0にすることで、 同様の効果を上げることが出来ます。 ただし、「DS」命令はデータ格納用の領域を確保するための命令なので、 次の様に実行される命令列の途中にあると、違和感があります。
  :  :  :  :
  JPL  PLUS
  JZE  ZERO
  CALL  PRINTM;PRINT ’−’
  CALL  NEGATE;VAL=−VAL
ZERO  DS  
PLUS  CALL  PRINTVAL
  :  :  :  :

 又「NOP」命令は、 命令の存在自体で、プログラム中に1語分の場所を占めます。 (CASLIIの仕様で1語分になると規定されている訳ではないので、 2語分になる場合も有り得ます。 しかし、オペランド(アドレス部)を持たないので、通常は1語分になります。) これによって、プログラムの長さを調整したい時に使います。
 例えば、オブジェクト・プログラムのデバッグ時に、 主記憶上のある命令を一時的に無効にしたい場合に、 その命令を「NOP」命令で置き換えます。 命令の種類によっては1つの命令が2語分の場所を占める場合がありますが、 この様な命令を置き換える場合は、「NOP」命令2つで置き換えます。
(主記憶上のプログラムを直接書き換えるのは、 デバッグ時に限定した方が良いです。 以前述べた通り、一般には避けるべきです。)


16-4.ファイル入力

 この章の内容は、 学習に便利な様に、Rookに追加した機能についてのものです。 将来、仕様や実現形態が変更になる可能性があります。

 CASLIIの入出力は予め割当てられた装置となっていますが、 Rookでは標準入力標準出力が割当てられています。 標準入力や標準出力とは、 プログラムから見て通常の入出力となるもののことで、 普通は操作用のキーボードや画面などに割当てられていて、 他の装置などに切替えることも出来ます。
 Rookでは標準入力を、 通常のキー入力からファイルからの入力に、 切替えることが出来ます。 標準出力は、現在は画面出力のみです。
 標準入力切換えのための新しい命令は、 「ROPEN」命令と 「RCLOSE」命令です。 入力ファイルに適当なデータを入れた上で、 次のプログラムを実行して見てください。 このソース・プログラム自体を入力ファイルにコピーして実行しても、 面白いでしょう。
SAMPLE  START
IN  STR,LEN
  ROPEN
NEXTL LD  GR1,LEN
  JMI  EOF;End of File
NEXTC SUBA  GR1,=1;Count Down
  JMI  EOL;End of Line
  LD  GR0,STR,GR1;Char.
  CPA  GR0,=’a’
  JMI  NEXTC
  CPA  GR0,=’z’
  JPL  NEXTC
  SUBA  GR0,=32;to Upper
  ST  GR0,STR,GR1;Char.
  JUMP  NEXTC;Next Char.
EOL OUT  STR,LEN
IN  STR,LEN
  JUMP  NEXTL;Next Line
EOF RCLOSE
IN  STR,LEN
EXIT
STR DS  256
LEN DS  
  END
 このプログラムは、入力ファイルの内容を、 英小文字を大文字に変換して出力します。 ただし、最初の1行はキー入力から取込みます。 又、出力後、1行をキー入力します。 この様に最初と最後にキー入力するのは、 標準入力が切り替わっていることを確認するためです。
 新しく出てきた「ROPEN」が 標準入力を入力ファイルからの入力に切替える命令で、 「RCLOSE」が元に戻す命令です。 ソース・プログラム中の最初の「IN」命令は、 「ROPEN」命令より前に実行されるので、 キー入力になります。 2つ目の「IN」命令は、 「ROPEN」命令より後にループ中で実行されるので、 入力ファイルから1行づつ反復して入力します。 ループを終了した後の3つ目の「IN」命令は、 「RCLOSE」命令より後に実行されるので、 キー入力になります。
 入力や出力のためにファイルをアクセス出来る様にする操作を オープンと言い、 ファイルの利用を終了する操作を クローズと言います。 ファイルを開く、閉じるという言い方もあります。 この2つの操作は対で行う必要があり、 その間でだけファイルを利用出来ます。 クローズしないでプログラムの実行を終了することは、 避けてください。 Rookではエラー終了しますが、 他の環境ではどの様な動作をするか判りません。 又、サブルーチン中でオープンしてクローズしないでリターンすると、 Rookも含め、呼出し元でもオープンされたままになってしまいます。
 入力ファイルからの入力では、 入力文字列長が負になることがループの終了条件になっていることに、 注意してください。 CASLIIのIN命令では、入力文字列長が−1になることで、 ファイルの終わりに達したことを表します。 この様なファイルの終わりのことを、 EOF(End Of File)と呼びます。 尚、Rookではキー入力する場合でも、 入力のキャンセル(Cancel)操作によって、EOFにすることが出来ます。
 EOF後にファイルから入力することも、避けてください。 この様な場合、 RookのIN命令では再度EOFになりますが、 他の環境ではどの様な動作をするか判りません。 尚、EOF前にクローズすることは可能です。

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

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