Montagem - Instruções Lógicas

O conjunto de instruções do processador fornece as instruções AND, OR, XOR, TEST e NOT lógica booleana, que testa, configura e apaga os bits de acordo com a necessidade do programa.

O formato dessas instruções -

Sr. Não. Instrução Formato
1 E AND operand1, operand2
2 OU OU operando1, operando2
3 XOR Operando 1 XOR, operando 2
4 TESTE TEST operando 1, operando 2
5 NÃO NÃO operando1

O primeiro operando em todos os casos pode estar no registro ou na memória. O segundo operando pode estar no registro / memória ou em um valor imediato (constante). No entanto, as operações de memória para memória não são possíveis. Essas instruções comparam ou combinam bits dos operandos e definem os sinalizadores CF, OF, PF, SF e ZF.

A instrução AND

A instrução AND é usada para oferecer suporte a expressões lógicas executando a operação AND bit a bit. A operação AND bit a bit retorna 1, se os bits correspondentes de ambos os operandos forem 1, caso contrário, ela retorna 0. Por exemplo -

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

A operação AND pode ser usada para limpar um ou mais bits. Por exemplo, digamos que o registrador BL contenha 0011 1010. Se você precisar limpar os bits de ordem superior para zero, faça o AND com 0FH.

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

Vamos pegar outro exemplo. Se você quiser verificar se um determinado número é ímpar ou par, um teste simples seria verificar o bit menos significativo do número. Se for 1, o número é ímpar, caso contrário, o número é par.

Supondo que o número esteja no registro AL, podemos escrever -

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

O programa a seguir ilustra isso -

Exemplo

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Even Number!

Altere o valor no registrador ax com um dígito ímpar, como -

mov  ax, 9h                  ; getting 9 in the ax

O programa exibiria:

Odd Number!

Da mesma forma, para limpar todo o registro, você pode fazer o AND com 00H.

A instrução OR

A instrução OR é usada para dar suporte à expressão lógica executando a operação OR bit a bit. O operador OR bit a bit retorna 1, se os bits correspondentes de um ou de ambos os operandos forem um. Ele retorna 0, se ambos os bits forem zero.

Por exemplo,

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

A operação OR pode ser usada para definir um ou mais bits. Por exemplo, vamos supor que o registrador AL contém 0011 1010, você precisa definir os quatro bits de ordem inferior, você pode fazer OR com um valor 0000 1111, ou seja, FH.

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

Exemplo

O exemplo a seguir demonstra a instrução OR. Vamos armazenar os valores 5 e 3 nos registradores AL e BL, respectivamente, então a instrução,

OR AL, BL

deve armazenar 7 no registro AL -

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

7

A Instrução XOR

A instrução XOR implementa a operação XOR bit a bit. A operação XOR define o bit resultante para 1, se e somente se os bits dos operandos forem diferentes. Se os bits dos operandos forem iguais (ambos 0 ou 1), o bit resultante é zerado para 0.

Por exemplo,

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

XORing um operando com ele mesmo muda o operando para 0. Isso é usado para limpar um registro.

XOR     EAX, EAX

A Instrução TEST

A instrução TEST funciona da mesma forma que a operação AND, mas ao contrário da instrução AND, ela não altera o primeiro operando. Portanto, se precisarmos verificar se um número em um registrador é par ou ímpar, também podemos fazer isso usando a instrução TEST sem alterar o número original.

TEST    AL, 01H
JZ      EVEN_NUMBER

A instrução NOT

A instrução NOT implementa a operação NOT bit a bit. A operação NOT inverte os bits em um operando. O operando pode estar em um registro ou na memória.

Por exemplo,

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