Atualizado: 09/11/2025

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

Funções Matemáticas Vetoriais com SSE e AVX em Assembly NASM

As extensões SSE e AVX incluem um conjunto de instruções para realizar operações matemáticas comuns em vetores, como cálculo de média, busca por valores máximos e mínimos, e obtenção do valor absoluto.

Cálculo de Média

As instruções (v)pavgb e (v)pavgw calculam a média aritmética dos elementos correspondentes de dois vetores.

pavgb xmmdest, xmmsrc/mem128
vpavgb xmmdest, xmmsrc1, xmmsrc2/mem128
vpavgb ymmdest, ymmsrc1, ymmsrc2/mem256

pavgw xmmdest, xmmsrc/mem128
vpavgw xmmdest, xmmsrc1, xmmsrc2/mem128
vpavgw ymmdest, ymmsrc1, ymmsrc2/mem256

A instrução (v)pavgb opera em bytes, calculando a média para cada par de bytes nas 16 pistas (para 128 bits) ou 32 pistas (para 256 bits). De forma análoga, (v)pavgw opera em words (16 bits) em 8 ou 16 pistas.

Se a soma dos dois valores for ímpar, o resultado é arredondado para cima. Matematicamente, a operação é (a + b + 1) / 2.

O exemplo a seguir para Linux demonstra o cálculo da média.

global main

extern printf

section .data
    nums0 dw 3, 4, 6, 7
    nums1 dw 2, 3, 4, 5
    format_str db "%d, %d, %d, %d", 10, 0

section .text
main:
    sub rsp, 8

    movaps xmm0, [nums0]
    movaps xmm1, [nums1]
    pavgw xmm0, xmm1       ; XMM0 = (XMM0 + XMM1 + 1) / 2
    ; Resultado em XMM0: [3, 4, 5, 6]
    ; (3+2+1)/2=3, (4+3+1)/2=4, (6+4)/2=5, (7+5)/2=6

    ; Exibe os dados no console
    movd esi, xmm0
    psrldq xmm0, 4
    movd edx, xmm0
    psrldq xmm0, 4
    movd ecx, xmm0
    psrldq xmm0, 4
    movd r8d, xmm0

    mov rdi, format_str
    xor rax, rax
    call printf

    add rsp, 8
    ret

Resultado da execução:

$ nasm -f elf64 hello.asm -o hello.o
$ gcc -static hello.o -o hello
$ ./hello
3, 4, 5, 6

Valores Máximos e Mínimos

A partir do SSE4.1, foram adicionadas instruções para encontrar o valor máximo ou mínimo entre os elementos correspondentes de dois vetores.

Para encontrar o máximo:

  • (v)pmaxsb, (v)pmaxsw, (v)pmaxsd, vpmaxsq: Para inteiros com sinal de 8, 16, 32 e 64 bits.
  • (v)pmaxub, (v)pmaxuw, (v)pmaxud, vpmaxuq: Para inteiros sem sinal de 8, 16, 32 e 64 bits.

Para encontrar o mínimo:

  • (v)pminsb, (v)pminsw, (v)pminsd, vpminsq: Para inteiros com sinal.
  • (v)pminub, (v)pminuw, (v)pminud, vpminuq: Para inteiros sem sinal.

A sintaxe geral, exemplificada com (v)pmaxuw, é:

pmaxuw xmmdest, xmmsrc/mem128
vpmaxuw xmmdest, xmmsrc1, xmmsrc2/mem128
vpmaxuw ymmdest, ymmsrc1, ymmsrc2/mem256

Essas instruções comparam cada par de elementos nas pistas dos operandos e copiam o maior (ou menor) valor para a pista correspondente do registrador de destino.

O exemplo a seguir para Linux encontra os valores máximos em cada pista.

global main

extern printf

section .data
    nums0 dd 2, 3, 8, 9
    nums1 dd 4, 5, 6, 7
    format_str db "%d, %d, %d, %d", 10, 0

section .text
main:
    sub rsp, 8

    movaps xmm0, [nums0]
    movaps xmm1, [nums1]
    pmaxud xmm0, xmm1       ; Compara XMM0 e XMM1, armazena os máximos em XMM0
    ; Resultado em XMM0: [4, 5, 8, 9]

    ; Exibe os dados no console
    movd esi, xmm0
    psrldq xmm0, 4
    movd edx, xmm0
    psrldq xmm0, 4
    movd ecx, xmm0
    psrldq xmm0, 4
    movd r8d, xmm0

    mov rdi, format_str
    xor rax, rax
    call printf

    add rsp, 8
    ret

Resultado da execução:

$ nasm -f elf64 hello.asm -o hello.o
$ gcc -static hello.o -o hello
$ ./hello
4, 5, 8, 9

Valor Absoluto

As extensões SSE/AVX também fornecem instruções para calcular o valor absoluto de inteiros com sinal: (v)pabsb (bytes), (v)pabsw (words) e (v)pabsd (dwords).

A sintaxe é a seguinte:

pabsb xmmdest, xmmsrc/mem128
vpabsb xmmdest, xmmsrc/mem128
vpabsb ymmdest, ymmsrc/mem256

pabsw xmmdest, xmmsrc/mem128
vpabsw xmmdest, xmmsrc/mem128
vpabsw ymmdest, ymmsrc/mem256

pabsd xmmdest, xmmsrc/mem128
vpabsd xmmdest, xmmsrc/mem128
vpabsd ymmdest, ymmsrc/mem256

Essas instruções calculam o valor absoluto de cada elemento no operando de origem e armazenam o resultado no operando de destino. As versões SSE (pabs*) não modificam os 128 bits superiores dos registradores YMM, enquanto as versões AVX de 128 bits (vpabs*) preenchem esses bits com zeros.


Resumo

  • As instruções pavg calculam a média de elementos correspondentes em dois vetores, com arredondamento para cima.
  • As instruções pmax e pmin realizam comparações paralelas para encontrar os valores máximos ou mínimos entre dois vetores.
  • As instruções pabs calculam o valor absoluto de múltiplos inteiros com sinal de uma só vez.
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