Operações Lógicas Bit a Bit em Assembly NASM: AND, OR, XOR, NOT e NEG
Para a manipulação direta de bits individuais dentro de um registrador ou valor na memória, o Assembly oferece um conjunto de instruções lógicas que operam bit a bit (bitwise). Essas instruções são fundamentais para tarefas como mascaramento de bits, configurações de hardware e otimizações de baixo nível.
As instruções and, or, e xor afetam os flags de status: elas sempre zeram o Carry Flag (CF) e o Overflow Flag (OF). O Zero Flag (ZF) é ativado se o resultado da operação for zero, e o Sign Flag (SF) reflete o estado do bit mais significativo do resultado.
AND (E Lógico)
A instrução and realiza uma operação E lógico bit a bit. Um bit no resultado será 1 somente se os bits correspondentes em ambos os operandos forem 1. É comumente usada para "limpar" ou zerar bits específicos (mascaramento).
Sintaxe: and destination, source
Exemplo (Linux):
global _start
section .text
_start:
mov rdi, 12 ; rdi = 0b1100
and rdi, 6 ; rdi = rdi AND 6
; 0b1100 (12)
; & 0b0110 ( 6)
; --------
; = 0b0100 ( 4)
mov rax, 60
syscall ; Encerra com o código de status 4Exemplo Análogo para Windows:
global _start
section .text
_start:
mov rax, 12 ; rax = 0b1100
and rax, 6 ; rax = 4
retTEST (Verificação Não-Destrutiva)
A instrução test realiza a mesma operação lógica que and, mas não altera o operando de destino. Seu único propósito é ajustar os flags de status. É ideal para verificar se um ou mais bits estão ativados sem modificar o valor.
Exemplo (Linux):
global _start
section .text
_start:
mov rbx, 12
test rbx, rbx ; Testa se rbx é zero. ZF será 0, pois 12 != 0.
je is_zero ; O salto não ocorre.
mov rdi, 2 ; Este bloco é executado.
jmp exit
is_zero:
mov rdi, 8 ; Este bloco não é executado.
exit:
mov rax, 60
syscallOR (OU Lógico)
A instrução or realiza uma operação OU lógico bit a bit. Um bit no resultado será 1 se o bit correspondente em pelo menos um dos operandos for 1. É comumente usada para "ligar" ou setar bits específicos.
Sintaxe: or destination, source
Exemplo (Linux):
global _start
section .text
_start:
mov rdi, 12 ; rdi = 0b1100
or rdi, 6 ; rdi = rdi OR 6
; 0b1100 (12)
; | 0b0110 ( 6)
; --------
; = 0b1110 (14)
mov rax, 60
syscall ; Encerra com o código de status 14XOR (OU Exclusivo Lógico)
A instrução xor realiza uma operação OU Exclusivo. Um bit no resultado será 1 somente se os bits correspondentes nos dois operandos forem diferentes.
Sintaxe: xor destination, source
Exemplo (Linux):
global _start
section .text
_start:
mov rdi, 12 ; rdi = 0b1100
xor rdi, 6 ; rdi = rdi XOR 6
; 0b1100 (12)
; ^ 0b0110 ( 6)
; --------
; = 0b1010 (10)
mov rax, 60
syscall ; Encerra com o código de status 10Uso Comum de
XOR: A operaçãoxor reg, regé a forma mais eficiente de zerar um registrador.xor rdi, rdié preferível amov rdi, 0.
NOT (Negação Lógica / Complemento de Um)
A instrução not inverte todos os bits do operando: 0s se tornam 1s, e 1s se tornam 0s.
Sintaxe: not destination
Exemplo (Linux):
global _start
section .text
_start:
mov rdi, 12 ; rdi = ...0000000000001100
not rdi ; rdi agora é ...1111111111110011
mov rax, 60
syscall ; Encerra com o código de status -13O resultado ...FFF3h, se interpretado como um número com sinal, é -13.
NEG (Negação Aritmética / Complemento de Dois)
A instrução neg calcula a negação aritmética, o que é matematicamente equivalente a multiplicar o valor por -1.
Sintaxe: neg destination
Exemplo (Linux):
global _start
section .text
_start:
mov rdi, -12
neg rdi ; rdi = -(-12) = 12
mov rax, 60
syscall ; Encerra com o código de status 12Resumo
and: Realiza um E lógico bit a bit. Usada para zerar (mascarar) bits.test: Similar aand, mas apenas ajusta os flags sem modificar o destino. Usada para verificar bits.or: Realiza um OU lógico bit a bit. Usada para setar (ligar) bits.xor: Realiza um OU Exclusivo bit a bit. Usada para inverter (toggle) bits ou para zerar registradores (xor reg, reg).not: Inverte todos os bits de um operando (complemento de um).neg: Calcula a negação aritmética (complemento de dois), efetivamente multiplicando o operando por -1.