Interface Hardware-Software
Categoria de Instruções da FPU
Transferência de dados
Aritméticas
Controle
Comparações
Transcendentais
Instrução FLD (Load Floating Point)
Carrega o valor de
origem
(32,64 ou 80 bits) na pilha
– Se origem for posição de memória, valor é convertido para ponto flutuante estendido
Decrementa o TOS(bits 11, 12 e 13 do reg de status) e
posteriormente armazena a informação no registrador apontado
por TOS
fld
origem
Forma Geral
origem exemplo memória fld qword[ebp] registrador fld st1
Instrução FLD <constante>
Classe de instrução que não possui operando explícito
Carrega o valor da
constante
na pilha
– Constantes que são comuns
fld
<constante>
Forma Geral
Constante Exemplo zero fldz um fld1 pi fldpi log2 e fldl2e log2 10 fldl2t log10 2 fldlg2 loge2 fldln2
Instrução FST (Store Floating Point)
Armazena o topo da pilha (st(0)) em
destino
– Se destino for posição de memória, valor é convertido para ponto flutuante de precisão simples (32 bits) ou precisão dupla (64 bits)
fst
destino
Forma Geral
origem exemplo
memória fst dword[ebp]
registrador fst st1
Em NASM, não se coloca o índice do registrador entre parênteses
Instrução FSTP (Store Floating Point and Pop)
Armazena o topo da pilha (st(0)) em
destino
e desempilha o
topo
fstp
destino
Forma Geral
origem exemplo memória fstp dword[ebp] registrador fstp st1
Instrução FILD (Load Integer)
Carrega um inteiro (16,32 ou 64 bits) da posição de memória
origem
na pilha
– O inteiro é convertido para ponto flutuante estendido
fild
origem
Forma Geral
origem exemplo
Instrução FIST (Store Integer)
Armazena o topo da pilha (st(0)) na posição de memória
destino
– Topo da pilha é convertido para inteiro (16, 32 ou 64 bits) – Valor é arredondado segundo o campo RC do registrador de
controle da FPU
fist
destino
Forma Geral
origem exemplo
Instrução FISTP (Store Integer and Pop)
Armazena o topo da pilha (st(0)) em
destino
e desempilha o
topo
fistp
destino
Forma Geral
origem exemplo
Instrução FXCH (Exchange Register Contents)
Na primeira forma troca o conteúdo do registrador
origem
com o
conteúdo do topo da pilha
Na segunda forma, troca o conteúdo de st(1) com o topo da pilha
(st(0))
fxch
origem
Formas Gerais
origem exemplo registrador fxch st2
fxch
Categoria de Instruções da FPU
Transferência de dados
Aritméticas
Controle
Comparações
Transcendentais
Instruções Aritméticas
As 4 operações básicas (adição, subtração, multiplicação e
divisão) possuem formas que permitem um operando
explícito ou dois operandos explícitos
– Na primeira forma, o operando explícito está na memória e o
operando implícito é o st(0)
– Na segunda forma, os operandos estão nos registradores e
um deles necessariamente é o st(0)
– Exemplos: fadd, fsub, fmul, fdiv
Existem variações destas instruções na primeira forma que
trabalham com inteiros
Instruções Aritméticas com POP
As 4 operações básicas possuem também uma variação
em que a instrução finaliza com “p”, onde o topo sempre é
desempilhado (pop)
– Exemplos: faddp, fsubp, fsubrp, fdivp, fmulp
As instruções onde ocorrem o pop, possuem duas formas:
- Uma sem operando explícito, onde a operação é feita com
st(0) e st(1)
- Na outra com dois operandos explícitos, sendo eles dois
registradores e um sendo necessariamente o st(0)
Instrução FADD
Na primeira forma, adiciona o valor contido na posição de
memória
origem
a st(0), colocando o resultado em st(0)
– Se origem for inteiro, utiliza-se a instrução fiadd
Na segunda forma, adiciona o valor de
origem
a
destino
,
colocando o resultado em
destino
– Neste caso, origem e destino devem ser registradores e um deles deve ser st(0)
fadd
origem
Formas Gerais
destino, origem Exemplo
-, memória fadd dword[ebx]
st(i), st(0) fadd st1, st0 st(0), st(i) fadd st0, st2
Instrução FADDP
Na primeira forma, adiciona o valor de st(0) a st(1), colocando o
resultado em st(1) e desempilha st(0)
– st(1) vira st(0) depois da instrução
– Alguns assemblers não aceitam esta forma, neste caso deve se utilizar fadd sem operando
Na segunda forma, adiciona o valor de
st(0)
a
destino
,
colocando o resultado em
destino
e desempilhando
st(0)
Formas Gerais
destino, origem Exemplo
-, - faddp
st(i), st(0) faddp st2, st0
faddp
destino
,
st(0)
faddp
Exemplo: FADDP
section . text global _start _start: fld1 fldpi faddp mov eax, 1 mov ebx,0 int 80hExemplos de FADD e FADDP
SECTION .data x dd 1.5 y dd 2.5 SECTION .text global main main: fld dword [x] fadd dword [y]SECTION .data x dd 1.5 y dd 2.5 SECTION .text global main main: fld dword [x] fld dword [y] faddp st1,st0
Equivalentes
Exemplo: Soma e Impressão
extern printf ; a função C chamada SECTION .data msg db "soma = %.3f",0x0a,0x00 x dd 1.5 y dd 2.5 z dq 0 SECTION .text global main main: fld dword [x] fld dword [y] faddp
fst qword [z] ; armazena soma em z
Exemplo: Soma e Impressão
push dword [z+4] ; deve ser passado para printf push dword [z] ; como dois valores de 32 bits push dword msg ; endereço do formato
call printf ; Chama a função C
add esp, 12 ; ajusta pilha depois da chamada ;3*4 bytes
mov eax, 1 mov ebx, 0
Instrução FSUB
Na primeira forma, faz st(0) -
origem
(origem deve ser um
operando na memória), colocando o resultado em st(0)
– Se origem for inteiro, utiliza-se a instrução fisub
Na segunda forma, faz
destino
-
origem
, colocando o
resultado em
destino
– Neste caso, origem e destino devem ser registradores e um deles deve ser st(0)
fsub
origem
Formas Gerais
destino, origem Exemplo
-, memória fsub dword[ebx]
st(i), st(0) fsub st1, st0 st(0), st(i) fsub st0, st2
Exemplo de FSUB
SECTION .data a: dd 3.6 b: dd 4.5 SECTION . text global _start _start: fld dword[a] fld dword[b] fsub st0,st1 fst dword[a] mov eax, 1 mov ebx,0 int 80h3.6
4.5
a
b
end
end + 4
3.6
0.9
4.5
a
b
end
end + 4
fld
4.5
3.6
0.9
3.6
fld
fsub
fst
ST
ST(1)
Instrução FSUBP
Na primeira forma, faz st(1) - st(0), colocando o resultado em
st(1) e desempilha st(0)
– st(1) vira st(0) depois da instrução
– Alguns assemblers não aceitam esta forma, neste caso deve se utilizar fsub sem operando
Na segunda forma, faz
destino
–
st(0)
, colocando o resultado
em
destino
e desempilhando st(0)
Formas Gerais
destino, origem Exemplo
-, - fsubp
st(i), st(0) fsubp st2, st0
fsubp
destino
,
st(0)
fsubp
Instrução FSUBR (Reverse Subtract)
Na primeira forma, faz valor contido na posição de memória
origem
- st(0), colocando o resultado em st(0)
Na segunda forma, faz
origem
-
destino
, colocando o
resultado em
destino
– Origem e destino devem ser registradores e um deles deve ser st(0)
Existem as versões pop (
fsubrp) da segunda forma com
origem
igual a st(0) e também sem operandos explícitos
fsubr
origem
Formas Gerais
destino, origem Exemplo
-, memória fsubr dword[ebx]
st(i), st(0) fsubr st1, st0 st(0), st(i) fsubr st0, st2
Exemplo de FSUBR
SECTION .data a: dd 3.6 b: dd 4.5 SECTION . text global _start _start: fld dword[a] fld dword[b] fsubr st0,st1 fst dword[a] mov eax, 1 mov ebx,0 int 80h3.6
4.5
a
b
end
end + 4
3.6
-0.9
4.5
a
b
end
end + 4
fld
4.5
3.6
-0.9
3.6
fld
fsubr
fst
ST
ST(1)
Instrução FMUL
Na primeira forma, multiplica o valor contido na posição de
memória
origem
com st(0), colocando o resultado em st(0)
Na segunda forma, multiplica o valor de
origem
com
destino
,
colocando o resultado em
destino
– Origem e destino devem ser registradores e um deles deve ser st(0)
Existem as versões pop (
fmulp) da segunda forma com
origem
igual a st(0) e também sem operandos explícitos
fmul
origem
Formas Gerais
destino, origem Exemplo
-, memória fmul dword[ebx]
st(i), st(0) fmul st1, st0 st(0), st(i) fmul st0, st2
Exemplo: Cálculo do Volume do Cilindro
SECTION .data raio dq 2.0 altura dq 3.0 SECTION .bss vol resq 1 SECTION .text global main main: fldpi ; empilha PIfld qword[raio] ; empilha o raio
fmul st0,st0 ; calcula e empilha raio^2
fmul st0,st1; calcula e empilha PI * raio^2 fld qword[altura] ; empilha altura
fmul st0,st1 ; calcula o volume do cilindro fst qword[vol] ; armazena na memoria
mov eax,1 mov ebx,0 int 80h
Instrução FDIV
Na primeira forma, faz st(0) /
origem
, colocando o resultado
em st(0)
Na segunda forma, faz
destino
/
origem
, colocando o
resultado em
destino
– Origem e destino devem ser registradores e um deles deve ser st(0)
Existem as versões pop (
fdivp) da segunda forma com
origem
igual a st(0) e também sem operandos explícitos
fdiv
origem
Formas Gerais
destino, origem Exemplo
-, memória fdiv dword[ebx]
st(i), st(0) fdiv st1, st0 st(0), st(i) fdiv st0, st2
Instrução FDIVR (Reverse Division)
Na primeira forma, faz valor contido posição de memória
origem
/st(0), colocando o resultado em st(0)
Na segunda forma, faz
origem
/
destino
, colocando o
resultado em
destino
– Origem e destino devem ser registradores e um deles deve ser st(0)
Existem as versões pop (
fdivrp) da segunda forma com
origem
igual a st(0) e também sem operandos explícitos
fdivr
origem
Formas Gerais
destino, origem Exemplo
-, memória fdivr dword[ebx]
st(i), st(0) fdivr st1, st0 st(0), st(i) fdivr st0, st2
Outras Instruções Aritméticas
Estas instruções não possuem operandos explícitos e sempre
trabalham como o topo (st(0))
Instrução Descrição
fsqrt Calcula raiz quadrada de st(0) e coloca
resultado em st(0)
frndint Arredonda o valor de st(0) para inteiro,
conforme o registrador de controle
fabs Coloca em st(0) o valor absoluto de st(0)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
1.0
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
2.0
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
2.0
2.0
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
4.0
1.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
5.0
ST(2)
Exemplo: Cálculo da Raiz Quadrada
SECTION .data m1 dq 1.0 m2 dq 2.0 m3 dq 0.0 SECTION .text global main main: fld qword[m1] fld st0 fmulp st1,st0 fld qword[m2] fld st0 fmulp st1,st0 faddp st1,st0 fsqrt fst qword[m3] mov eax,1 mov ebx,0 int 80hST
ST(1)
2.24
ST(2)
Categoria de Instruções da FPU
Transferência de dados
Aritméticas
Controle
Comparações
Transcendentais
Instrução FSTSW (Store Status Word)
Armazena o registrador de status em
destino
– destino pode ser memória ou o registrador ax– Depois de armazenado, o status pode ser examinado pelo software
fstsw
destino
Forma Geral
origem exemplo
memória fstsw dword[ebp]
Outras Instruções de Controle
Instrução Descrição
finit “Reseta” a FPU fclex Limpa flags de erro
fstcw mem Armazena registrador de controle na posição de memória indicada por mem
fldcw mem Carrega o registrador de controle proveniente
Categoria de Instruções da FPU
Transferência de dados
Aritméticas
Controle
Comparações
Transcendentais
Instrução FCOM
Na primeira forma, compara st(0) com st(1) e atribui às flags de
status da FPU os valores correspondentes à comparação
– Existe fcomp que faz a comparação e desempilha o topo
– Existe fcompp que faz a comparação e desempilha duas vezes
Na segunda forma, compara st(0) com o valor de
origem
– Existe também o fcomp
fcom
Formas Gerais
Origem Exemplo
- fcom
Memória fcom dword[ebx] Registrador fcom st(2)
Instrução FTST
Compara st(0) com 0.0 e atribui às flags de status da FPU os
valores correspondentes à comparação
ftst
Valores Atribuídos ao Registrador de Status
Na execução de fcom/fcomp/fcompp as flags C0, C2 e C3 do
registrador de status da FPU são afetadas
Como Usar FCOM/FTST para Desvios?
Pode-se utilizar o
fcom para desvios condicionais, desde que
se armazene o registrador de status da FPU no registrador de
flags (EFLAGS) da CPU, para depois utilizar qualquer instrução
de desvio condicional
Outras Instruções de Comparação
A partir do Pentium Pro, novas instruções permitem que se faça
a comparação e automaticamente o registrador EFLAGS é
“setado”
Instrução Descrição
fcomi st,st(i) Compara st(0) com st(i) e “seta” o EFLAGS fcomip st, st(i) Compara st(0) com st(i), seta o EFLAGS, e
Categoria de Instruções da FPU
Transferência de dados
Aritméticas
Controle
Comparações
Transcendentais
Instruções Transcendentais
Implementam funções transcendentais e não possuem
operandos explícitos
Instrução Descrição
fptan Calcula a tangente do valor (em radianos) que
está no topo da pilha (st(0)), coloca o resultado no topo e depois empilha o valor 1
fpatan Calcula arco-tangente st(1)/st(0) e coloca o
resultado em st(0)
fsin Calcula o seno do valor que está em st(0) e coloca o valor em st(0)
fcos Calcula o cosseno do valor que está em st(0) e
coloca o valor em st(0)
fsincos Calcula o seno e o cosseno do valor que está em st(0), coloca o seno em st(1) e o cosseno em st(0)
fyL2x Calcula o valor de YLog2X, onde Y é st(1) e X é