PICBASICコンパイラ
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
まるでインタプリタ。でもコンパイラです。超カンタン超シンプルです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第23回]
●AND()、OR()、XOR()
AND(&)やOR(|)を使った論理式は[第20回]で説明をしました。
そこで説明したAND(&)やOR(|)は比較演算子によって2数を比較する式を2つつないでそれぞれの式の結果の値(真と偽、1と0)のANDとORを計算するものでした。
今回説明するAND()、OR()、XOR()は8ビットの2数をビットごとに論理演算してその結果を求めるものです。
AND()、OR()、XOR()はいずれもその結果の値をもつ8ビットの関数です。
[1]AND()
AND()の書式です。
AND(a,b)
a、bは変数、定数、式のいずれも使用できます。
AND()はI/Oポートの入力データのうち必要なビットのみを残してそれ以外をマスクするときなどによく使われます。
AND()のプログラム例です。
()内の数として変数と定数を使った例です。
AND()の結果の値は()内の2つの数のどちらも1のビットが1になりそれ以外のビットは0になります。
この例では
a =’01010101’
定数=’11110000’
なので2数をビットごとにANDの計算を行なうと
b =’01010000’
になります。
()内の数として両方とも変数にした例です。
さきほどはaの値の下位4ビットがマスクされて結果の値の上位4ビットのみがaの値と同じになりました(下位4ビットはaの値に関係なく0)。
こんどはそれとは逆に上位4ビットがマスクされた結果cの値の上位4ビットは0になり下位4ビットのみがaの下位4ビットと同じになりました。
あまり適切な例ではありませんが()内の2数として計算式を置くこともできます。
()内の第1項はa−3でこれを計算すると$52になります。
第2項はb+$10で計算すると$1Fになります。
’01010010’
’00011111’
を計算した結果は
’00010010’($12)
になります。
()内の数として2数とも定数にすることもできます(これもプログラムとしてはあまり意味はありませんが)。
3(00000011)と7(00000111)のANDですから結果は3になります。
[2]OR()
OR()の書式です。
OR(a,b)
a、bは変数、定数、式のいずれも使用できます。
a、bはAND()のところの説明と同じです。
OR()は2数のどちらかが1のビットは結果の値のビットが1になります。
2数のどちらのビットも0のときは結果の値のビットが0になります。
OR()のプログラム例です。
OR()の計算も基本的なところはAND()と同じです。
a =’01010101’
定数=’11110000’
なので2数をビットごとにORの計算を行なうと
b =’11110101’
になります。
()内の数として両方とも変数にした例です。
結果としては上の計算の上位ビットと下位ビットが入れ替わっただけです。
OR()についても()内の数に計算式、定数を使うことができますがAND()のときと同じですからその例は省略します。
[3]多重使用はできません
AND()の説明のところで()の中には数式も記述できると書きました。
ただしそれには禁則事項があります。
数式にAND()〜XOR()を含めて記述することはできません。
下はそのできないプログラム例です。
このような書き方はややこしくて間違えてしまうもとですから書かないほうがいいにきまっています。
このように書いてもエラーにはなりませんが…。
正しい計算結果にはなりません。
このような書き方に応えるためには演算の途中結果を一時的に保存するためのスタックが必要です。
しかしPICはそのスタックエリアがとても小さいのです。
PICではスタックはおもにPC(プログラムカウンタ)の退避のために使われているのでそこにデータを退避しようとするとスタックオーバーになってしまう危険があります。
通常のデータエリアをデータの一時退避のために使うことも可能ですが(実際にそのように利用しています)、ここでもともと記述しにくくわかりにくい使い方のためにそこまでするのもなんだかなあという感じがします。
何でもできるのがよいシステムだとは限りません。
制約があってこそまともなプログラムが書けるということもあります。
そこでPICBASICコンパイラではこのような多重使用はできないことに決めました。
このようにしたい場合には下のようなプログラムを書きます。
このように書いたほうがスッキリしてわかりやすいプログラムになります。
正しい結果が得られていることを順を追って確かめてみてください。
[4]XOR()
XOR()の書式です。
XOR(a,b)
a、bは変数、定数、式のいずれも使用できます。
a、bはAND()のところの説明と同じです。
XOR()はなんとも理解しにくい関数です。
Exclusive ORを意味する関数です。
排他的論理和と訳します。
そのように訳してみたってわからないことに変わりはありません。
AND()、OR()とはひと味違っていてちょっとひねくれています。
2つの数のビットが同じとき(1と1または0と0)に結果の数のビットが0になります。
2つの数のビットが異なっているとき(1と0または0と1)に結果の数のビットが1になります。
なんともたまらんなあという感じです。
XOR()のプログラム例です。
XOR()の計算も基本的なところはAND()と同じです。
a =’01010101’
定数=’11110000’
なので2数をビットごとにXORの計算を行なうと
b =’10100101’
になります。
()内の数として両方とも変数にした例です。
結果としては上の計算の上位ビットと下位ビットが入れ替わっただけです。
XORの計算では同じ数同士を計算した結果の値は必ず0になります。
たとえばXOR($55,$55)=0です。
マシン語のプログラムではこれを利用してLD A,0(2バイト必要)と書く代わりにXOR A(1バイトで済む)と書くテクニックが昔から使われてきました。
昔はメモリが貴重だったので皆1バイトを減らすことにしのぎを削っていました(今は極楽でありまする)。
そんなことをしなくてもBASICではa=0と書けばよいだけですからそのためにXOR()を使うメリットは全くありません。
[5]NOT()?
AND()、OR()、XOR()と続くとNOT()は無いのか?と思われるかもしれません。
実はNOTはXOR()を使って簡単に計算できるのでPICBASICコンパイラではNOT()関数までは用意しません。
$FFとの間でXORを実行すると結果はNOTになります。
そのプログラム例です。
$55と$FFとの間でXORを計算した結果$55の各ビットを反転した値$AAになりました(下記参照)。
$55=’01010101’
$AA=’10101010’
PICBASICコンパイラ[第23回]
2023.5.16upload
前へ
次へ
ホームページトップへ戻る