Aprendendo Assembly
Doar para o autor
  • Introdução
  • Conteúdo
  • Como usar este livro
  • A base
    • Noção geral da arquitetura
    • Modos de operação
    • Sintaxe
    • Registradores de propósito geral
    • Endereçamento
    • Pilha
    • Saltos
    • Procedimentos
    • Seções e símbolos
    • Instruções assembly x86
    • Instruções do NASM
    • Pré-processador do NASM
    • Syscall no Linux
    • Olá mundo no Linux
    • Revisão
  • Aprofundando em Assembly
    • Registradores de segmento
    • CALL e RET
    • Position-independent executable
    • Atributos
    • Prefixos
    • Flags do processador
    • Instruções condicionais
    • Programando no MS-DOS
    • Interrupções de software e exceções
    • Procedimentos do BIOS
    • Usando instruções da FPU
    • Entendendo SSE
      • Instruções de movimentação de dados
      • Instruções aritméticas
      • Instruções lógicas e de comparação
      • Instruções com inteiros 128-bit
      • Instruções de conversão
  • Programando junto com C
    • Sintaxe do GAS
    • Convenção de chamada da System V ABI
    • Convenções de chamada no Windows
    • Variáveis em C
    • Funções em C
    • Ambiente hosted
    • Ambiente freestanding
    • Inline Assembly no GCC
    • Instruções intrínsecas
  • Depuração de código
    • Entendendo os depuradores
    • Depurando com o GDB
    • Depurando com o Dosbox
  • Apêndices
    • Código de máquina
      • Formato das instruções
      • Atributos e prefixos
      • Immediate
      • Displacement
      • ModR/M e SIB
      • Opcode
      • Prefixo REX
      • Codificação dos registradores
  • Metadados
    • TO DO
    • Referências
Powered by GitBook
On this page
  • ADDP(S|D) | Add Packed (Single|Double)-precision floating-point values
  • SUBP(S|D) | Subtract Packed (Single|Double)-precision floating-point values
  • ADDS(S|D) | Add Scalar (Single|Double)-precision floating-point value
  • SUBS(S|D) | Subtract Scalar (Single|Double)-precision floating-point value
  • MULP(S|D) | Multiply Packed (Single|Double)-precision floating-point values
  • MULS(S|D) | Multiply Scalar (Single|Double)-precision floating-point value
  • DIVP(S|D) | Divide Packed (Single|Double)-precision floating-point values
  • DIVS(S|D) | Divide Scalar (Single|Double)-precision floating-point value
  • RCPPS | Compute Reciprocals of Packed Single-precision floating-point values
  • RCPSS | Compute Reciprocal of Scalar Single-precision floating-point value
  • SQRTP(S|D) | Compute square roots of Packed (Single|Double)-precision floating-point values
  • SQRTS(S|D) | Compute square root of Scalar (Single|Double)-precision floating-point value
  • RSQRTPS | Compute Reciprocals of square roots of Packed Single-precision floating-point values
  • RSQRTSS | Compute Reciprocal of square root of Scalar Single-precision floating-point value
  • MAXP(S|D) | return maximum of Packed (Single|Double)-precision floating-point values
  • MAXS(S|D) | return maximum of Scalar (Single|Double)-precision floating-point value
  • MINP(S|D) | return minimum of Packed (Single|Double)-precision floating-point values
  • MINS(S|D) | return minimum of Scalar (Single|Double)-precision floating-point value

Was this helpful?

Export as PDF
  1. Aprofundando em Assembly
  2. Entendendo SSE

Instruções aritméticas

Instruções de operação aritmética do SSE.

ADDP(S|D) | Add Packed (Single|Double)-precision floating-point values

ADDPS xmm(n), xmm(n)
ADDPS xmm(n), float(4)


ADDPD xmm(n), xmm(n)
ADDPD xmm(n), double(2)

Soma 4 números float (ou 2 números double) de uma única vez no registrador destino com os quatro números float (ou 2 números double) do registrador/memória fonte. Exemplo:

#include <stdio.h>

void assembly(float *array);

int main(void)
{
  float array[4] = {5.0f, 5.0f, 5.0f, 5.0f};
  assembly(array);

  printf("Resultado: %f, %f, %f, %f\n", array[0], array[1], array[2], array[3]);
  return 0;
}
bits 64
default rel

section .rodata align=16
    sum_array: dd 1.5
               dd 2.5
               dd 3.5
               dd 4.5

section .text

global assembly
assembly:
    movaps xmm0, [rdi]
    addps xmm0, [sum_array]
    movaps [rdi], xmm0
    ret

SUBP(S|D) | Subtract Packed (Single|Double)-precision floating-point values

SUBPS xmm(n), xmm(n)
SUBPS xmm(n), float(4)


SUBPD xmm(n), xmm(n)
SUBPD xmm(n), double(2)

Funciona da mesma forma que a instrução anterior porém faz uma operação de subtração nos valores.

ADDS(S|D) | Add Scalar (Single|Double)-precision floating-point value

ADDSS xmm(n), xmm(n)
ADDSS xmm(n), float(1)


ADDSD xmm(n), xmm(n)
ADDSD xmm(n), double(1)

ADDSS faz a adição do float contido no double word (4 bytes) menos significativo do registrador XMM. Já ADDSD faz a adição do double contido na quadword (8 bytes) menos significativa do registrador.

Conforme exemplo abaixo:

#include <stdio.h>

float sum(float x, float y);

int main(void)
{
  printf("Resultado: %f\n", sum(5.0f, 1.5f));
  return 0;
}
bits 64

section .text

