Atualizado: 09/11/2025

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

Operações Aritméticas Vetoriais com Ponto Flutuante em SSE e AVX com Assembly NASM

As extensões SSE e AVX fornecem um conjunto de instruções para realizar operações paralelas com números de ponto flutuante, que são fundamentais em computação gráfica, processamento de sinais e cálculos científicos.

O sufixo da instrução indica o tipo de dado: ps (Packed Single-precision) para float (32 bits) e pd (Packed Double-precision) para double (64 bits).

Instruções Aritméticas Básicas

  • Adição:

    • addps / vaddps: Soma vetorial de números float.
    • addpd / vaddpd: Soma vetorial de números double.
  • Subtração:

    • subps / vsubps: Subtração vetorial de float.
    • subpd / vsubpd: Subtração vetorial de double.
  • Multiplicação:

    • mulps / vmulps: Multiplicação vetorial de float.
    • mulpd / vmulpd: Multiplicação vetorial de double.
  • Divisão:

    • divps / vdivps: Divisão vetorial de float.
    • divpd / vdivpd: Divisão vetorial de double.

Mínimo e Máximo

  • maxps / vmaxps: Encontra o valor máximo entre pares de float.
  • maxpd / vmaxpd: Encontra o valor máximo entre pares de double.
  • minps / vminps: Encontra o valor mínimo entre pares de float.
  • minpd / vminpd: Encontra o valor mínimo entre pares de double.

Raiz Quadrada

  • sqrtps / vsqrtps: Calcula a raiz quadrada de cada float no vetor.
  • sqrtpd / vsqrtpd: Calcula a raiz quadrada de cada double no vetor.
  • rsqrtps / vrsqrtps: Calcula uma aproximação do inverso da raiz quadrada (1 / sqrt(x)) para cada float, uma operação muito rápida e útil em gráficos 3D para normalização de vetores.

Sintaxe das Instruções

A maioria dessas instruções segue um padrão de sintaxe similar. Exemplificando com (v)addps:

addps xmmdest, xmmsrc/mem128

vaddps xmmdest, xmmsrc1, xmmsrc2/mem128
vaddps ymmdest, ymmsrc1, ymmsrc2/mem256

As instruções de raiz quadrada, que são unárias, recebem apenas um operando de origem:

sqrtps xmmdest, xmmsrc/mem128

vsqrtps xmmdest, xmmsrc/mem128
vsqrtps ymmdest, ymmsrc/mem256

Exemplo de Adição em Ponto Flutuante

O programa a seguir para Linux demonstra a soma de dois vetores de números float de 32 bits.

global main

extern printf

section .data
    nums0 dd 1.1, 2.2, 3.3, 4.4
    nums1 dd 1.2, 2.3, 3.4, 4.5
    format_str db "%.1f, %.1f, %.1f, %.1f", 10, 0

section .text
main:
    sub rsp, 8
    movaps xmm0, [nums0]
    movaps xmm1, [nums1]
    vaddps xmm5, xmm0, xmm1  ; xmm5 = xmm0 + xmm1

    ; Extrai e exibe cada elemento do resultado
    movss xmm0, xmm5        ; Move o primeiro float para o registrador de argumento
    cvtss2sd xmm0, xmm0     ; Converte de float para double para printf
    psrldq xmm5, 4          ; Desloca para o próximo float
    movss xmm1, xmm5
    cvtss2sd xmm1, xmm1
    psrldq xmm5, 4
    movss xmm2, xmm5
    cvtss2sd xmm2, xmm2
    psrldq xmm5, 4
    movss xmm3, xmm5
    cvtss2sd xmm3, xmm3

    mov rdi, format_str
    mov rax, 4              ; Indica a printf que 4 argumentos de ponto flutuante estão nos regs XMM
    call printf

    add rsp, 8
    ret

Neste código, os vetores nums0 e nums1 são somados com vaddps, e o resultado é armazenado em xmm5. Para exibir o resultado com printf, cada elemento float é extraído de xmm5, convertido para double (pois printf espera double para o formato %f), e passado nos registradores xmm0 a xmm3.

Compilação e execução do programa:

$ nasm -f elf64 hello.asm -o hello.o
$ gcc -static hello.o -o hello
$ ./hello
2.3, 4.5, 6.7, 8.9

A seguir, a versão análoga do programa para Windows.

global main

extern printf

section .data
    nums0 dd 1.1, 2.2, 3.3, 4.4
    nums1 dd 1.2, 2.3, 3.4, 4.5
    format_str db "%.1f, %.1f, %.1f, %.1f", 10, 0

section .text
main:
    sub rsp, 40
    movaps xmm0, [rel nums0]
    movaps xmm1, [rel nums1]
    vaddps xmm5, xmm0, xmm1  ; xmm5 = xmm0 + xmm1

    ; Extrai e passa os argumentos conforme a convenção do Windows x64
    movss xmm1, xmm5
    cvtss2sd xmm1, xmm1
    movq rdx, xmm1

    psrldq xmm5, 4
    movss xmm2, xmm5
    cvtss2sd xmm2, xmm2
    movq r8, xmm2

    psrldq xmm5, 4
    movss xmm3, xmm5
    cvtss2sd xmm3, xmm3
    movq r9, xmm3

    psrldq xmm5, 4
    movss xmm4, xmm5
    cvtss2sd xmm4, xmm4
    movq qword [rsp+32], xmm4

    mov rcx, format_str
    call printf

    add rsp, 40
    ret

Resumo

  • As extensões SSE e AVX oferecem um conjunto abrangente de instruções para aritmética paralela com números de ponto flutuante de precisão simples (ps) e dupla (pd).
  • As operações incluem adição, subtração, multiplicação, divisão, mínimo/máximo e raiz quadrada.
  • O uso dessas instruções pode acelerar significativamente aplicações que dependem de cálculos matemáticos intensivos.
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