Assembly-programming-assembly-logical-instructions

提供:Dev Guides
移動先:案内検索

アセンブリ-論理命令

プロセッサの命令セットは、AND、OR、XOR、TEST、およびNOTのブール論理命令を提供し、プログラムの必要性に応じてビットをテスト、設定、およびクリアします。

これらの指示の形式-

Sr.No. Instruction Format
1 AND AND operand1, operand2
2 OR OR operand1, operand2
3 XOR XOR operand1, operand2
4 TEST TEST operand1, operand2
5 NOT NOT operand1

すべての場合の最初のオペランドは、レジスタまたはメモリのいずれかにあります。 2番目のオペランドは、レジスタ/メモリまたは即値(定数)にあります。 ただし、メモリ間操作はできません。 これらの命令は、オペランドのビットを比較または一致させ、CF、OF、PF、SF、およびZFフラグを設定します。

AND命令

AND命令は、ビット単位のAND演算を実行して論理式をサポートするために使用されます。 両方のオペランドの一致するビットが1の場合、ビット単位のAND演算は1を返します。それ以外の場合は0を返します。 たとえば-

             Operand1:  0101
             Operand2:  0011
----------------------------
After AND -> Operand1:   0001

AND演算は、1つ以上のビットをクリアするために使用できます。 たとえば、BLレジスタに0011 1010が含まれているとします。 上位ビットをゼロにクリアする必要がある場合は、0FHとANDします。

AND BL,   0FH   ; This sets BL to 0000 1010

別の例を取り上げましょう。 特定の数値が奇数か偶数かを確認する場合、簡単なテストは、数値の最下位ビットを確認することです。 これが1の場合、数値は奇数です。それ以外の場合、数値は偶数です。

番号がALレジスタにあると仮定すると、私たちは書くことができます-

AND AL, 01H     ; ANDing with 0000 0001
JZ    EVEN_NUMBER

次のプログラムはこれを示しています-

section .text
   global _start            ;must be declared for using gcc

_start:                     ;tell linker entry point
   mov   ax,   8h           ;getting 8 in the ax
   and   ax, 1              ;and ax with 1
   jz    evnn
   mov   eax, 4             ;system call number (sys_write)
   mov   ebx, 1             ;file descriptor (stdout)
   mov   ecx, odd_msg       ;message to write
   mov   edx, len2          ;length of message
   int   0x80               ;call kernel
   jmp   outprog

evnn:

   mov   ah,  09h
   mov   eax, 4             ;system call number (sys_write)
   mov   ebx, 1             ;file descriptor (stdout)
   mov   ecx, even_msg      ;message to write
   mov   edx, len1          ;length of message
   int   0x80               ;call kernel

outprog:

   mov   eax,1              ;system call number (sys_exit)
   int   0x80               ;call kernel

section   .data
even_msg  db  'Even Number!' ;message showing even number
len1  equ  $ - even_msg

odd_msg db  'Odd Number!'    ;message showing odd number
len2  equ  $ - odd_msg

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Even Number!

のように、奇数レジスタでaxレジスタの値を変更します-

mov  ax, 9h                  ; getting 9 in the ax

プログラムは以下を表示します。

Odd Number!

同様に、レジスタ全体をクリアするには、00HでANDできます。

OR命令

OR命令は、ビット単位のOR演算を実行して論理式をサポートするために使用されます。 一方または両方のオペランドの一致するビットが1である場合、ビット単位のOR演算子は1を返します。 両方のビットがゼロの場合、0を返します。

例えば、

             Operand1:     0101
             Operand2:     0011
----------------------------
After OR -> Operand1:    0111

OR演算を使用して、1つ以上のビットを設定できます。 たとえば、ALレジスタに0011 1010が含まれている場合、4つの下位ビットを設定する必要があり、値0000 1111、つまりFHとORすることができます。

OR BL, 0FH                   ; This sets BL to  0011 1111

次の例は、OR命令を示しています。 値5と3をそれぞれALレジスタとBLレジスタに保存してから、命令、

OR AL, BL

ALレジスタに7を保存する必要があります-

section .text
   global _start            ;must be declared for using gcc

_start:                     ;tell linker entry point
   mov    al, 5             ;getting 5 in the al
   mov    bl, 3             ;getting 3 in the bl
   or     al, bl            ;or al and bl registers, result should be 7
   add    al, byte '0'      ;converting decimal to ascii

   mov    [result],  al
   mov    eax, 4
   mov    ebx, 1
   mov    ecx, result
   mov    edx, 1
   int    0x80

outprog:
   mov    eax,1             ;system call number (sys_exit)
   int    0x80              ;call kernel

section    .bss
result resb 1

上記のコードをコンパイルして実行すると、次の結果が生成されます-

7

XOR命令

XOR命令は、ビット単位のXOR演算を実装します。 XOR演算は、オペランドのビットが異なる場合にのみ、結果のビットを1に設定します。 オペランドからのビットが同じ場合(両方とも0または両方1)、結果のビットは0にクリアされます。

例えば、

             Operand1:     0101
             Operand2:     0011
----------------------------
After XOR -> Operand1:    0110

オペランドとそれ自身の XORing は、オペランドを 0 に変更します。 これは、レジスタをクリアするために使用されます。

XOR     EAX, EAX

テスト命令

TEST命令はAND演算と同じように機能しますが、AND命令とは異なり、第1オペランドを変更しません。 したがって、レジスタ内の数値が偶数か奇数かを確認する必要がある場合は、元の数値を変更せずにTEST命令を使用してこれを行うこともできます。

TEST    AL, 01H
JZ      EVEN_NUMBER

NOT命令

NOT命令は、ビット単位のNOT演算を実装します。 NOT演算は、オペランドのビットを反転します。 オペランドは、レジスタまたはメモリにあります。

例えば、

             Operand1:    0101 0011
After NOT -> Operand1:    1010 1100