数字を文字列に変換する処理をCASL2ではソフトウェアで実現しないといけません。
前回は、16進数のキャストの方法について触れました。
今回は、2進数のキャストについてに見てみたいと思います。
数値を2進文字列にキャスト
例1: 数値「2」を2進文字列にキャスト
1 | MAIN | START |
|
2 | | CALL INT2BIN | ;「INT2BIN」サブルーチンの呼び出し
|
3 | | OUT STR, STRLEN | ;STR番地開始の文字列を出力
|
4 | | RET |
|
5 | | |
|
6 | INT2BIN | LD GR1, INT | ;INT番地から数値を転送
|
7 | | LAD GR2, 15 | ;指標値
|
8 | LP | LD GR3, GR1 | ;編集用に数値をGR3に転送
|
9 | | AND GR3, =#0001 | ;数値の1ビット目が1か0か判定
|
10 | | LD GR0, ='0' | ;「0」の文字コードをGR0に転送
|
11 | | CPA GR3, =0 | ;数値と0を比較
|
12 | | JZE NX | ;数値が0と同じならNXに移動
|
13 | | ADDA GR0, =1 | ;文字コードに1を加算
|
14 | NX | ST GR0, STR, GR2 | ;文字コードをSTRに格納
|
15 | | LAD GR2, -1, GR2 | ;指標値をデクリメント
|
16 | | SRL GR1, 1 | ;数値を1ビット右シフト
|
17 | | CPA GR2, =0 | ;指標値と0を比較
|
18 | | JPL LP | ;指標値が0より大きいならLPに移動
|
19 | | JZE LP | ;指標値が0と同じならLPに移動
|
20 | | RET |
|
21 | | |
|
22 | INT | DC 2 | ;数値
|
23 | STR | DS 16 | ;文字列を入れる領域
|
24 | STRLEN | DC 16 | ;文字列の長さ
|
25 | | END |
|
シミュレータにそのままコピー&ペーストで使えます。
解説
数値を2進文字列にキャストは、数値の先頭ビットから1ビットずつ参照し1か0であるか確認しキャストしています。
このプログラムは、先頭ビットから1ビットずつ値を見て行き、
・0のときは「0」の文字コード(0030)16
・1のときは「1」の文字コード(0031)16
をメモリに格納します。
数値
2を2進文字列に変えるので、
「0000 0000 0000 0010」が出力されます。
1ビットずつ桁の数字を確かめているので、どうしてもループ回数が多くなってしまうのが難点ですね。
以下参考までに文字コード表を載せます。
【文字コード表】

