Wikipedia
ウィキペディアCASLの記事があります。

基本情報技術者試験に出題されるCASL(きゃする)に関するコンテンツです。

はじめに編集

基本情報技術者試験(FE)では午後の科目で、選択必須問題としてソフトウェア開発プログラミング)に関する問題が出題されています。C言語JavaPython、CASL、表計算ソフトの5つのコンピュータ言語の中から一つ選択して解答するという内容になっています。

FE午後ではソフトウェア開発の問題は配点が非常に大きいため、擬似言語とともに同試験の鬼門として名高いです。合格するためには擬似言語とソフトウェア開発の問題に関しては特に重点的に対策する必要があります。

CASLはC言語Javaなどに比べて命令文が単純で、プログラムの行数も少ないといった特徴があり、覚えやすい言語です。問題自体も簡単であり、シミュレータも用意しやすいため、初心者がプログラミングを勉強するには丁度良い言語と言えます。

CASLの仕様は試験実施者が予め発表してくれるほか、試験問題中にも仕様書を示してくれるので、試験中にその場で仕様書を読んで理解し解答することも可能です。初心者が合格を狙うならば、表計算と並びオススメの言語です。

CASLの概要編集

CASL(キャスル)は、基本情報技術者試験(旧名称:第二種情報処理技術者試験)におけるプログラミングの試験のために、CAP-Xの後継として1986年(昭和61年)に仕様が策定されたアセンブリ(アセンブラ)言語です。

基本情報技術者試験ではプログラミング能力に関する問題が出題されますが、これでは幾つかのプログラミング言語のなかから、受験者はそれぞれが最も得意とする言語による試験を選択することで、特定の言語のプログラマが有利になることを防いでいます。

この試験で使用するアセンブラ言語としてCASLが開発されました。アセンブラ言語には、ハードウェアのアーキテクチャとの関連性が強いという特徴があります。特定の実在するアーキテクチャを試験に採用した場合、それを利用する受験者に有利に働いてしまうという問題がある。このため、実在するどのアーキテクチャとも関連性がない単純化した仮想の計算機COMP-Xと、そのアセンブリ言語の仕様CAP-Xを策定することで、この問題を解消しました。その後継の仮想計算機をCOMETと呼び、アセンブリ言語の仕様をCASLと名付けました。

COMETは、最低限の機能のみを実装した仮想機械であり、そのためCASLも非常に簡素なアセンブリ言語となっています。初期の仕様ではCOMETの各機械語命令を除けば4種類の擬似命令と3種類のマクロしかありません。COMETとCASLの仕様は試験実施者が予め発表するほか、試験問題中にも示し、試験中にその場で仕様を理解し解答することも可能です。

2001年(平成13年)に第二種情報処理技術者試験が基本情報処理技術者試験に改称された際に、COMETとCASLの仕様改訂も行われており、改訂後はそれぞれCOMET IICASL IIと呼ばれています。なおIT人材育成センター国家資格・試験部(旧・情報処理技術者試験センター)から、WindowsのJava環境で動作するCASL-IIシミュレータが学習用に提供されています。(この他にも非公式のシミュレータがいくつか開発されています。)

情報処理技術者試験の開始当初には、同様にCAP-XおよびCOMP-Xが用いられていましたが、主にマイクロプロセッサの登場と普及に伴う主流アーキテクチャの変化に伴い、変化に対応した新しいアセンブラ言語および仮想計算機としてCASLおよびCOMETが定義されています。

COMET の仕様編集

ここでは、COMET IIに改訂される前のCOMETの仕様について述べます。COMET IIとの違いについては#仕様改訂による変更点を参照してください。

COMETは、1ワード長が16ビットの固定長語で表現され、処理の対象となるデータは全てワード単位で行われます。1ワードを構成するビットの並びは、最上位ビットを0番、最下位ビットを15番とします(COMET IIで変更されています)。制御方式は逐次処理方式であり、命令語は2ワードの固定長で表現されます。扱うデータは算術データ、論理データ、文字データの3種類があり、算術データは 1ワードのデータを2の補数表現で表現し、論理データは符号無し整数として扱います。文字データはJIS X 0201規格を採用しています。

