Atualizado: 18/10/2025

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

Extensões SSE e AVX/AVX2 em Assembly NASM

As instruções SIMD (Single Instruction, Multiple Data — “uma instrução, múltiplos dados”) representam um conjunto especial de instruções que permitem o processamento paralelo de dados. Isso significa que grupos de valores podem ser processados simultaneamente, o que aumenta o desempenho e acelera a execução do programa.

Na arquitetura x86-64, as instruções SIMD são implementadas através de extensões de diferentes gerações:

  • SSE/SSE2 (Streaming SIMD Extensions): fornecem dezesseis registradores de 128 bits (XMM0–XMM15), capazes de trabalhar com tipos inteiros e de ponto flutuante.
  • AVX/AVX2 (Advanced Vector Extensions): suportam dezesseis registradores de 256 bits (YMM0–YMM15).
  • AVX-512: amplia o conjunto para trinta e dois registradores de 512 bits (ZMM0–ZMM31).

Essas arquiteturas lidam com dois tipos principais de dados: valores escalares (números isolados) e vetores (conjuntos de valores). Os valores escalares representam inteiros ou números de ponto flutuante de precisão simples ou dupla. Os vetores contêm vários valores numéricos dispostos em sequência, variando de 2 a 32 elementos, conforme o tipo de dado e o tamanho do registrador (byte, word, dword, qword).

Os registradores XMM (XMM0–XMM15) armazenam um valor de ponto flutuante de 32 bits (float) ou quatro valores de 32 bits (vetor com 4 floats). Os registradores YMM (YMM0–YMM15) armazenam oito valores de ponto flutuante de precisão simples (32 bits cada).

Armazenamento de números de ponto flutuante de precisão simples em registradores SIMD na arquitetura x86-64

Os registradores XMM também podem conter um número de ponto flutuante de precisão dupla (.double) ou um vetor com dois números double. Os registradores YMM armazenam vetores com quatro números double.

Armazenamento de números de ponto flutuante de precisão dupla em registradores SIMD na arquitetura x86-64

Além de números de ponto flutuante, os registradores podem armazenar inteiros: o XMM contém 16 bytes, 8 words, 4 dwords ou 2 qwords, enquanto o YMM contém o dobro dessa capacidade.

Armazenamento de inteiros em registradores SIMD na arquitetura x86-64

Os elementos de um vetor também são chamados de lanes (pistas) dos registradores XMM e YMM. Por exemplo, um registrador XMM de 128 bits pode conter um vetor de 16 bytes. Os bits de 0 a 7 formam a lane 0, de 8 a 15 a lane 1, de 16 a 23 a lane 2 e assim por diante. Os bits de 120 a 127 formam a lane 15. Um registrador YMM de 256 bits possui 32 lanes de 1 byte, e um registrador ZMM de 512 bits possui 64 lanes.

De forma semelhante, um registrador XMM contém 8 lanes para o tipo word, o YMM possui 16 e o ZMM, 32. Para tipos dword ou long, o XMM possui 4 lanes, o YMM possui 8 e o ZMM possui 16.


Verificação de suporte às extensões SIMD

Os processadores diferem quanto ao suporte às extensões SIMD. Versões mais novas geralmente suportam instruções mais recentes. As extensões SSE4.2 foram lançadas em 2006, e é altamente provável que qualquer computador moderno as suporte. As extensões AVX foram apresentadas em 2008, e os primeiros processadores com suporte — a série Sandy Bridge — surgiram em 2011. As extensões AVX2 apareceram em 2013 nos processadores Haswell. As AVX-512 foram propostas em 2013 e lançadas nas famílias Xeon Phi x200 e Skylake-X entre 2015 e 2016.

A instrução cpuid permite identificar os recursos disponíveis no processador. Ela recebe um parâmetro em EAX, e o resultado é retornado em registradores como EAX, EBX, ECX e EDX, dependendo da informação solicitada.