それでは、データの流れを追ってみます。
例1のINT2BIN(6~20行)のトレース
初期状態
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | |
~1ループ目~
8行 LD GR3, GR1
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | |
9行 AND GR3, =#0001
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | |
AND演算で、GR3の値が0になるためフラグレジスタが変化します。
10行 LD GR0, ='0'
【汎用レジスタ】
GR0 | 110000 |
GR1 | 10 |
GR2 | 1111 |
GR3 | 0 |
【フラグレジスタ】
【メモリ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | |
GR0に「0」の文字コードを転送します。
11行 CPA GR3, =0
【汎用レジスタ】
GR0 | 110000 |
GR1 | 10 |
GR2 | 1111 |
GR3 | 0 |
【フラグレジスタ】
【メモリ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | |
CPA命令で、GR1の値 0 と 0 を比較します。
0 = 0 なのでフラグレジスタに変化はありません。
12行 JZE NX
【フラグレジスタ】
ZFが1なので、JZE命令で指定されたラベル「NX」に移動し14行を処理します。
14行 ST GR0, STR, GR2
【汎用レジスタ】
GR0 | 110000 |
GR1 | 10 |
GR2 | 1111 |
GR3 | 0 |
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
ST命令で、STR+15番地に「0」の文字コードを格納します。
15行 LAD GR2, -1, GR2
【汎用レジスタ】
GR0 | 110000 |
GR1 | 10 |
GR2 | 1110 |
GR3 | 0 |
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
16行 SRL GR1, 1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
GR1の値が1になるためフラグレジスタが変化します。
17行 CPA GR2, =0
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
CPA命令で、GR2の値 14 と 0 を比較します。
14 > 0 なのでフラグレジスタに変化はありません。
18行 JPL LP
19行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し8行を処理します。
前行でジャンプしているので19行は処理しません。
~2ループ目~
8行 LD GR3, GR1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
9行 AND GR3, =#0001
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
AND演算で、GR3の値が1になるためフラグレジスタに変化はありません。
10行 LD GR0, ='0'
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
GR0に「0」の文字コードを転送します。
11行 CPA GR3, =0
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
CPA命令で、GR3の値 1 と 0 を比較します。
1 > 0 なのでフラグレジスタに変化はありません。
12行 JZE NX
【フラグレジスタ】
ZFが0なので、JZE命令で指定されたラベル「NX」に移動せず13行を処理します。
13行 ADDA GR0, =1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | |
STR+15 | 110000 |
GR0の値が(0031)16になるためフラグレジスタに変化はありません。
14行 ST GR0, STR, GR2
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
ST命令で、STR+14番地に「1」の文字コードを格納します。
15行 LAD GR2, -1, GR2
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
16行 SRL GR1, 1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
GR1の値が0になるためフラグレジスタが変化します。
17行 CPA GR2, =0
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR3の値 13 と 0 を比較します。
13 < 0 なのでフラグレジスタが変化します。
18行 JPL LP
19行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し8行を処理します。
前行でジャンプしているので19行は処理しません。
~3ループ目~
8行 LD GR3, GR1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
9行 AND GR3, =#0001
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
AND演算で、GR3の値が0になるためフラグレジスタが変化します。
10行 LD GR0, ='0'
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
GR0に「0」の文字コードを転送します。
11行 CPA GR3, =0
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR3の値 0 と 0 を比較します。
0 = 0 なのでフラグレジスタに変化はありません。
12行 JZE NX
【フラグレジスタ】
ZFが1なので、JZE命令で指定されたラベル「NX」に移動し14行を処理します。
14行 ST GR0, STR, GR2
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
ST命令で、STR+13番地に「0」の文字コードを格納します。
15行 LAD GR2, -1, GR2
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
16行 SRL GR1, 1
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR1の値が0になるためフラグレジスタに変化はありません。
17行 CPA GR2, =0
【汎用レジスタ】
【フラグレジスタ】
STR+0 | |
: | : |
STR+12 | |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR2の値 12 と 0 を比較します。
12 > 0 なのでフラグレジスタが変化します。
18行 JPL LP
19行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し8行を処理します。
前行でジャンプしているので19行は処理しません。
以下、4~16ループ目ではほぼ同じ処理なので省略します。
STR+12~STR+0まで「0」の文字コードを格納し、処理が終了します。
結果、メモリの内容は以下のようになります。
0~13番地に
「0」の文字コードが格納されています。
STR+0:(0030)16 = 「0」の文字コード
:
STR+14:(0031)16 = 「1」の文字コード
STR+15:(0030)16 = 「0」の文字コード
最後にOUT命令で、STR+0 ~ STR+15番地まで出力され
「0000 0000 0000 0010」と表示されます。
(0000 0000 0000 0010)2 = 2
なので正しい答えになっていますね。
2進文字列を数値にキャスト
例2: 2進文字列「0000 0000 0000 0010」を数値にキャスト
1 | MAIN | START |
|
2 | | CALL BIN2INT | ;「BIN2INT」サブルーチンの呼び出し
|
3 | | ST GR0, INT | ;答えの数値をINT番地に格納
|
4 | | RET |
|
5 | | |
|
6 | BIN2INT | LAD GR0, 0 | ;GR0を答えの格納用に初期化
|
7 | | LD GR2, IDX | ;指標値
|
8 | | LAD GR3, 1 | ;答えの数値
|
9 | LP | LD GR1, STR, GR2 | ;STR+指標値番地から文字コードを転送
|
10 | | CPA GR1, ='0' | ;文字コードと「0」の文字コードを比較
|
11 | | JZE NX | ;文字コードが「0」の文字コードと同じならNXに移動
|
12 | | ADDA GR0, GR3 | ;答えを加算
|
13 | NX | SLL GR3, 1 | ;答えを1ビット左シフト
|
14 | | LAD GR2, -1, GR2 | ;指標値から1を減算
|
15 | | CPA GR2, =0 | ;指標値と0を比較
|
16 | | JPL LP | ;指標値が0より大きいならLPに移動
|
17 | | JZE LP | ;指標値が0と同じならLPに移動
|
18 | | RET |
|
19 | | |
|
20 | STR | DC '0000000000000010' | ;2進文字列
|
21 | IDX | DC 15 | ;指標値
|
22 | INT | DS 1 | ;数値を入れる領域
|
23 | | END |
|
シミュレータにそのままコピー&ペーストで使えます。
解説
2進文字列を数値にキャストは、2進文字列の末尾から一つ一つ値を見て行き、「0」の文字コード(0030)16なら何もせず、「1」の文字コード(0031)16なら該当する値を加算する処理を行っています。
該当する値とは汎用レジスタGR3に転送された値のことです。GR3の値は、最終結果
ループ処理毎に、加算する値の重みを増すために1ビット論理左シフトを行っています。
それでは、トレースでデータの流れを追ってみます。
【文字コード表】

