- 追加された行はこの色です。
- 削除された行はこの色です。
- 全ビット判定 へ行く。
*目次 [#pf124412]
#contents
*マスクと論理積を取る方法 [#me42372f]
AND演算(論理積演算)で特定のビットを取り出すことができる。
例:2進数の「10101010」と「00001111」をAND演算すると、下位4ビット分を取り出せる。
#img(http://s-akademeia.sakura.ne.jp/main/image9/and.jpg)
#img(,clear)
この取り出すために用意するデータのことを''マスク(データ)''と呼ぶ。そして、指定ビット以外を0にすることを''「マスクをかける」''と呼ぶ。
**マスクを固定し、データをシフトするアプローチ [#q7db7be6]
#img(http://s-akademeia.sakura.ne.jp/main/image9/and2.jpg)
#img(,clear)
常に最下位ビットを取り出し、1があるかどうかを調べる。
なお、ここでは右シフトする例で考えるが、もちろん左シフトでも問題ない。
***CASL兇両豺 [#t8bb412c]
例:M(DATA)に格納されているデータ「#A5F3」(=「1010 0101 1111 0011」)に含まれている1のビット数をカウントしてM(ANS)に格納するプログラムである。
#code(asm){{
SMP0411 START
LD GR1,DATA
LAD GR3,0
LOOP LD GR0,GR1
AND GR0,MASK
JZE SKIP
ADDA GR3,=1
SKIP SRL GR1,1
JNZ LOOP
ST GR3,ANS
RET
DATA DC #A5F3
MASK DC #0001
ANS DS 1
END
}}
4〜6行目で最下位ビットに1があるかどうかを調べる。もし1であれば、7行目でGR3をインクリメントする。もし1でなければ、SKIPへ飛んでインクリメントする行を飛ばす。~
8行目でデータを右シフト(論理)して、9行目でデータが0になるまで繰り返すようにループさせる。~
最終的にST命令でGR3からM(ANS)へデータをコピーする。
**マスクをシフトし、データを固定するアプローチ [#n9430814]
#img(http://s-akademeia.sakura.ne.jp/main/image9/and3.jpg)
#img(,clear)
第15ビットから第0ビットまでを順に取り出し、1があるかどうか調べる。
なお、ここでは右シフトする例で考えるが、もちろん左シフトでも問題ない。
***CASL兇両豺 [#h849f0e7]
例:M(DATA)に格納されているデータ「#A5F3」(=「1010 0101 1111 0011」)に含まれている1のビット数をカウントしてM(ANS)に格納するプログラムである。
#code(asm){{
SMP0412 START
LD GR1,DATA
LD GR2,MASK
LAD GR3,0
LOOP LD GR0,GR2
AND GR0,GR1
JZE SKIP
ADDA GR3,=1
SKIP SRL GR2,1
JNZ LOOP
ST GR3,ANS
RET
DATA DC #A5F3
MASK DC #8000
ANS DS 1
END
}}
GR1にデータ、GR2にマスクをセットする。そして一旦GR2のデータをGR0にコピーして、GR0とGR1をAND演算して結果をGR0にセットする。そのとき8行目でERがゼロならばSKIPに移動。ゼロでなければ、GR3にインクリメントする。~
9行目でGR2をひとつ分論理右シフトする。その結果10行目でERがゼロでなければLOOPへ戻る。つまり、16桁あるデータを調べるので、15回(最後の一回は戻らなくてよいため)必ずLOOPへ戻るわけである。~
すべての桁のビット判定をチェックしたら、GR3にその数がセットされているはずである。11行目でST命令でGR3からM(ANS)にコピーする。
*マスクを用いない方法 [#ze41a429]
**符号ビット利用によるアプローチ [#wf97d761]
まず、データをGR1にセットする。LD命令なので、このときFRも設定される。そこで、一旦FRのSF(サインフラグ)をチェックする。~
その後、データを左シフトして、FRのSF(サインフラグ)をチェックする。これを何度(実質15回のチェック)も繰り返して、ビット1の総数を知ることができる。
#img(http://s-akademeia.sakura.ne.jp/main/image9/nomask1.jpg)
#img(,clear)
***CASL兇両豺 [#uf0f73c7]
例:M(DATA)に格納されているデータ「#A5F3」(=「1010 0101 1111 0011」)に含まれている1のビット数をカウントしてM(ANS)に格納するプログラムである。
#code(asm){{
SMP0421 START
LAD GR3,0
LD GR1,DATA
LOOP JPL SKIP
JZE SKIP
ADDA GR3,=1
SKIP SLL GR1,1
JNZ LOOP
ST GR3,ANS
RET
DATA DC #A5F3
ANS DS 1
END
}}
**オーバーフローフラグ利用によるアプローチ [#vdb1bbc5]
データを右にシフトして、FRのOF(オーバーフローフラグ)をチェックしてビット1の総数を知ることができる。
#img(http://s-akademeia.sakura.ne.jp/main/image9/nomask2.jpg)
#img(,clear)
***CASL兇両豺 [#qd3e348e]
例:M(DATA)に格納されているデータ「#A5F3」(=「1010 0101 1111 0011」)に含まれている1のビット数をカウントしてM(ANS)に格納するプログラムである。
#code(asm){{
SMP0422 START
LAD GR3,0
LD GR1,DATA
LOOP SRL GR1,1
JOV STEP
JNZ LOOP
ST GR3,ANS
RET
STEP ADDA GR3,=1
JUMP LOOP
DATA DC #A5F3
ANS DS 1
END
}}
FRのOFが1ならGR3をインクリメントし、0なら何もしない。OF=0のときに分岐する命令があれば便利だが、CASL兇OFに関連する分岐はJOV命令((F=1のときに分岐))しかない。そこでJOV命令でSTEPにジャンプして、そこでGR3をインクリメントさせてLOOPへ戻ってこさせるように処理させている。
*参考文献 [#p1714cdc]
-『情報処理試験 CASLII 〜CASLIIの講義と実習〜 [第2版]』