CASL U - パリティビット |
データの誤りをチェックする手法の1つとしてパリティがある。1語のデータの1であるビットの個数をカウントして、奇数か偶数かによってパリティビットを設定する。
奇数にする奇数パリティはデータの1であるビットの個数が、奇数ならばパリティビットを0に、偶数ならばパリティビットを1にして、1であるビットの個数を奇数にする。偶数にする偶数パリティはその逆である。
1であるビットの個数 奇数 偶数 奇数パリティ 0 1 偶数パリティ 1 0
偶数パリティを求めて設定するプログラムを作成する。
データは第0ビットから第14ビットの計15ビットとし、偶数パリティを第15ビットに設定する。
(1) 1であるビットの個数のカウント
すべてのビットを調べる方法として、調べたいビットだけが1のデータを用意してAND演算を行う。結果が0出なければそのビットは1であると判定できる。第0ビットから第14ビットを調べる必要がある。
第0ビットを調べるためのデータ = 0000 0000 0000 0001(2) = #0001
第1ビットを調べるためのデータ = 0000 0000 0000 0010(2)
第2ビットを調べるためのデータ = 0000 0000 0000 0100(2)
〜 〜
第14ビットを調べるためのデータ = 0100 0000 0000 0000(2)
このように調べるデータを作りながら(#0001を1ビットずつ左シフトする)調べる方法もあるが、1であるビットをカウントする必要もあるので、元のデータを右に1ビットずつシフトして、第0ビットだけを調べるようにする。
4ビットの例
データ 第0ビット 個数 右シフト ↓
右シフト ↓
右シフト ↓
右シフト ↓0111 1 1 0011 1 2 0001 1 3 0000 0 3
右シフトしながらデータ 0000 0000 0000 0001(2) = #0001 とAND演算をすると第0ビットは表のように0または1になり、その他のビットはすべて0になる。このAND演算との結果を加算していけば個数ということになる。
(2) データが奇数か偶数かの判定
左に0〜5までを4ビットの2進数で示す。
偶数 奇数 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101
偶数と奇数のデータの第0ビットに注目してみよう。
偶数は第0ビットが0。
奇数は第0ビットが1。
というようになっている。すなわち、特別な処理(計算)をしなくても第0ビットを調べれば、偶数か奇数かを判定できる。
(3) 特定のビットを1にする
求めた偶数パリティを第15ビットに設定する必要がある。偶数パリティが0のときは何もしなくても良いが、1のときは演算が必要になる。第15ビットは1にし、そのほかのビットは元のままにしておかなければならない。
第15ビットだけを1にするには 1000 0000 0000 0000(2) = #8000 とOR演算をする。1と0または1のORは1、0と0または1のORは0または1、すなわち元のままということになる。
0000 1111 0000 1111(2)
OR 1000 0000 0000 0000(2)
1000 1111 0000 1111(2)
データはGR0の第0ビットから第14ビットに格納して副プログラムに渡し、偶数パリティを第15ビットに設定した値をGR0に格納する。手順は次の通りである。
- 1であるビットの個数カウント用のGR2を0で初期化する。
- 繰り返し回数用のGR3を15で初期化する。
- GR0の内容をGR4に退避しておく。偶数パリティを求めた後で再利用する。
- GR0の内容をGR1に記憶する。AND演算で値が変わるため保存しておく。
- GR0の第0ビットを調べる。GR0と1のAND演算。
- GR2とGR0を加算し、GR2に格納する。1であるビットの個数カウント。
- GR3から1を減じる。繰り返し回数。
- 繰り返し回数が負ならば 12. へジャンプする。負でなければ次へ。
- GR0にGR1の内容を記憶する。GR0を元(AND演算前の値)に戻す。
- GR0を1ビット右シフトする。
- 4.へジャンプする。繰り返し。
- GR0にGR4の内容を記憶する。元のデータに戻す。GR4は3.で退避したデータ。
- GR2の第0ビットを調べる。奇数か偶数かの判定。
- 偶数なら 16. へジャンプする。奇数なら次へ。
- GR0の第15ビットを1にする。GR0と#8000のOR演算。
- 呼び出し元に戻る。
MAIN1 START
LD GR0, DATA
CALL PARITY1
ST GR0, ANS
RET
DATA DC #0FF8
ANS DS 1
END
PARITY1 START
RPUSH
LAD GR2, 0 ;1. カウント用の初期化.
LAD GR3, 15 ;2. 回数用の初期化.
LD GR4, GR0 ;3. データ退避.
L1 LD GR1, GR0 ;4. データ保存.
AND GR0, B1 ;5. GR0の第0ビットを調べる.
ADDA GR2, GR0 ;6. カウント。GR2とGR0の加算.
SUBA GR3, B1 ;7. 回数の減算.
JMI L2 ;8. 終わり?
LD GR0, GR1 ;9. 保存データをGR0に戻す.
SRA GR0, 1 ;10. GR0を1ビット右シフト.
JUMP L1 ;11. L1にジャンプ.
L2 LD GR0, GR4 ;12. 退避データをGR0に戻す.
AND GR2, B1 ;13. 個数が偶数か奇数かを判定.
JZE L3 ;14. 偶数ならL3へジャンプ.
OR GR0, =#8000 ;15. GR0の第15ビットを1にする.
L3 RPOP
RET
B1 DC 1
END
プログラムで設定しているデータは #0FF8 である。2進数で 0000 1111 1111 1000(2) なので、1であるビットの個数は9個である。偶数パリティは1であるビットの個数を偶数にするものであるから1である。この偶数パリティ第15ビットに設定すると結果は 1000 1111 1111 1000(2) = #8FF8 となる。
上のプログラムでは、繰り返し回数を15回とGR3に設定しているので、必ず15回繰り返される。元のデータが#0001のときも#7FFFのときも15回繰り返す。1であるビットを調べているので、右シフトして0になれば繰り返しを終了すると、元のデータが#0001のときは1回、#7FFFのときは15回繰り返す。
プログラムを次に示す。
MAIN2 START LD GR0, DATA CALL PARITY2 ST GR0, ANS RET DATA DC #0FF8 ANS DS 1 END PARITY2 START RPUSH LAD GR2, 0 ;1. カウント用の初期化. LD GR4, GR0 ;3. データ退避. L1 LD GR1, GR0 ;4. データ保存. AND GR0, B1 ;5. GR0の第0ビットを調べる. ADDA GR2, GR0 ;6. カウント。GR2とGR0の加算. LD GR0, GR1 ;9. 保存データをGR0に戻す. SRA GR0, 1 ;10. GR0を1ビット右シフト. JNZ L1 ;0でなければL1へジャンプする。0ならば次へ. L2 LD GR0, GR4 ;12. 退避データをGR0に戻す. AND GR2, B1 ;13. 個数が偶数か奇数かを判定. JZE L3 ;14. 偶数ならL3へジャンプ. OR GR0, =#8000 ;15. GR0の第15ビットを1にする. L3 RPOP RET B1 DC 1 END
課題1 データをGR0の第0ビットから第14ビットに格納して副プログラムに渡し、奇数パリティを第15ビットに設定した値をGR0に格納する。
レジスタの値は副プログラム呼び出し前と変わらないようにすること。
CASL U | Copyright © 2003,2017 Hiroshi Masuda |