例2のBIN2INT(6~18行)のトレース
初期状態
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
~1ループ目~
9行 LD GR1, STR, GR2
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
10行 CPA GR1, ='0'
【汎用レジスタ】
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR1の値 「0」の文字コード と 「0」の文字コード を比較します。
(0030)16 = (0030)16 なのでフラグレジスタが変化します。
11行 JZE NX
【フラグレジスタ】
ZFが1なので、JZE命令で指定されたラベル「NX」に移動し13行を処理します。
13行 SLL GR3, 1
【汎用レジスタ】
GR0 | 0 |
GR1 | 110000 |
GR2 | 1111 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR3の値が2になるためフラグレジスタが変化します。
14行 LAD GR2, -1, GR2
【汎用レジスタ】
GR0 | 0 |
GR1 | 110000 |
GR2 | 1110 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
15行 CPA GR2, =0
【汎用レジスタ】
GR0 | 0 |
GR1 | 110000 |
GR2 | 1110 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR2の値 14 と 0 を比較します。
14 > 0 なのでフラグレジスタに変化はありません。
16行 JPL LP
17行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。
~2ループ目~
9行 LD GR1, STR, GR2
【汎用レジスタ】
GR0 | 0 |
GR1 | 110001 |
GR2 | 1110 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
10行 CPA GR1, ='0'
【汎用レジスタ】
GR0 | 0 |
GR1 | 110001 |
GR2 | 1110 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR1の値 「1」の文字コード と 「0」の文字コード を比較します。
「1」の文字コード > 「0」の文字コード なのでフラグレジスタに変化はありません。
11行 JZE NX
【フラグレジスタ】
ZFが0なので、JZE命令で指定されたラベル「NX」に移動せず12行を処理します。
12行 ADDA GR0, GR3
【汎用レジスタ】
GR0 | 10 |
GR1 | 110001 |
GR2 | 1110 |
GR3 | 10 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR0の値が2になるためフラグレジスタに変化はありません。
13行 SLL GR3, 1
【汎用レジスタ】
GR0 | 10 |
GR1 | 110001 |
GR2 | 1110 |
GR3 | 100 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR3の値が4になるためフラグレジスタに変化はありません。
14行 LAD GR2, -1, GR2
【汎用レジスタ】
GR0 | 10 |
GR1 | 110001 |
GR2 | 1101 |
GR3 | 100 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
15行 CPA GR2, =0
【汎用レジスタ】
GR0 | 10 |
GR1 | 110001 |
GR2 | 1101 |
GR3 | 100 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR2の値 13 と 0 を比較します。
13 > 0 なのでフラグレジスタに変化はありません。
16行 JPL LP
17行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。
~3ループ目~
9行 LD GR1, STR, GR2
【汎用レジスタ】
GR0 | 10 |
GR1 | 110000 |
GR2 | 1101 |
GR3 | 100 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
10行 CPA GR1, ='0'
【汎用レジスタ】
GR0 | 10 |
GR1 | 110000 |
GR2 | 1101 |
GR3 | 100 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
CPA命令で、GR1の値 「0」の文字コード と 「0」の文字コード を比較します。
「0」の文字コード = 「0」の文字コード なのでフラグレジスタが変化します。
11行 JZE NX
【フラグレジスタ】
ZFが1なので、JZE命令で指定されたラベル「NX」に移動し13行を処理します。
13行 SLL GR3, 1
【汎用レジスタ】
GR0 | 10 |
GR1 | 110000 |
GR2 | 1101 |
GR3 | 1000 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR3の値が8になるためフラグレジスタが変化します。
14行 LAD GR2, -1, GR2
【汎用レジスタ】
GR0 | 10 |
GR1 | 110000 |
GR2 | 1100 |
GR3 | 1000 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
15行 CPA GR2, =0
【汎用レジスタ】
GR0 | 10 |
GR1 | 110000 |
GR2 | 1100 |
GR3 | 1000 |
【フラグレジスタ】
【メモリ】
STR+0 | 110000 |
: | : |
STR+12 | 110000 |
STR+13 | 110000 |
STR+14 | 110001 |
STR+15 | 110000 |
GR2の値が12になるためフラグレジスタに変化はありません。
16行 JPL LP
17行 JZE LP
【フラグレジスタ】
ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。
以下、4~16ループ目ではほぼ同じ処理なので省略します。
STR+12~STR+0番地には「0」の文字コードが格納されているので、GR0に0が加算され続けるため省略します。
以上で処理が終了し、GR0に答えが格納されています。
GR0:(10)2 = 2
よって、正しい答えが格納されていますね。
最後に
今回は、2進数、2進文字列相互の変換についてでした。
それでは次回にまたご期待を!