ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ






2018-08-08

CASL2で2進数のキャスト方法







数字を文字列に変換する処理を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行)のトレース



初期状態

【汎用レジスタ】
GR0?
GR110
GR21111
GR3?

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0
::
STR+12
STR+13
STR+14
STR+15



~1ループ目~

8行 LD GR3, GR1

【汎用レジスタ】
GR0?
GR110
GR21111
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0
::
STR+12
STR+13
STR+14
STR+15



9行 AND GR3, =#0001

【汎用レジスタ】
GR0?
GR110
GR21111
GR30

【フラグレジスタ】
ZFSFOF
100

【メモリ】
STR+0
::
STR+12
STR+13
STR+14
STR+15

AND演算で、GR3の値が0になるためフラグレジスタが変化します。



10行 LD GR0, ='0'

【汎用レジスタ】
GR0110000
GR110
GR21111
GR30

【フラグレジスタ】
ZFSFOF
100

【メモリ】
STR+0
::
STR+12
STR+13
STR+14
STR+15

GR0に「0」の文字コードを転送します。



11行 CPA GR3, =0

【汎用レジスタ】
GR0110000
GR110
GR21111
GR30

【フラグレジスタ】
ZFSFOF
100

【メモリ】
STR+0
::
STR+12
STR+13
STR+14
STR+15

CPA命令で、GR1の値 0 と 0 を比較します。
0 = 0 なのでフラグレジスタに変化はありません。



12行 JZE NX

【フラグレジスタ】
ZFSFOF
100

ZFが1なので、JZE命令で指定されたラベル「NX」に移動し14行を処理します。



14行 ST GR0, STR, GR2

【汎用レジスタ】
GR0110000
GR110
GR21111
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

ST命令で、STR+15番地に「0」の文字コードを格納します。



15行 LAD GR2, -1, GR2

【汎用レジスタ】
GR0110000
GR110
GR21110
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14
STR+15110000



16行 SRL GR1, 1

【汎用レジスタ】
GR0110000
GR11
GR21110
GR30

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

GR1の値が1になるためフラグレジスタが変化します。



17行 CPA GR2, =0

【汎用レジスタ】
GR0110000
GR11
GR21110
GR30

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

CPA命令で、GR2の値 14 と 0 を比較します。
14 > 0 なのでフラグレジスタに変化はありません。



18行 JPL LP
19行 JZE LP

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し8行を処理します。
前行でジャンプしているので19行は処理しません。



~2ループ目~

8行 LD GR3, GR1

【汎用レジスタ】
GR0110000
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000



9行 AND GR3, =#0001

【汎用レジスタ】
GR0110000
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

AND演算で、GR3の値が1になるためフラグレジスタに変化はありません。



10行 LD GR0, ='0'

【汎用レジスタ】
GR0110000
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

GR0に「0」の文字コードを転送します。



11行 CPA GR3, =0

【汎用レジスタ】
GR0110000
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

CPA命令で、GR3の値 1 と 0 を比較します。
1 > 0 なのでフラグレジスタに変化はありません。



12行 JZE NX

【フラグレジスタ】
ZFSFOF
000

ZFが0なので、JZE命令で指定されたラベル「NX」に移動せず13行を処理します。



13行 ADDA GR0, =1

【汎用レジスタ】
GR0110001
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14
STR+15110000

GR0の値が(0031)16になるためフラグレジスタに変化はありません。



14行 ST GR0, STR, GR2

【汎用レジスタ】
GR0110001
GR11
GR21110
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

ST命令で、STR+14番地に「1」の文字コードを格納します。




15行 LAD GR2, -1, GR2

【汎用レジスタ】
GR0110001
GR11
GR21101
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000



16行 SRL GR1, 1

【汎用レジスタ】
GR0110001
GR10
GR21101
GR31

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

GR1の値が0になるためフラグレジスタが変化します。



17行 CPA GR2, =0

【汎用レジスタ】
GR0110001
GR10
GR21101
GR31

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

CPA命令で、GR3の値 13 と 0 を比較します。
13 < 0 なのでフラグレジスタが変化します。



18行 JPL LP
19行 JZE LP

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し8行を処理します。
前行でジャンプしているので19行は処理しません。



~3ループ目~

8行 LD GR3, GR1

【汎用レジスタ】
GR0110001
GR10
GR21101
GR30

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000



9行 AND GR3, =#0001

【汎用レジスタ】
GR0110001
GR10
GR21101
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

AND演算で、GR3の値が0になるためフラグレジスタが変化します。



10行 LD GR0, ='0'

【汎用レジスタ】
GR0110000
GR10
GR21101
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

GR0に「0」の文字コードを転送します。



11行 CPA GR3, =0

【汎用レジスタ】
GR0110000
GR10
GR21101
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13
STR+14110001
STR+15110000

CPA命令で、GR3の値 0 と 0 を比較します。
0 = 0 なのでフラグレジスタに変化はありません。



12行 JZE NX

【フラグレジスタ】
ZFSFOF
100

ZFが1なので、JZE命令で指定されたラベル「NX」に移動し14行を処理します。



14行 ST GR0, STR, GR2

【汎用レジスタ】
GR0110000
GR10
GR21101
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13110000
STR+14110001
STR+15110000

ST命令で、STR+13番地に「0」の文字コードを格納します。



