論理演算


論理積と論理和

今回は、算術演算ではなく論理演算を行ってみましょう
アセンブリでも当然、ビット単位の論理演算をサポートしています

論理積を求めるにはAND命令を
論理和を求めるにはOR命令を用います

これらの命令は、第一オペランド(ディスティネーションオペランド)と
第二オペランド(ソースオペランド)を論理演算し、その結果を第一オペランドに格納します
ディスティネーションオペランドにはレジスタ、またはメモリを指定し
ソースオペランドには、レジスタ、メモリ、または即値を指定することができます
-A 100
15F2:0100 MOV AL , 35
15F2:0102 MOV BYTE PTR [0200] , AL
15F2:0105 AND AL , 0F
15F2:0107 MOV BYTE PTR [0201] , AL
15F2:010A

-G =100 10A

AX=0005  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=010A   NV UP EI PL NZ NA PE NC

-D 200 201
15F2:0200  35 05                                             5.
これは、ニ進化十進数の性質を利用した変換プログラムです
最初にALレジスタに代入しているのは、ASCIIコードの '5' でバイナリの 5 ではありません
これを数値の5として扱うには、論理演算を利用して変換する方法が最も簡易です

C言語の講座でも似たようなことをやっていますが
この変換の応用で、アルファベットの小文字と大文字の変換も可能です

あるビットを除去するにはANDを使いますが、付加するにはORを用います
次のプログラムは、先ほどのプログラムの逆を行っています
-A 100
15F2:0100 MOV AL , 5
15F2:0102 OR AL , 30
15F2:0104 MOV BYTE PTR [0200] , AL
15F2:0107

-G =100 107

AX=0035  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0107   NV UP EI PL NZ NA PE NC

-D 200 200
15F2:0200  35                                                5


論理否定

レジスタ、またはメモリのビット列を反転する否定も可能です
論理否定はNOT命令を指定します

NOTはディスティネーションオペランドのみを指定します
第一オペランドは、レジスタまたはメモリアドレスを指定します
ただビット列を反転されるだけなので、とくに難しいこともありません
また、フラグには一切影響を与えません
-A 100
15F2:0100 MOV AL , 5A
15F2:0102 NOT AL
15F2:0104
-G =100 104

AX=00A5  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0104   NV UP EI PL NZ NA PO NC
ALレジスタの内容をNOT命令によって反転させています
ビットが反転していることが、結果からわかるでしょう


排他的論理和

最後に排他的論理和を学習しましょう
排他的論理和は、一方が1、もう一方が0の状態で1になる論理演算です
逆に、両方が0または1の状態であれば0になります

排他的論理和にはXOR命令を用います
第一オペランド(ディスティネーション・オペランド)には、レジスタまたはメモリを指定し
第二オペランド(ソース・オペランド)には、対象となるレジスタ、メモリ、または即値を指定します
二つのオペランドを排他的論理和で演算し、その結果をディスティネーションに格納します
-A 100
15F2:0100 MOV AL , FF
15F2:0102 XOR AL , CC
15F2:0104 MOV AH , AL
15F2:0106 XOR AL , CC
15F2:0108
-G =100 108

AX=33FF  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0108   NV UP EI NG NZ NA PE NC
最初にビット列 1111 1111 に 1100 1100 で論理演算を行っています
この結果 0011 0011 は、AHに格納されています
次に、同じ値 1100 1100 で再び排他的論理演算を行います
この結果は、最初の 1111 1111 に再生されます


符号の反転

8086では、数値の符号を簡単に反転させることができます
すなわち、対象の2の補数を求めることができます

符号を反転させるにはNEG命令を用います
第一オペランド(ディスティネーション・オペランド)には、対象となるレジスタまたはメモリを指定します
NEG命令は、対象の2の補数を求めディスティネーションにストアします
-A 100
15F2:0100 MOV AL , 0F
15F2:0102 NEG AL
15F2:0104
-G =100 104

AX=00F1  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0104   NV UP EI NG NZ AC PO CY
ビット列 0000 1111 の負数を求めています
0000 1111 をまず反転して1の補数にし、それに1を加算します
つまり 1111 0001 となるわけですね


結果を破棄する論理積

論理演算命令の中に、特殊な命令があります
これは、論理積を演算子結果を破棄するというものです

この命令の目的は CMP 命令と同じで、フラグをセットするためです
内容を破棄するということ以外は AND 命令と同じです
-A 100
15F2:0100 MOV AL , F0
15F2:0102 TEST AL , 00
15F2:0104
-G =100 104

AX=00F0  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=15F2  ES=15F2  SS=15F2  CS=15F2  IP=0104   NV UP EI PL ZR NA PE NC
AXレジスタの内容は変化していません
しかし、TEST命令でANDと同じ演算をしてフラグがセットされています
CFフラグはAND命令では必ず NC になりますし、TESTの結果は0なのでSFフラグもPLです



前のページへ戻る次のページへ