casl2の命令の覚書です。主に自分が使う用ですが、casl2につまずいている人にも役立ててもらえたら嬉しいです。記述内容には注意してますが、間違えている可能性も0ではない(特にIN、OUT命令、OF関連)ので、複数の媒体を参照することをお勧めします。
前提として知っておいた方がいいこと
- どの命令も、
[ラベル] [命令] [オペランド]
の形で使われる。オペランドの中は左から順に汎用レジスタ、アドレス、汎用(指標)レジスタの順で並ぶ。機械語命令は1または2語である。 - 機械語命令でアドレスを参照する場合は2語、しない場合は1語である。
- 1メモリ16ビットであり、これを1語と呼ぶ。2進数でOOOO OOOO OOOO OOOO_(2)の時、右から順にビット位置0,1,2,~,15となる。
- 16進数は#OOOOの形で扱われる。例えば#0013=19である。
- 通常16ビットであれば0~65535までの整数を扱える。また2の補数表現を用いれば-32768~32767の範囲の整数を扱える。前者の範囲で行う演算を 算術演算 、後者の範囲で行う演算を 論理演算 と呼ぶ。
- GR0~7の計8つの 汎用レジスタ(GRn) 、現在実行している命令を指す プログラムレジスタ(PR) 、スタックの位置を指す スタックポインタ(SP) が存在する。そのどれも16ビットである。
- 命令などを補助する フラグレジスタ(FR) は OF、SF、ZF の計3つある。
基本的には以下のように動く(例外もある)。
フラグ名 | 1になる条件 |
---|---|
オーバーフローフラグ(OF) | 算術演算時に結果が-32768~32767の範囲にならないとき、また論理演算時に結果が0~65535の範囲にならないとき |
サインフラグ(SF) | 符号ビットである、ビット位置15が1のとき |
ゼロフラグ(ZF) | 値が0のとき |
- (adr)はアドレスがadrであるメモリの中身を指す。(GRn)はレジスタGRnの中身を指す。
- アドレスの後に,GRxと書くことで、命令で扱うときはadr+(GRx)をアドレスとして扱う。このように命令で扱うアドレスを 実行アドレス と呼ぶ。またこのGRxを 指標レジスタ と呼ぶ。
- 指標レジスタにGR0を使うことは出来ない。
- 命令の前に最大8文字の文字を置けば、ラベル付けでき、そこのアドレスをラベルで置き換えられる。例えば"LABEL"とラベル名を付けたときラベル名のついたアドレスはLABELと書ける。
- =数字と書くと、その数字が格納されたメモリが用意され、その=数字の部分がそのメモリのアドレスに置き換えられる(この=数字を リテラル と呼ぶ)。
プログラム例
;;プログラムEXAMPLE……DATAの値の2の補数表現を求め、RESULTに格納する(例のため敢えて冗長に書いている)
EXAMPLE START ;プログラムの始まり
LD GR1,DATA ;DATAの中身(=#405E)をGR1に格納する
LAD GR2,#FFFF ;GR2に値#FFFFを格納する
LD GR3,=1 ;GR3に値1を格納する
XOR GR1,GR2 ;GR1とGR2の排他的論理和をとり、GR1に格納する
ADDA GR1,DATA,GR3 ;GR1にDATA+1のアドレスが指すメモリの中身(=1)を足す
ST GR1,RESULT ;GR1の中身をRESULTに格納する
RET ;プログラムを終了する
DATA DC #405E ;あるメモリにラベル'DATA'を名付け、値#405Eを格納する
DC 1 ;メモリに値1を格納する
RESULT DS 1 ;1語分のメモリ領域を用意して、最初のメモリにラベル'RESULT'を名付ける
END ;プログラムの終わり
;;セミコロン';'を使うことでプログラムにコメントを付けられる。
命令一覧
1.アセンブラ命令
- プログラムの始まりを表す START
- プログラムの終わりを表す END
- データ領域を示す DS, DC
2.機械語命令
- データをレジスタにロードする LD, LAD
- レジスタのデータをメモリにストア(格納)する ST
- レジスタに値を加算・減算する ADDA, ADDL, SUBA, SUBL
- レジスタの値に論理演算を行う AND, OR, XOR
- レジスタの値を比較をする CPA, CPL
- レジスタの値にシフト演算を行う SLA, SLL, SRA, SRL
- FRの値に従って命令分岐する JOV, JPL, JMI, JZE, JNZ, JUMP
- レジスタの値をスタックする PUSH
- スタックをレジスタに取り出す POP
- サブルーチンに移行する CALL
- サブルーチンから戻る RET
- 割り込み命令を示す SVC
- 何もしない NOP
3.マクロ命令
- 文字列を入力する IN
- 文字列を出力する OUT
- GR1~7のレジスタを全て退避する RPUSH
- RPUSHで退避したレジスタを元に戻す RPOP
アセンブラ命令の説明
1. START命令
- 語数 …… 0語
- 使用形 ……
START
、START adr
- FR設定 …… なし
- 説明 …… START命令はプログラムのスタート地点を示します。メインルーチンの場合ここから、サブルーチンの場合CALLで飛んだ場所がここになります。オペランドにadrを取ると、その地点からプログラムを開始します。PRをadrに設定する命令ともいえます。adrがない場合STARTの下からスタートします。
2. END命令
- 語数 …… 0語
- 使用形 ……
END
- FR設定 …… なし
- 説明 …… END命令はプログラムの終わりの地点を示します。オペランドはなしです。
3. DS命令
- 語数 …… 任意
- 使用形 ……
DS n
- FR設定 …… なし
- 説明 …… DS命令はn語分のメモリの領域を確保します。例えば
DS 10
とするとメモリ領域を10語分確保します。DS 0
の場合は領域を確保しません。なお、確保したメモリ領域に入っている値は不定です。
ラベルを付けて領域を確保した場合、実際にラベル付けされるのは確保した領域の一番最初のメモリです。0語の場合は次のメモリがラベル付けされます。
4. DC命令
- 語数 …… 1語、または任意
- 使用形 ……
DC n
、DC #f
、DC 'string'
、DC adr
- FR設定 …… なし
- 説明 …… DC命令はオペランドの値を格納したメモリを用意する命令です。主に3つの使い方があります。
命令 | 内容 |
---|---|
DC n 、DC #f
|
10進数n、または16進数#fを格納したメモリを1語分用意します。 |
DC 'string' |
シングルクォーテーションで囲まれた文字列を1文字ずつ順にJIS X 0201に従って変換して、メモリに順に格納していきます。用意されるメモリは文字列の文字数分で、ラベル付けした場合一番最初の文字が格納されたメモリをラベル付けします。 |
DC adr |
アドレスadrを格納したメモリを1語分用意します。基本的にDC #f と同じです。もしラベルをオペランドにしたらラベルが指すアドレスを格納します。 |
参考
もしシングルクォーテーション'
自体を格納したい場合、シングルクォーテーションを2つ連続して書くことで格納できます。例:DC 'Let''s go!'
機械語命令の説明
1. ロード・ストア命令
1-1. LD命令
- 語数 …… 1, 2語
- 使用形 ……
LD GRn,GRn'
、LD GRn,adr
、LD GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnにレジスタの中身GRn'、または実行アドレスの指すメモリの中身を格納します。
1-2. LAD命令
- 語数 …… 2語
- 使用形 ……
LAD GRn,adr
、LD GRn,adr,GRx
- FR設定 …… なし
- 説明 …… レジスタGRnに実行アドレス自体を格納します。
1-3. ST命令
- 語数 …… 2語
- 使用形 ……
ST GRn,adr
、ST GRn,adr,GRx
- FR設定 …… なし
- 説明 …… レジスタGRnの値を実行アドレスの指すメモリに格納します。
2. 加算・減算命令
2-1. ADDA命令
- 語数 …… 1, 2語
- 使用形 ……
ADDA GRn,GRn'
、ADDA GRn,adr
、ADDA GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnにレジスタGRn'の中身、または実行アドレスの指すメモリの中身を足します。ADDAのADD'A'は 算術演算(Arithmetic operation) のAを表します。なので、この命令は算術演算の範囲 (-32768~32767) で加算します。
2-2. ADDL命令
- 語数 …… 1, 2語
- 使用形 ……
ADDL GRn,GRn'
、ADDL GRn,adr
、ADDL GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnにレジスタGRn'の中身、または実行アドレスの指すメモリの中身を足します。ADDLのADD'L'は 論理演算(Logical operation) のLを表します。なので、この命令は論理演算の範囲 (0~65535) で加算します。
2-3. SUBA命令
- 語数 …… 1, 2語
- 使用形 ……
SUBA GRn,GRn'
、SUBA GRn,adr
、SUBA GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnにレジスタGRn'の中身、または実行アドレスの指すメモリの中身を引きます。この命令は算術演算の範囲(-32768~32767)で減算します。
2-4. SUBL命令
- 語数 …… 1, 2語
- 使用形 ……
SUBL GRn,GRn'
、SUBL GRn,adr
、SUBL GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnにレジスタGRn'の中身、または実行アドレスの指すメモリの中身を引きます。この命令は論理演算の範囲(0~65535)で減算します。
3. 論理演算命令
3-1. AND命令
- 語数 …… 1, 2語
- 使用形 ……
AND GRn,GRn'
、AND GRn,adr
、AND GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnとレジスタGRn'の中身、または実行アドレスの指すメモリの中身で 論理積 を取り、GRnに結果を格納します。
3-2. OR命令
- 語数 …… 1, 2語
- 使用形 ……
OR GRn,GRn'
、OR GRn,adr
、OR GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnとレジスタGRn'の中身、または実行アドレスの指すメモリの中身で 論理和 を取り、GRnに結果を格納します。
3-3. XOR命令
- 語数 …… 1, 2語
- 使用形 ……
XOR GRn,GRn'
、XOR GRn,adr
、XOR GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnとレジスタGRn'の中身、または実行アドレスの指すメモリの中身で 排他的論理和 を取り、GRnに結果を格納します。
4. シフト演算命令
4-1. SLA命令
- 語数 …… 2語
- 使用形 ……
SLA GRn,adr
、SLA GRn,adr,GRx
- FR設定 …… あり
- 説明 …… 算術演算 の範囲でレジスタの値を左シフトします。具体的にいうと、ビット位置15を除いた15個のビットを左に実行アドレス分移動して、空いたビットに0を格納します。
またFRの内OFは、 最後にシフト演算でレジスタ外に出た値が格納されます。これは他のシフト演算命令も同様です。
4-2. SLL命令
- 語数 …… 2語
- 使用形 ……
SLL GRn,adr
、SLL GRn,adr,GRx
- FR設定 …… あり
- 説明 …… 論理演算 の範囲でレジスタの値を左シフトします。SLA命令と違い、ビット位置15もシフト演算を行います。
4-3. SRA命令
- 語数 …… 2語
- 使用形 ……
SRA GRn,adr
、SRA GRn,adr,GRx
- FR設定 …… あり
- 説明 …… 算術演算の範囲でレジスタの値を右シフトします。SLA命令では空いたビットに0を格納していましたが、SRA命令では ビット位置15の値 が空いたマスに格納されます。
4-4. SRL命令
- 語数 …… 2語
- 使用形 ……
SRL GRn,adr
、SRL GRn,adr,GRx
- FR設定 …… あり
- 説明 …… 論理演算の範囲でレジスタの値を右シフトします。SRA命令と異なり、SLA命令やSLL命令と同じように空いたビット位置には0が格納されます。
それぞれの命令の実行例を以下に示します。
命令 | 命令実行後のGR1の値 | FRの設定 | ビット位置15 |
---|---|---|---|
(命令実行前) | 1110 0110 0011 1001_(2) (=#E639) | ||
SLA GR1,3 |
1011 0001 1100 1000_(2) (=#B1C8) | 010 | 変化しない |
SLL GR1,3 |
0011 0001 1100 1000_(2) (=#31C8) | 100 | 変化する |
SRA GR1,3 |
1111 1100 1100 0111_(2) (=#FCC7) | 010 | 変化しない |
SRL GR1,3 |
0001 1100 1100 0111_(2) (=#1CC7) | 000 | 変化する |
5. 比較命令
5-1. CPA命令
- 語数 …… 1, 2語
- 使用形 ……
CPA GRn,GRn'
、CPA GRn,adr
、CPA GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnとレジスタGRn'の中身、または実行アドレスの指すメモリの中身を 算術演算 の範囲で比較して、結果からFRを設定します。汎用レジスタやメモリの中身は変化しません。FRは以下のように設定されます。
比較結果 | FRの値(OF/SF/ZF) |
---|---|
(GRn)>(GRn')、または(GRn)>(実行アドレス) | 000 |
(GRn)=(GRn')、または(GRn)=(実行アドレス) | 001 |
(GRn)<(GRn')、または(GRn)<(実行アドレス) | 010 |
5-2. CPL命令
- 語数 …… 1, 2語
- 使用形 ……
CPL GRn,GRn'
、CPL GRn,adr
、CPL GRn,adr,GRx
- FR設定 …… あり
- 説明 …… レジスタGRnとレジスタGRn'の中身、または実行アドレスの指すメモリの中身を 論理演算 の範囲で比較して、結果からFRを設定します。汎用レジスタやメモリの中身は変化しません。FRはCPA命令と同じように設定されます。
6. 分岐命令
6-1. JOV命令
- 語数 …… 2語
- 使用形 ……
JOV GRn,adr
、JOV GRn,adr,GRx
- FR設定 …… なし
- 説明 …… FRのOFの値が1 のとき、次行う命令が実行アドレスが指す場所になります。つまりPRを実行アドレスの位置に設定します。もし条件を満たさない場合はJOV命令は何もせず、JOV命令の次の命令にPRは移動します。これは他の分岐命令でも同じです。
6-2. JPL命令
- 語数 …… 2語
- 使用形 ……
JPL GRn,adr
、JPL GRn,adr,GRx
- FR設定 …… なし
- 説明 …… FRのSFとZFの両方が共に0 のとき、実行アドレスの場所に移動します。
6-3. JMI命令
- 語数 …… 2語
- 使用形 ……
JMI GRn,adr
、JMI GRn,adr,GRx
- FR設定 …… なし
- 説明 …… FRのSFが1 のとき、実行アドレスの場所に移動します。
6-4. JZE命令
- 語数 …… 2語
- 使用形 ……
JZE GRn,adr
、JZE GRn,adr,GRx
- FR設定 …… なし
- 説明 …… FRのZFが1 のとき、実行アドレスの場所に移動します。
6-5. JNZ命令
- 語数 …… 2語
- 使用形 ……
JNZ GRn,adr
、JNZ GRn,adr,GRx
- FR設定 …… なし
- 説明 …… FRのZFが0 のとき、実行アドレスの場所に移動します。
6-6. JUMP命令
- 語数 …… 2語
- 使用形 ……
JUMP GRn,adr
、JUMP GRn,adr,GRx
- FR設定 …… なし
- 説明 …… 無条件 に実行アドレスの場所に移動します。
分岐命令の移動条件まとめ(〇で移動、×で移動しない)
FR | OF | SF | ZF | 分岐命令 | JOV | JPL | JMI | JZE | JNZ | JUMP |
---|---|---|---|---|---|---|---|---|---|---|
110 | 1 | 1 | 0 | → | 〇 | × | 〇 | × | 〇 | 〇 |
101 | 1 | 0 | 1 | → | 〇 | × | × | 〇 | × | 〇 |
100 | 1 | 0 | 0 | → | 〇 | 〇 | × | × | 〇 | 〇 |
010 | 0 | 1 | 0 | → | × | × | 〇 | × | 〇 | 〇 |
001 | 0 | 0 | 1 | → | × | × | × | 〇 | × | 〇 |
000 | 0 | 0 | 0 | → | × | 〇 | × | × | 〇 | 〇 |
※なお、FRが111、及び011の値を取ることは論理的に不可能(SFとZFを同時に1にできない)。
7. スタック操作命令
7-1. PUSH命令
- 語数 …… 2語
- 使用形 ……
PUSH GRn,adr
、PUSH GRn,adr,GRx
- FR設定 …… なし
- 説明 …… 実行アドレスの値をスタックします。具体的にいうと、SPの値を1減じてから、SPの指すメモリに実行アドレスを格納します。adrを0と書くと、指標レジスタGRxの値を格納できます。
7-2. POP命令
- 語数 …… 1語
- 使用形 ……
POP GRn
- FR設定 …… なし
- 説明 …… ストックした値をポップしてレジスタに格納します。具体的にいうと、SPの指すアドレスの中身をレジスタに移して、SPを1加算します。
8. 呼び出し命令
8-1. CALL命令
- 語数 …… 2語
- 使用形 ……
CALL adr
、CALL adr,GRx
- FR設定 …… なし
- 説明 …… 実行アドレスが指すサブルーチンにプログラムを移行します。具体的にいうと、CALL命令のあるアドレスに2を足した値をスタックして、実行アドレスの指す地点をPRに格納します。
8-2. RET命令
- 語数 …… 1語
- 使用形 ……
RET
- FR設定 …… なし
- 説明 …… プログラムの終了を意味します。メインルーチンの場合ここで終了します。またサブルーチンの場合は呼び出しの行ったCALL命令の次の命令部分にPRを移動します。具体的にいうと、CALL命令でスタックしたCALL命令の次命令のアドレスをポップして、PRに格納します。いうなれば
POP PR
です。
9. その他の命令
9-1. SVC命令 (2語)
SVC命令は割り込み操作を行います。命令後、FR及びGRは不定です。
9-2. NOP命令 (1語)
NOP命令はなにもしません。
マクロ命令の説明
1. IN命令
- 語数 …… 12語
- 使用形 ……
IN adr,adr'
実際の命令
IN STRING,STRLEN
;; || 同値
PUSH 0,GR1
PUSH 0,GR2
LAD GR1,STRING
LAD GR1,STRLEN
SVC #FFF0
;;ここで入力
POP GR2
POP GR1
- FR設定 …… あり
- 説明 …… 文字列の入力を受け付け、adrから順に格納、その文字列の文字数をadr'に格納します。文字はJIS X 0201に従って格納されます。文字数の最大値は256文字です。それを超える文字を入力したとき、最初の256文字が格納、超過分は無視されて文字数は256文字で扱われます。FRは不定です。
2. OUT命令
- 語数 …… 12語
- 使用形 ……
OUT adr,adr'
実際の命令
OUT STRING,STRLEN
;; || 同値
PUSH 0,GR1
PUSH 0,GR2
LAD STRING
LAD STRLEN
SVC #FFF2
;;ここで出力
POP GR2
POP GR1
- FR設定 …… あり
- 説明 …… adrから格納された文字をadr'に格納された文字数分出力します。IN命令と同様に、JIS X 0201に従い出力されます。FRは不定です。
3. RPUSH命令
- 語数 …… 14語
- 使用形 ……
RPUSH
実際の命令
RPUSH
;; || 同値
PUSH 0,GR1
PUSH 0,GR2
PUSH 0,GR3
PUSH 0,GR4
PUSH 0,GR5
PUSH 0,GR6
PUSH 0,GR7
- FR設定 …… なし
- 説明 …… GR1から順に、7つの汎用レジスタをスタックします。GR0はスタックされません。ポップはGR7から順にポップされます。
4. RPOP命令
- 語数 …… 7語
- 使用形 ……
RPOP
実際の命令
RPOP
;; || 同値
POP GR7
POP GR6
POP GR5
POP GR4
POP GR3
POP GR2
POP GR1
- FR設定 …… なし
- 説明 …… GR7から順に、7つの汎用レジスタをポップします。GR0はポップしません。
RPUSH
でスタックされたレジスタを、RPOP
命令で元に戻せます。
注意点とか
-
指標レジスタにGR0は使えません! 例えば
PUSH 0,GR0
やST GR1,DATA,GR0
のようには使えません。 - 基本的に実行アドレスは 中身 を参照します。例外として分岐関連、スタック・ストア関連、LAD命令 は実行アドレス自体が参照されると思えばいいでしょう。
例
LD GR0,1
〇アドレス1が指すメモリの中身をGR0に読み込む
×GR0に1を格納する……LD GR0,=1
、LAD GR0,1
が正しい
XOR GR1,#FFFF
〇GR1とアドレス#FFFFが指すメモリの中身で排他的論理和を取り、GR1に格納する
×GR1と#FFFFで排他的論理和を取り、GR1に格納する……XOR GR1,=#FFFF
が正しい
ADDA GR2,1
〇GR2にアドレス1が指すメモリの中身を足す
×GR2に1を足す……ADDA GR2,=1
、LAD GR2,1,GR2
が正しい
LAD GR3,=#FFFF
〇GR3に値#FFFFを格納したメモリのアドレスを格納する
×GR3に値#FFFFを格納する……LAD GR3,#FFFF
、LD GR3,=#FFFF
が正しい
SLL GR4,=5
〇GR4を(5を格納したアドレス)分左にシフトする
×GR4を左に5シフトする……SLL GR4,5
が正しい
- CALL・RET命令とPUSH・POP命令のスタックは共通なので、サブルーチンでのスタックの扱いには気を付けましょう。
- IN命令で数字を打ち込んでもそれは数字の 文字列 です。例えば'230'と打った場合文字'2'、'3'、'0'が順に格納されます。数値として扱うためには数値に変換する必要があります。また、OUT命令で出力されるのも文字列なので、数値230を出力したい場合'2'、'3'、'0'のように文字に変換して、順に文字列を格納して出力する必要があります。
おまけ:命令表
命令の種類による分類
命令の種類 | 命令 |
---|---|
アセンブラ命令 |
START 、END 、DS 、DC
|
機械語命令 |
LD 、LAD 、ST 、ADDA 、ADDL 、SUBA 、SUBL 、AND 、OR 、XOR 、CPA 、CPL 、SLA 、SLL 、SRA 、SRL 、JOV 、JPL 、JMI 、JZE 、JNZ 、JUMP 、PUSH 、POP 、CALL 、RET 、SVC 、NOP
|
マクロ命令 |
IN 、OUT 、RPUSH 、RPOP
|
オペランドの形による分類
オペランド | 命令 |
---|---|
GRn |
POP |
GRn,adr(,GRx) |
LD 、LAD 、ST 、ADDA 、ADDL 、SUBA 、SUBL 、AND 、OR 、XOR 、CPA 、CPL 、SLA 、SLL 、SRA 、SRL
|
GRn,GRn' |
LD 、ADDA 、ADDL 、SUBA 、SUBL 、AND 、OR 、XOR 、CPA 、CPL 、SLA 、SLL 、SRA 、SRL
|
adr(,GRx) |
JOV 、JPL 、JMI 、JZE 、JNZ 、JUMP 、PUSH 、CALL 、SVC
|
adr,adr' |
IN 、OUT
|
なし |
START 、END 、RET 、NOP 、RPUSH 、RPOP
|
その他 |
START adr 、DC データ 、DS 領域数
|
語数による分類
語数 | 命令 |
---|---|
0語 |
START 、END
|
1語 |
DC adr 、LD 、ADDA 、ADDL 、SUBA 、SUBL 、AND 、OR 、XOR 、CPA 、CPL 、SLA 、SLL 、SRA 、SRL 、POP 、RET 、NOP
|
2語 |
LD 、LAD 、ST 、ADDA 、ADDL 、SUBA 、SUBL 、AND 、OR 、XOR 、CPA 、CPL 、SLA 、SLL 、SRA 、SRL 、JOV 、JPL 、JMI 、JZE 、JNZ 、JUMP 、PUSH 、CALL 、SVC
|
3語以上 |
IN 、OUT 、RPUSH 、RPOP
|
不定 |
DC '文字列' 、DS 領域数
|