Atualizado: 09/11/2025

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

Comparação de Números de Ponto Flutuante em Assembly NASM

As extensões SSE incluem um conjunto de instruções que permitem comparar números de ponto flutuante de forma direta. Essas instruções verificam condições específicas e armazenam o resultado — verdadeiro (todos os bits 1) ou falso (todos os bits 0) — no primeiro operando (registrador XMM).

Principais instruções de comparação

cmpss xmm, xmm/mem32, imm8
cmpsd xmm, xmm/mem64, imm8

cmpeqss xmm, xmm/mem32       ; iguais
cmpltss xmm, xmm/mem32       ; menor que
cmpless xmm, xmm/mem32       ; menor ou igual
cmpunordss xmm, xmm/mem32    ; desordenado (um ou ambos são NaN)
cmpneqss xmm, xmm/mem32      ; diferentes
cmpnltss xmm, xmm/mem32      ; não menor
cmpnless xmm, xmm/mem32      ; não menor ou igual
cmpordss xmm, xmm/mem32      ; ordenado (nenhum é NaN)

cmpeqsd xmm, xmm/mem64       ; iguais
cmpltsd xmm, xmm/mem64       ; menor que
cmplesd xmm, xmm/mem64       ; menor ou igual
cmpunordsd xmm, xmm/mem64    ; desordenado (um ou ambos são NaN)
cmpneqsd xmm, xmm/mem64      ; diferentes
cmpnltsd xmm, xmm/mem64      ; não menor
cmpnlesd xmm, xmm/mem64      ; não menor ou igual
cmpordsd xmm, xmm/mem64      ; ordenado

As instruções cmpss e cmpsd aceitam um terceiro operando imediato (imm8) que define o tipo de comparação:

Valor (imm8)Condição de comparação
0Igual (==)
1Menor (<)
2Menor ou igual (<=)
3Desordenado (quando um ou ambos os operandos são NaN)
4Diferente ()
5Não menor (>=)
6Maior (>)
7Ordenado (nenhum é NaN)

Funcionamento

Após a comparação, o resultado (verdadeiro ou falso) é gravado em todos os bits do primeiro operando. Esse valor pode ser movido para um registrador inteiro com as instruções movq ou movd para permitir verificações com instruções condicionais.


Exemplo: comparação de igualdade (Linux)

global _start

section .data
num0 dq 3.4
num1 dq 3.4

section .text
_start:
    movsd xmm0, [num0]     ; carrega num0 em xmm0
    movsd xmm1, [num1]     ; carrega num1 em xmm1

    cmpeqsd xmm0, xmm1     ; verifica igualdade
    movq rdi, xmm0         ; transfere resultado para RDI

    mov rax, 60
    syscall

O resultado será:

  • Todos os bits 1 (valor decimal -1) - se os números forem iguais.
  • Todos os bits 0 - se forem diferentes.

Exemplo equivalente em Windows

global _start

section .data
num0 dq 3.4
num1 dq 3.4

section .text
_start:
    movsd xmm0, [rel num0]
    movsd xmm1, [rel num1]

    cmpeqsd xmm0, xmm1
    movq rax, xmm0
    ret

Uso com instruções condicionais

Após copiar o resultado para um registrador geral, é possível utilizar instruções como test e jnz (jump if not zero) para criar estruturas condicionais.

Exemplo completo em Linux

global _start

section .data
num0 dq 3.6
num1 dq 3.5

str_equal db "Equal", 10, 0
str_equal_len equ $ - str_equal

str_notequal db "Not equal", 10, 0
str_notequal_len equ $ - str_notequal

section .text
_start:
    movsd xmm0, [num0]
    movsd xmm1, [num1]

    cmpeqsd xmm0, xmm1
    movq rdi, xmm0

    test rdi, rdi          ; verifica se resultado ≠ 0
    jnz equal              ; se verdadeiro (==), salta para equal

    mov rsi, str_notequal
    mov rdx, str_notequal_len
    jmp exit

equal:
    mov rsi, str_equal
    mov rdx, str_equal_len

exit:
    mov rax, 1             ; syscall write
    mov rdi, 1             ; stdout
    syscall

    mov rax, 60
    syscall

O programa imprime “Equal” se os valores forem iguais ou “Not equal” caso contrário.


Exemplo equivalente em Windows

global _start

extern WriteFile
extern GetStdHandle

section .data
num0 dq 3.6
num1 dq 3.5

str_equal db "Equal", 10, 0
str_equal_len equ $ - str_equal

str_notequal db "Not equal", 10, 0
str_notequal_len equ $ - str_notequal

section .text
_start:
    sub rsp, 40

    movsd xmm0, [rel num0]
    movsd xmm1, [rel num1]

    cmpeqsd xmm0, xmm1
    movq rdi, xmm0

    test rdi, rdi
    jnz equal

    mov rdx, str_notequal
    mov r8d, str_notequal_len
    jmp exit

equal:
    mov rdx, str_equal
    mov r8d, str_equal_len

exit:
    mov rcx, -11
    call GetStdHandle
    mov rcx, rax
    xor r9, r9
    mov qword [rsp + 32], 0
    call WriteFile
    add rsp, 40
    ret

Observações

  • As instruções de comparação (cmp*ss, cmp*sd) retornam -1 (todos os bits 1) para verdadeiro e 0 para falso.
  • A combinação de test e jnz é uma forma prática de verificar resultados lógicos em código Assembly.
  • Comparações envolvendo NaN (Not a Number) podem gerar resultados não ordenados — nesse caso, use cmpunordss ou cmpunordsd.
  • Instruções cmpss e cmpsd com o operando imediato (imm8) permitem definir explicitamente o tipo de comparação desejada.

Resumo

  • As instruções SSE permitem comparações diretas entre números de ponto flutuante.
  • cmpeqsd / cmpeqss — igualdade.
  • cmpltsd / cmpltss — menor que.
  • cmplesd / cmpless — menor ou igual.
  • cmpneqsd / cmpneqss — diferentes.
  • cmpordsd / cmpordss — comparação ordenada (sem NaN).
  • O resultado é retornado em XMM como 0 (falso) ou -1 (verdadeiro).
  • Pode-se transferir esse valor para um registrador inteiro e criar fluxos condicionais.
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