レジスタは次の通りです。

汎用レジスタ GR0、GR1、GR2、GR3、GR4
16ビットのレジスタ。算術演算と論理演算、比較およびシフト演算に用います。このうち GR1からGR4 は指標(インデックス)レジスタとしても用います。GR4はスタックポインタとして用います。スタックポインタにはスタックの最上段のアドレスが保持されます。
プログラムカウンタ PC
実行中の命令語の先頭アドレスを保持し、命令が終了すると次に実行される命令語の先頭アドレスが設定されます。上述のようにCOMETの命令語は2ワード固定長なので分岐命令のように次に実行するアドレスを指定するもの以外の場合は保持しているアドレスに 2 を加算します。
フラグレジスタ FR
2ビットのレジスタで、実行された命令が算術演算や論理演算命令の場合、実行結果が負なら10、正なら00、零なら01が設定されます。比較演算命令も同様に比較結果に応じて値が設定されます。

前述の通りCASLは命令語を2ワードの固定長として扱います。命令語の構成は先頭から順に OPフィールド(8ビット)、GRフィールド(4ビット)、XRフィールド(4ビット)、ADRフィールド(16ビット)のデータアドレスと続きます。COMETの前身であるCOMP-Xとほぼ同様の構成ですが各フィールドのビット数が違うことに注意してください。

OP フィールドは命令の種類を表すコード(オペコード部)であり、初期のCOMETでは23種類の命令が用意されており、COMET IIでは 28種類に拡張されています。GR フィールドでは演算で使用する GR の番号が指定されます。分岐命令やスタック操作の場合は GRを指定することはないので、これらの命令ではこの部分は無視されます(何を指定しても問題ありません)。XR フィールドではアドレス修飾を行う GR の番号が指定され、内容が0の場合はGR0を意味するのではなく、GR によるアドレス修飾をしないGRフィールドと同様、アドレス修飾を持たない命令においては無視されます。ADRフィールドは処理対象となるアドレスが指定され、このアドレスにXRフィールドのアドレス修飾を施したものが実行アドレスとして使用されます。

なお、COMP-Xと異なり、COMETでは命令の具体的なオペコードは定義されていません(定義の後に、定義の一部でないと明示のうえで参考資料として示されています)。

命令コードと各命令の概要は以下の通りです。なお、書き方の[]は省略可能を意味しています。