Para verificar o suporte a extensões SIMD, define-se EAX = 1 e examina-se o conteúdo de ECX. Cada bit de ECX indica a presença de um recurso específico:

BitRecurso
0SSE3 disponível
1PCLMULQDQ disponível
9SSSE3 disponível
19SSE4.1 disponível
20SSE4.2 disponível
28AVX disponível

Exemplo de programa Linux para exibir o conteúdo de ECX em hexadecimal:

global _start

section .data
hexstr db "0x123456789ABCDEFG",10,0
len equ $-hexstr
hexmap db 48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70

section .text
_start:
    mov eax, 1
    cpuid
    mov edi, ecx
    call print_reg

    mov rax, 60
    syscall

print_reg:
    mov rbx, hexstr
    mov rsi, hexmap
    add rbx, 17
    mov rcx, 16
forloop:
    mov rax, rdi
    and rax, 0x0f
    mov al, byte [rsi + rax]
    mov byte [rbx], al
    sub rbx, 1
    shr rdi, 4
    sub rcx, 1
    jne forloop
    mov rax, 1
    mov rdi, 1
    mov rsi, hexstr
    mov rdx, len
    syscall
    ret

No exemplo acima, o valor retornado em ECX indica os recursos suportados. Por exemplo, um valor 0x00000000FEDAB223 em binário corresponde a 11111110110110101011001000100011, o que permite identificar os bits ativos e, portanto, as extensões disponíveis.

Para informações adicionais, define-se EAX = 7 e ECX = 0. Neste caso, os bits de EBX indicam o suporte a extensões mais recentes:

BitRecurso
3BMI1 (Bit Manipulation Instructions 1)
5AVX2 disponível
8BMI2 disponível

Exemplo de programa para verificar suporte a SSE4.2, AVX e AVX2:

global _start

section .data
SSE42Support equ 0x00180000
AVXSupport  equ 0x10000000
AVX2Support equ 0x20

section .text
_start:
    mov rax, 7
    xor ecx, ecx
    cpuid
    and ebx, AVX2Support
    jnz AVX2

    mov rax, 1
    cpuid
    and ecx, AVXSupport
    jnz AVX

    and ecx, SSE42Support
    jnz SSE42

    mov rdi, 40
    jmp exit
AVX2:
    mov rdi, 52
    jmp exit
AVX:
    mov rdi, 50
    jmp exit
SSE42:
    mov rdi, 42
exit:
    mov rax, 60
    syscall

Nesse código, as máscaras binárias são aplicadas aos registradores de saída da instrução cpuid para identificar a extensão presente no processador.


Registro de controle MXCSR

O SSE possui um registrador de controle e status chamado MXCSR, com 32 bits, que define o comportamento das operações de ponto flutuante e as condições de exceção.

Os primeiros 16 bits têm significados específicos:

BitNomeDescrição
0IEExceção de operação inválida
1DEExceção de denormalização
2ZEExceção de divisão por zero
3OEExceção de overflow
4UEExceção de underflow
5PEPerda de precisão
6DAZTrata valores denormalizados como zero
7–12Máscaras de exceção correspondentes (IM, DM, ZM, OM, UM, PM)
13–14Controle de arredondamento (00 = mais próximo, 01 = -∞, 10 = +∞, 11 = truncamento)
15FTZDefine underflow para zero

Os bits de 16 a 31 são reservados.

O acesso ao registrador MXCSR é feito com as instruções:

ldmxcsr mem32
stmxcsr mem32

A primeira carrega o registrador a partir de uma variável de 32 bits, enquanto a segunda armazena o seu conteúdo em memória. Essas instruções são geralmente empregadas para configurar o modo de arredondamento.


Resumo

  • As instruções SIMD permitem o processamento paralelo de dados.
  • SSE e AVX introduzem registradores XMM, YMM e ZMM com 128, 256 e 512 bits.
  • A instrução cpuid identifica quais extensões estão disponíveis no processador.
  • O registrador MXCSR controla exceções e modos de arredondamento das operações SSE.
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