PIC講習/ビット演算

概要

本章では、基本的な4つのビット演算をする命令を学びます。

重要語

マスク

特定のビットの値のみを取り出すこと

必要語

レジスタ

数値を一時記憶する回路

ビット演算

PICでは、AND、OR、XOR、NOTの基本的なビット演算を行うことができます。
Wレジスタの値と、レジスタの値または即値とを使うことができます。

COM命令

COM命令は、一般的にNOT演算と呼ばれる動作をします。
引数は1つで、レジスタの番号を指定します。
名前の由来は、1の補数One's Complementをとる演算であることです。

レジスタを用いた演算

他の3つの演算を行う命令は、それぞれAND/IOR/XORです。
IORIは、排他的論理和Exclusive ORに対して、包括的Inclusiveであることに由来します。
これらの命令は、引数の数によって動作が異なります。
まず、引数が2つある場合、1つめの引数の番号のレジスタを用いた演算とみなされます。
そのレジスタとWレジスタの値を1ビットごとに計算しますが、結果の保存先を指定できます。
2つめの引数がWならWレジスタ、Fなら一つ目の引数のレジスタに書き込みます。
なお、1つめの引数にはWレジスタも指定できます。
この場合、AND/IOR命令では何も起こらず、XOR命令では、Wレジスタがクリアされます。

即値を用いた演算

AND/IOR/XOR命令の引数が1つのみのとき、その引数は即値とみなされます。
この即値と、Wレジスタの値を計算し、結果はWレジスタに書き込まれます。
なお、即値は8ビットの値で、1ビットごとに演算が行われます。
ビット演算の例
COL.W.$09     #基幹レジスタ
COL.R.$20     #汎用レジスタ

              #実行後の値
              #レジスタR:Wレジスタ
CLR.R         #%00000000: ? ? ? ?
COM.R         #%11111111: ? ? ? ?

MOV.%11011010 #%11111111:%11011010
XOR.R.F       #%00100101:%11011010

MOV.%00110110 #%00100101:%00110110
AND.R.W       #%00100101:%00100100

IOR.%11000101 #%00100101:%11100101

XOR.%11111111 #%00100101:%00011010
COM.W         #%00100101:%11100101

XOR.W.F       #%00100101:%00000000

マスクと合成

値には、不要なビットが含まれていることがあります。
これを取り除いたり、意味のある値同士を合成して値を作る方法を紹介します。

マスク

値に対して、特定のビットを残し、他の情報をなくすことを、マスクをかけるといいます。
一般的には、AND演算で、不要な部分をすべて0にします。

合成

AND演算でマスクをかけた値は、OR演算で合成できます。
演算の相手方が0であるビットの値がそのまま残るからです。
出力の合成の例
COL.W.$09     #基幹レジスタ
COL.LATA.$0C  #特殊レジスタ
COL.A.$20     #汎用レジスタ

MOV.%11101100 #ビット3-5が意味を持つとする
MOV.A.F

MOV.%00111000 #マスク
AND.A.F

COM.W
MBS.2
AND.LATA.W    #マスク
MBS.0

IOR.A.W       #合成

MBS.2
MOV.LATA.F    #出力
MBS.0

ビット反転

ビットは、BCF/BSFで値を設定できます。
また、8ビットまとめて反転するCOM命令もあります。
しかし、1ビットのみを反転する命令はありません。
そこで、XORを用いて、特定のビットを反転させる方法があります。

Lチカのループ部分

以下に、Lチカの章のプログラムのループ部分を再掲します。
また、その次のプログラムは、XORを用いて書き換えた例です。
再掲
  COL.START     #ループ開始
    MBS.2       #バンク2
    BCF.LATB.0  #RB0ピンに0を出力する
    MBS.0
    CAL.WAITA   #1秒待つ
    MBS.2
    BSF.LATB.0  #RB0ピンに1を出力する
    MBS.0
    CAL.WAITA   #1秒待つ
    GOT.START   #戻る(無限にループする)
XORを用いた例
  COL.START     #ループ開始
    MOV.%00000001
    MBS.2       #バンク2
    XOR.LATB.F  #RB0ピンを反転する
    MBS.0
    CAL.WAITA   #1秒待つ
    GOT.START   #戻る(無限にループする)