LD GR, adr[, XR] - LoaD
有効アドレスの内容を指定した GRアドレスに設定します。
ST GR, adr[, XR] - STore
GRレジスタに設定された内容を実行アドレスに格納します。
LEA GR, adr[, XR] - Load Effective Address
有効アドレスの番地をGRに格納します。実行後、格納された値に応じて、FRに01、10、00を設定します。COMET IIの改訂後にこの命令は廃止され、代わりにFRレジスタを更新しないLAD命令が追加されました。
ADD GR, adr[, XR] - ADD arithmetic
GRの内容と有効アドレスの内容を加算し、結果をGRに格納します。このとき、FRの設定も行います。COMET IIの改訂後に、名称をADDAと改称しています。
SUB GR, adr[, XR] - SUBtract arithmetic
GRの内容から有効アドレスの内容を減算し、結果をGRに格納します。このとき、FRの設定も行います。ADDと同様、COMET IIの改訂後に名称をSUBAと改称しています。
AND GR, adr[, XR]
GRの内容と有効アドレスの内容の論理積をGRに格納します。このとき、FRの設定も行います。
OR GR, adr[, XR]
GRの内容と有効アドレスの内容の論理和をGRに格納します。このとき、FRの設定も行います。
EOR GR, adr[, XR] - Exclusive OR
GRの内容と有効アドレスの内容の排他的論理和をGRに格納します。このとき、FRの設定も行います。COMET IIの改訂後に、名称をXORと改称しています。
CPA GR, adr[, XR] - ComPare Arithmetic
GRの内容と有効アドレスの内容を算術比較し、GRの内容の方が大きければ、FRに00を、等しければ01を、小さければ10を設定します。
CPL GR, adr[, XR] - ComPare Logic
CPAと同様ですが、内容を算術データではなく論理データとして扱います。
SLL GR, adr[, XR] - Shift Left Logic
左に有効アドレス分シフトします、シフトにより欠落したデータは捨てられ、空いたビットには0が入ります。シフト後の内容により、FRに値が設定されます。
SLA GR, adr[, XR] - Shift Left Arithmetic
符号を表すビット(第0ビット、COMET IIでは第15ビット)を除いて左に有効アドレス分シフトします。シフトにより欠落したデータは捨てられ、空いたビットには 0が入ります。シフト後の内容により、FRに値が更新されます。
SRL GR, adr[, XR] - Shift Right Logic
SLLの右シフト版です。
SRA GR, adr[, XR] - Shift Right Arithmetic
SLAの右シフト版です。
JPZ adr[, XR] - Jump on Plus or Zero
FRの値が00か01の場合は有効アドレスに分岐します。COMET IIの改訂により廃止されました。
JMI adr[, XR] - Jump on MInus
FRの値が10の場合は有効アドレスに分岐します。
JNZ adr[, XR] - Jump on Non Zero
FRの値が10か01の場合は有効アドレスに分岐します。
JZE adr[, XR] - Jump on ZEro
FRの値が00の場合は有効アドレスに分岐します。
JMP adr[, XR] - unconditional JuMP
無条件に有効アドレスに分岐します。
PUSH adr[, XR] - PUSH effective address
有効アドレスをスタックに格納します。このとき GR4にスタックの先頭アドレスが設定されます。
POP GR - POP up
スタックの先頭に格納されているアドレスを GRに設定します。GR4に新しいスタックの先頭アドレスが設定されます。
CALL adr[, XR] - CALL subroutine
サブルーチンを呼び出します。
RET - RETurn form subroutine
サブルーチンから呼び出し、呼び出し元に復帰します。

CASL の仕様編集

CASL は1行に、ラベル、命令コード、オペランドの順に記述します。ラベルは記述しない場合もあります。ラベルは3文字以内で、先頭は英大文字、それ以外は英大文字または数字でし。オペランドでアドレスを指定する際に数値の代わりにラベルを記述できます。

CASL には次の擬似命令があります。

START [実行開始番地]
プログラムの先頭に必ず書かれます。実行開始番地は[エントリーポイント]が指定されます、省略された場合は先頭から実行を開始します。
END
プログラムの終了を意味します。プログラムの最後に必ず書かれなければなりません。
DC n - Define Constant
nで指定した10進数の数値を1ワードの2進数データとして格納します。ただし、n が算術データの範囲(-32768から32767まで)に無い場合は、下位16ビットが格納されます。
DS n - Define Storage
nワード語長の領域を確保します。

また、CASLには入出力を表すマクロ命令が用意されています。内容は以下の通りです。

IN 入力領域, 入力文字長
この命令が実行されると入力待ちが発生します。データが入力されると入力されたデータを文字型として入力領域に入力します、入力は1文字を1ワードに格納します。COMETでは文字データはJIS X 0201(8ビット)のため、1文字1ワード(16ビット)では空きが発生することになりますが、入力データは 8ビット目以降に入力され、0から7ビット目までには0が格納されます。また入力長には入力したデータの長さが格納されます。入力領域、入力長はともにラベル名で指定します。
OUT 出力領域, 出力文字長
出力領域に格納されているデータを出力文字長分、文字として表示します。IN 命令と同様 1ワード1文字に対応します。
EXIT
プログラムの実行を終了します。CASL IIの改訂により廃止されました。

仕様改訂による変更点編集

