Atualizado: 30/08/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Comparação de Dados em Assembly NASM com a Instrução CMP

Em programação Assembly, a execução de lógicas condicionais depende da comparação de operandos. A instrução cmp (compare) é o mecanismo padrão para essa finalidade. Ela compara dois operandos, ajusta os flags de status do processador com base no resultado e preserva os valores originais dos operandos.

A sintaxe da instrução é: cmp operand1, operand2

Os operandos podem ser registradores, valores na memória ou constantes (operandos imediatos), sujeitos às mesmas restrições de endereçamento de outras instruções de dois operandos (por exemplo, ambos não podem ser endereços de memória).

Mecanismo de Operação

A instrução cmp opera executando uma subtração implícita de operand1 - operand2. Os flags de status (ZF, CF, SF, OF) são atualizados como se uma instrução sub tivesse sido executada. No entanto, o resultado dessa subtração é descartado, e o valor em operand1 permanece inalterado.

O estado dos flags após cmp operand1, operand2 reflete a relação entre os dois operandos, permitindo que instruções de salto condicional subsequentes alterem o fluxo de controle do programa.

Instruções de Salto Condicional Pós-Comparação

A escolha da instrução de salto condicional correta após uma cmp é determinada pela interpretação dos dados: se são tratados como inteiros sem sinal (unsigned) ou com sinal (signed).

Saltos para Comparações Sem Sinal (Unsigned) Utilizados para dados como contadores, tamanhos de buffers ou endereços de memória. A lógica de comparação é baseada nos flags CF e ZF.

  • je (Jump if Equal): Salta se operand1 == operand2. (Verifica ZF=1).
  • jne (Jump if Not Equal): Salta se operand1 != operand2. (Verifica ZF=0).
  • ja (Jump if Above): Salta se operand1 > operand2. (Verifica CF=0 e ZF=0).
  • jb (Jump if Below): Salta se operand1 < operand2. (Verifica CF=1). É um mnemônico para jc.
  • jae (Jump if Above or Equal): Salta se operand1 >= operand2. (Verifica CF=0). É um mnemônico para jnc.
  • jbe (Jump if Below or Equal): Salta se operand1 <= operand2. (Verifica CF=1 ou ZF=1).

Saltos para Comparações Com Sinal (Signed) Utilizados para dados que podem representar valores negativos, como temperaturas ou coordenadas. A lógica de comparação é baseada nos flags SF, OF e ZF.

  • je (Jump if Equal): Salta se operand1 == operand2.
  • jne (Jump if Not Equal): Salta se operand1 != operand2.
  • jg (Jump if Greater): Salta se operand1 > operand2. (Verifica SF=OF e ZF=0).
  • jl (Jump if Less): Salta se operand1 < operand2. (Verifica SF!=OF).
  • jge (Jump if Greater or Equal): Salta se operand1 >= operand2. (Verifica SF=OF).
  • jle (Jump if Less or Equal): Salta se operand1 <= operand2. (Verifica SF!=OF ou ZF=1).

Exemplos de Implementação

Exemplo 1: Verificação de Igualdade A verificação de igualdade é idêntica para ambos os tipos de dados, pois depende exclusivamente do Zero Flag.

global _start
section .text
_start:
    mov rcx, 33
    cmp rcx, 33     ; Compara rcx com 33. ZF é setado para 1.
    je equal        ; Salto ocorre, pois ZF=1.

    mov rdi, 2      ; Código não alcançado
    jmp exit
equal:
    mov rdi, 4      ; Código executado
exit:
    mov rax, 60
    syscall

Exemplo 2: Distinção entre Comparações Unsigned e Signed O padrão de bits 0xFFFFFFFFFFFFFFFF pode ser interpretado como o maior inteiro sem sinal de 64 bits ou como -1 (em complemento de dois). A escolha da instrução de salto define o comportamento do programa.

Cenário A: Interpretação Sem Sinal (Unsigned) Aqui, o padrão de bits em rax é tratado como um número positivo muito grande.

global _start
section .text
_start:
    mov rax, -1     ; rax = 0xFFFFFFFFFFFFFFFF
    mov rbx, 5
    cmp rax, rbx

    ; Usa-se 'ja' para a comparação sem sinal.
    ja rax_is_above ; O salto ocorre, pois rax (unsigned) > rbx.

    mov rdi, 1      ; Código não alcançado
    jmp exit
rax_is_above:
    mov rdi, 100    ; Código executado.
exit:
    mov rax, 60
    syscall

Cenário B: Interpretação Com Sinal (Signed) Aqui, o mesmo padrão de bits em rax é tratado como -1.

global _start
section .text
_start:
    mov rax, -1     ; rax representa -1
    mov rbx, 5
    cmp rax, rbx

    ; Usa-se 'jl' para a comparação com sinal.
    jl rax_is_less  ; O salto ocorre, pois -1 < 5.

    mov rdi, 1      ; Código não alcançado
    jmp exit
rax_is_less:
    mov rdi, 200    ; Código executado.
exit:
    mov rax, 60
    syscall

Esses exemplos demonstram que a instrução cmp é neutra. A lógica condicional é determinada pela instrução de salto subsequente, que deve ser escolhida pelo programador de acordo com o tipo de dados sendo manipulado.


Resumo

  • A instrução cmp realiza uma subtração implícita para ajustar os flags de status (ZF, CF, SF, OF) sem modificar os operandos.
  • A escolha da instrução de salto condicional após uma cmp é fundamental e depende do contexto dos dados (com ou sem sinal).
  • Utilizam-se ja/jb (Above/Below) e suas variantes para comparações sem sinal.
  • Utilizam-se jg/jl (Greater/Less) e suas variantes para comparações com sinal.
  • je e jne são válidas para ambos os tipos de dados.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com