global sum
sum:
    addss xmm0, xmm1
    ret

SUBS(S|D) | Subtract Scalar (Single|Double)-precision floating-point value

SUBSS xmm(n), xmm(n)
SUBSS xmm(n), float(1)


SUBSD xmm(n), xmm(n)
SUBSD xmm(n), double(1)

Funciona da mesma forma que a instrução anterior porém subtraindo os valores.

MULP(S|D) | Multiply Packed (Single|Double)-precision floating-point values

MULPS xmm(n), xmm(n)
MULPS xmm(n), float(4)


MULPD xmm(n), xmm(n)
MULPD xmm(n), double(2)

Funciona como ADDPS/ADDPD porém multiplicando os números ao invés de somá-los.

MULS(S|D) | Multiply Scalar (Single|Double)-precision floating-point value

MULSS xmm(n), xmm(n)
MULSS xmm(n), float(1)


MULSD xmm(n), xmm(n)
MULSD xmm(n), double(1)

Funciona como ADDSS/ADDSD porém multiplicando os números ao invés de somá-los.

DIVP(S|D) | Divide Packed (Single|Double)-precision floating-point values

DIVPS xmm(n), xmm(n)
DIVPS xmm(n), float(4)


DIVPD xmm(n), xmm(n)
DIVPD xmm(n), double(2)

Funciona como ADDPS/ADDPD porém dividindo os números ao invés de somá-los.

DIVS(S|D) | Divide Scalar (Single|Double)-precision floating-point value

DIVSS xmm(n), xmm(n)
DIVSS xmm(n), float(1)


DIVSD xmm(n), xmm(n)
DIVSD xmm(n), double(1)

Funciona como ADDSS/ADDSD porém dividindo os números ao invés de somá-los.

RCPPS | Compute Reciprocals of Packed Single-precision floating-point values

RCPPS xmm(n), xmm(n)
RCPPS xmm(n), float(4)

RCPSS | Compute Reciprocal of Scalar Single-precision floating-point value

RCPSS xmm(n), xmm(n)
RCPSS xmm(n), float(1)

Calcula o valor aproximado do inverso multiplicativo do float no operando fonte (a direita) e armazena o resultado na double word (4 bytes) menos significativa do operando destino.

SQRTP(S|D) | Compute square roots of Packed (Single|Double)-precision floating-point values

SQRTPS xmm(n), xmm(n)
SQRTPS xmm(n), float(4)


SQRTPD xmm(n), xmm(n)
SQRTPD xmm(n), double(2)

Calcula as raízes quadradas dos números floats/doubles no operando fonte e armazena os resultados no operando destino.

SQRTS(S|D) | Compute square root of Scalar (Single|Double)-precision floating-point value

SQRTSS xmm(n), xmm(n)
SQRTSS xmm(n), float(1)


SQRTSD xmm(n), xmm(n)
SQRTSD xmm(n), double(1)

Calcula a raiz quadrada do número escalar no operando fonte e armazena o resultado no float/double menos significativo do operando destino. Exemplo:

#include <stdio.h>

double my_sqrt(double x);

int main(void)
{
  printf("Resultado: %f\n", my_sqrt(81.0));
  return 0;
}
bits 64

section .text

global my_sqrt
my_sqrt:
    sqrtsd xmm0, xmm0
    ret

RSQRTPS | Compute Reciprocals of square roots of Packed Single-precision floating-point values

RSQRTPS xmm(n), xmm(n)
RSQRTPS xmm(n), float(4)

RSQRTSS | Compute Reciprocal of square root of Scalar Single-precision floating-point value

RSQRTSS xmm(n), xmm(n)
RSQRTSS xmm(n), float(1)

Calcula o inverso multiplicativo da raiz quadrada do número escalar no operando fonte e armazena o resultado no double word menos significativo do operando destino.

MAXP(S|D) | return maximum of Packed (Single|Double)-precision floating-point values

MAXPS xmm(n), xmm(n)
MAXPS xmm(n), float(4)


MAXPD xmm(n), xmm(n)
MAXPD xmm(n), double(2)

Compara cada um dos valores contidos nos dois operandos e retorna o maior valor entre os dois.

MAXS(S|D) | return maximum of Scalar (Single|Double)-precision floating-point value

MAXSS xmm(n), xmm(n)
MAXSS xmm(n), float(1)


MAXSD xmm(n), xmm(n)
MAXSD xmm(n), double(1)

Compara os dois valores escalares e armazena o maior deles no float/double menos significativo do operando destino.

MINP(S|D) | return minimum of Packed (Single|Double)-precision floating-point values

MINPS xmm(n), xmm(n)
MINPS xmm(n), float(4)


MINPD xmm(n), xmm(n)
MINPD xmm(n), double(2)

Funciona da mesma forma que MAXPS/MAXPD porém retornando o menor valor entre cada comparação.

MINS(S|D) | return minimum of Scalar (Single|Double)-precision floating-point value

MINSS xmm(n), xmm(n)
MINSS xmm(n), float(1)


MINSD xmm(n), xmm(n)
MINSD xmm(n), double(1)

Funciona da mesma forma que MAXSS/MAXSD porém retornando o menor valor entre os dois.

PreviousInstruções de movimentação de dadosNextInstruções lógicas e de comparação

Last updated 3 years ago

Was this helpful?

Calcula o valor aproximado do dos floats no operando fonte (a direita) e armazena os valores no operando destino.

Calcula o das raízes quadradas dos floats no operando fonte, armazenando os resultados no operando destino. Essa instrução é equivalente ao uso de SQRTPS seguido de RCPPS.

inverso multiplicativo
inverso multiplicativo