2001年のCOMET II、CASL IIの改訂によってCASL COMETに比べていくつかの変更が行われています。具体的には以下の通りです。

  • ビットの数え方が変更されています。COMETでは最上位ビットを0番、最下位ビットを15番としていましたが、COMET IIでは最上位ビットが15番、最下位ビットが0番です。
  • GRの数がGR0からGR7までに拡張されています。
  • スタックポインタ専用のレジスタ SPが追加されています。これにより、スタックポインタとGR4の関係が無くなりました。
  • FRが3ビットに変更されています。最上位ビットにあたる部分が算術命令等で算術オーバーフローが発生した場合は1、それ以外が0が格納されるフラグとして追加されます。
  • ADD、SUBがそれぞれADDA、SUBAという名称に変更されています。
  • EORがXORという名称に変更されています。
  • JMPがJUMPという名称に変更されています。
  • レジスタ同士の演算が可能になりました。具体的には "命令 GR1, GR2"という書き方で有効アドレスではなく GR2の内容から演算を行う。この書き方が採用された命令は以下の通りです。
    • LD
    • ADDA(ADD)
    • SUBA(SUB)
    • AND
    • OR
    • XOR(EOR)
    • CPA
    • CPL
  • LD 命令の実行後 FRが設定されるようになりました。
  • COMETのLEAとJPZ命令、CASLのEXIT命令が廃止されました。
  • COMET II、CASL II共に追加された命令があります。

COMET IIに追加された命令は以下の通りです。

LAD GR, adr[, XR] - Load ADress
廃止された LEA 命令と同様の機能を持ちますが、実行後に FRレジスタを更新しない点が異なります。
ADDL GR, adr[, XR]、ADDL GR1, GR2 - ADD Logic
ADDA とほぼ同様ですが、データを算術データではなく論理データ(符号無し整数)として扱います。
SUBL GR, adr[, XR]、SUBL GR1, GR2 - SUBtract Logic
SUBA と同様ですがデータを算術データではなく論理データ(符号無し整数)として扱います。
JPL adr[, XR] - Jump on PLus
FRの値が *00 の場合、有効アドレスに分岐します。
JOV adr[, XR] - Jump on OVerflow
FRの値が 1** の場合、有効アドレスに分岐します。
SVC adr[, XR] - SuperVisor Call
実行アドレスを引数としてシステムコールを行います。実行後のGRとFRは不定となります。
NOP - No OPeration
何もしない命令です。

CASL IIに追加された命令は以下の通りです。

RPUSH
GR1からGR7の順で内容をスタックに順次格納します。
RPOP
スタックから順次値を取り出し、GR7からGR1の順に格納します。

サンプルコード編集

以下は CASL II による再帰呼び出しを用いて、ハノイの塔(パズルの一種)を解くサンプルコードの一例です。

; ハノイの塔を解くプログラム
MAIN   START
       LD      GR0,N
       LD      GR1,A
       LD      GR2,B
       LD      GR3,C
       CALL    HANOI       ; hanoi(3, A, B, C)
       RET

; hanoi(N, X, Y, Z)
HANOI  CPA     GR0,=1      ; if N == 1 then
       JZE     DISP        ;  move it, return
       SUBA    GR0,=1      ; N - 1
       PUSH    0,GR2       ; swap GR2 GR3
       LD      GR2,GR3
       POP     GR3
       CALL    HANOI       ; hanoi(N-1, X, Z, Y)
       ST      GR1,MSG1
       ST      GR2,MSG2    ; now GR2 holds Z
       OUT     MSG,LNG     ; 'from X to Z'
       PUSH    0,GR2       ; rotate registers
       LD      GR2,GR1
       LD      GR1,GR3
       POP     GR3
       CALL    HANOI       ; hanoi(N-1, Y, X, Z)
       PUSH    0,GR2       ; restore registers
       LD      GR2,GR1
       POP     GR1
       ADDA    GR0,=1      ; also N has restored
       RET

DISP   ST      GR1,MSG1    ; 'from X to Z'
       ST      GR3,MSG2
       OUT     MSG,LNG
       RET

N      DC      3	; 輪の総数
LNG    DC      11	; メッセージの長さ
A      DC      'A'
B      DC      'B'
C      DC      'C'
MSG    DC      'from '
MSG1   DS      1
       DC      ' to '
MSG2   DS      1
       END

このコードを実行すると以下の結果が得られます(ここで、from A to C は A の一番上にある円盤を C に移すことを意味しています)。

from A to C
from A to B
from C to B
from A to C
from B to A
from B to C
from A to C
このページ「CASL」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。