Instruções lógicas e de comparação
Instruções lógicas SSE
ANDP(S|D) | bitwise logical AND of Packed (Single|Double)-precision floating-point values
Faz uma operação E bit a bit (bitwise AND) em cada um dos valores float/double contidos no operando fonte e armazena o resultado no operando destino.
ANDNP(S|D) | bitwise logical AND NOT of Packed (Single|Double)-precision floating-point values
Faz uma operação NAND bit a bit em cada um dos valores float/double contidos no operando fonte e armazena o resultado no operando destino.
ORP(S|D) | bitwise logical OR of Packed (Single|Double)-precision floating-point values
Faz uma operação OU bit a bit (bitwise OR) em cada um dos valores float/double contidos no operando fonte e armazena o resultado no operando destino.
XORP(S|D) | bitwise logical XOR of Packed (Single|Double)-precision floating-point values
Faz uma operação OU Exclusivo bit a bit (bitwise eXclusive OR) em cada um dos valores float/double contidos no operando fonte e armazena o resultado no operando destino.
Instruções de comparação SSE
As instruções de comparação do SSE recebem um terceiro operando imediato de 8 bits que serve como identificador para indicar qual comparação deve ser efetuada com os valores, onde os valores válidos são de 0 até 7. Na tabela abaixo é indicado cada valor e qual operação de comparação ele representa:
Valor
Mnemônico
Descrição
0
EQ
Verifica se os valores são iguais.
1
LT
Verifica se o primeiro operando é menor que o segundo.
2
LE
Verifica se o primeiro operando é menor ou igual ao segundo.
3
UNORD
Verifica se os valores não estão ordenados.
4
NEQ
Verifica se os valores não são iguais.
5
NLT
Verifica se o primeiro operando não é menor que o segundo (ou seja, se é igual ou maior).
6
NLE
Verifica se o primeiro operando não é menor ou igual que o segundo (ou seja, se é maior).
7
ORD
Verifica se os valores estão ordenados.
Felizmente para facilitar nossa vida os assemblers, incluindo o NASM, adicionam pseudo-instruções que removem o operando imediato e, ao invés disso, usa os mnemônicos apresentados na tabela como conditional code para a instrução. Como é demonstrado no exemplo abaixo:
CMPP(S|D)/CMPccP(S|D) | Compare Packed (Single|Double)-precision floating-point values
Essa instrução compara cada um dos valores float/double contido nos dois operandos e armazena o resultado da comparação no operando fonte (o primeiro). O valor imediato passado como terceiro operando é um código numérico para identificar qual operação de comparação deve ser executada em cada um dos valores.
O resultado é armazenado como todos os bits ligados (1) caso a comparação seja verdadeira, se não todos os bits estarão desligados (0) indicando que a comparação foi falsa. Cada número float/double tem um resultado distinto no registrador destino.
CMPS(S|D)/CMPccS(S|D) | Compare Scalar (Single|Double)-precision floating-point value
Funciona da mesma forma que a instrução anterior porém comparando um único valor escalar. O resultado é armazenado no float/double menos significativo do operando fonte.
COMIS(S|D)/UCOMIS(S|D) | (Unordered) Compare Scalar (Single|Double)-precision floating-point value and set EFLAGS
As quatro instruções comparam os dois operandos escalares e definem as status flags em EFLAGS de acordo com a comparação sem modificar os operandos. Comportamento semelhante ao da instrução CMP.
Quando uma operação aritmética com números floats resulta em NaN existem dois tipos diferentes:
quiet NaN (QNaN): O valor é apenas definido para NaN sem qualquer indicação de problema.
signaling NaN (SNaN): O valor é definido para NaN e uma exceção floating-point invalid-operation (
#I
) é disparada caso você execute alguma operação com o valor.
A diferença entre COMISS/COMISD e UCOMISS/UCOMISD é que COMISS/COMISD irá disparar a exceção #I
se o primeiro operando for QNaN ou SNaN. Já UCOMISS/UCOMISD apenas dispara a exceção se o primeiro operando for SNaN.
Last updated