15行 LAD GR2, -1, GR2

【汎用レジスタ】
GR0110000
GR10
GR21100
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13110000
STR+14110001
STR+15110000



16行 SRL GR1, 1

【汎用レジスタ】
GR0110000
GR10
GR21100
GR30

【フラグレジスタ】
ZFSFOF
100

STR+0
::
STR+12
STR+13110000
STR+14110001
STR+15110000

GR1の値が0になるためフラグレジスタに変化はありません。



17行 CPA GR2, =0

【汎用レジスタ】
GR0110000
GR10
GR21100
GR30

【フラグレジスタ】
ZFSFOF
000

STR+0
::
STR+12
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR2の値 12 と 0 を比較します。
12 > 0 なのでフラグレジスタが変化します。



18行 JPL LP
19行 JZE LP

【フラグレジスタ】
ZFSFOF
000

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行)のトレース



初期状態

【汎用レジスタ】
GR00
GR1?
GR21111
GR31

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



~1ループ目~

9行 LD GR1, STR, GR2

【汎用レジスタ】
GR00
GR1110000
GR21111
GR31

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000




10行 CPA GR1, ='0'

【汎用レジスタ】
GR00
GR1110000
GR21111
GR31

【フラグレジスタ】
ZFSFOF
100

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR1の値 「0」の文字コード と 「0」の文字コード を比較します。
(0030)16 = (0030)16 なのでフラグレジスタが変化します。



11行 JZE NX

【フラグレジスタ】
ZFSFOF
100

ZFが1なので、JZE命令で指定されたラベル「NX」に移動し13行を処理します。



13行 SLL GR3, 1

【汎用レジスタ】
GR00
GR1110000
GR21111
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

GR3の値が2になるためフラグレジスタが変化します。



14行 LAD GR2, -1, GR2

【汎用レジスタ】
GR00
GR1110000
GR21110
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



15行 CPA GR2, =0

【汎用レジスタ】
GR00
GR1110000
GR21110
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR2の値 14 と 0 を比較します。
14 > 0 なのでフラグレジスタに変化はありません。



16行 JPL LP
17行 JZE LP

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。



~2ループ目~

9行 LD GR1, STR, GR2

【汎用レジスタ】
GR00
GR1110001
GR21110
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



10行 CPA GR1, ='0'

【汎用レジスタ】
GR00
GR1110001
GR21110
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR1の値 「1」の文字コード と 「0」の文字コード を比較します。
「1」の文字コード > 「0」の文字コード なのでフラグレジスタに変化はありません。



11行 JZE NX

【フラグレジスタ】
ZFSFOF
000

ZFが0なので、JZE命令で指定されたラベル「NX」に移動せず12行を処理します。



12行 ADDA GR0, GR3

【汎用レジスタ】
GR010
GR1110001
GR21110
GR310

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

GR0の値が2になるためフラグレジスタに変化はありません。



13行 SLL GR3, 1

【汎用レジスタ】
GR010
GR1110001
GR21110
GR3100

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

GR3の値が4になるためフラグレジスタに変化はありません。



14行 LAD GR2, -1, GR2

【汎用レジスタ】
GR010
GR1110001
GR21101
GR3100

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



15行 CPA GR2, =0

【汎用レジスタ】
GR010
GR1110001
GR21101
GR3100

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR2の値 13 と 0 を比較します。
13 > 0 なのでフラグレジスタに変化はありません。



16行 JPL LP
17行 JZE LP

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。



~3ループ目~

9行 LD GR1, STR, GR2

【汎用レジスタ】
GR010
GR1110000
GR21101
GR3100

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



10行 CPA GR1, ='0'

【汎用レジスタ】
GR010
GR1110000
GR21101
GR3100

【フラグレジスタ】
ZFSFOF
100

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

CPA命令で、GR1の値 「0」の文字コード と 「0」の文字コード を比較します。
「0」の文字コード = 「0」の文字コード なのでフラグレジスタが変化します。



11行 JZE NX

【フラグレジスタ】
ZFSFOF
100

ZFが1なので、JZE命令で指定されたラベル「NX」に移動し13行を処理します。



13行 SLL GR3, 1

【汎用レジスタ】
GR010
GR1110000
GR21101
GR31000

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

GR3の値が8になるためフラグレジスタが変化します。



14行 LAD GR2, -1, GR2

【汎用レジスタ】
GR010
GR1110000
GR21100
GR31000

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000



15行 CPA GR2, =0

【汎用レジスタ】
GR010
GR1110000
GR21100
GR31000

【フラグレジスタ】
ZFSFOF
000

【メモリ】
STR+0110000
::
STR+12110000
STR+13110000
STR+14110001
STR+15110000

GR2の値が12になるためフラグレジスタに変化はありません。



16行 JPL LP
17行 JZE LP

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP」に移動し再び9行を処理します。
前行でジャンプしているので17行は処理しません。



以下、4~16ループ目ではほぼ同じ処理なので省略します。
STR+12~STR+0番地には「0」の文字コードが格納されているので、GR0に0が加算され続けるため省略します。



以上で処理が終了し、GR0に答えが格納されています。


GR0:(10)2 = 2


よって、正しい答えが格納されていますね。





最後に



今回は、2進数、2進文字列相互の変換についてでした。


それでは次回にまたご期待を!














プロフィール

ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