Arquitectura del procesador matemático 8087

Anuncio
Arquitectura del procesador
matemático 8087
El funcionamiento del 8087 es diferente al del 8086.
Internamente tiene 8 registros de 80 bits organizados
como una pila cíclica.
Cada elemento de la pila puede almacenar un valor en
formato real temporal de 10 bytes (80bits).
El puntero de la pila (ST) indica en todo momento el
elemento en la cima. Puede valer entre 0 y 7.
Las instrucciones del 8087 pueden trabajar con datos en
memoria (ver el Ejemplo 2) o directamente con datos en
la pila (ver el Ejemplo 1). De esta forma, una instrucción
aritmética utiliza uno o dos operandos de la pila, y el
resultado se deja también en la pila.
Ejemplo 1:
finit
fild multiplicando
fild multiplicador
fmul st,st(1)
fist resultado
Ejemplo 2:
finit
fild multiplicando
fimul multiplicador
fist resultado
Todas las instrucciones del 8087 comienzan por “F”.
Si acaban por “P” quiere decir que la pila se cargará con
el resultado. Por ejemplo, FISTP VAR saca el resultado
de la cima de la pila, lo guarda en la variable en
memoria y lo quita de la pila (mueve el puntero).
Tipos de instrucciones:
•
De transferencia de datos
•
Aritméticas
•
De comparación
•
De cálculo de funciones transcendentes
•
Relativas a constantes
•
De control
Para utilizar el 8087, el 8086 debe ejecutar la instrucción
de inicialización FINIT . A continuación ya se pueden
utilizar las instrucciones del 8087 (el procesador se
ocupa en ejecutar las instrucciones máquina o pasárselas
al co-procesador matemático).
Si alguna instrucción del 8087 pudiera tardar mucho
tiempo, podemos utilizar la instrucción FWAIT para que
el 8086 espere a ejecutar la siguiente instrucción sólo
cuando el 8087 haya terminado la que está en curso (no
siempre será necesaria).
Veamos a continuación tres ejemplos de uso del coprocesador matemático 8087 para hacer cálculos
numéricos:
Ejemplo para multiplicar dos variables
Cálculo de resultado = var1 * var2
pila segment stack 'stack'
dw 100h dup (?)
pila ends
datos segment 'data'
var1 dw 7
var2 dw 3
resultado dw 0
datos ends
codigo segment 'code'
assume cs:codigo, ds:datos, ss:pila
main PROC
mov ax,datos
mov ds,ax
finit
fild var1
fimul var2
fist resultado
mov ax,resultado
call escribir_numero
mov ax,4C00h
int 21h
main ENDP
escribir_numero PROC NEAR
push ax
push dx
mov bx,10
mov dl,al
cmp ax,bx
jb escribir_resto
sub dx,dx
div bx
call escribir_numero
escribir_resto:
add dl,'0'
mov ah,2
int 21h
pop dx
pop ax
ret
escribir_numero ENDP
codigo ends
END main
Ejemplo para multiplicar y dividir
accediendo directamente a la pila
Ejemplo para calcular una raíz cuadrada
resultado = (var1 * var2) / var3
resultado = sqrt((var1 * var2) – var3)
pila segment stack 'stack'
dw 100h dup (?)
pila ends
datos segment 'data'
var1 dw 8
var2 dw 3
var3 dw 2
resultado dw 0
datos ends
codigo segment 'code'
assume cs:codigo, ds:datos, ss:pila
main PROC
mov ax,datos
mov ds,ax
finit
fild var3
fild var2
fild var1
fmul st,st(1)
fdiv st,st(2)
fist resultado
mov ax,resultado
call escribir_numero
mov ax,4C00h
int 21h
main ENDP
escribir_numero PROC NEAR
push ax
push dx
mov bx,10
mov dl,al
cmp ax,bx
jb escribir_resto
sub dx,dx
div bx
call escribir_numero
escribir_resto:
add dl,'0'
mov ah,2
int 21h
pop dx
pop ax
ret
escribir_numero ENDP
codigo ends
END main
pila segment stack 'stack'
dw 100h dup (?)
pila ends
datos segment 'data'
var1 dw 6
var2 dw 3
var3 dw 2
resultado dw 0
datos ends
codigo segment 'code'
assume cs:codigo, ds:datos, ss:pila
main PROC
mov ax,datos
mov ds,ax
finit
fild
fimul
fisub
fsqrt
fist
var1 ;cargar 6
var2 ;multip por 3
var3 ;restarle 2
;hacer la raiz cuadrada
resultado
mov ax,resultado
call escribir_numero
mov ax,4C00h
int 21h
main ENDP
escribir_numero PROC NEAR
push ax
push dx
mov bx,10
mov dl,al
cmp ax,bx
jb escribir_resto
sub dx,dx
div bx
call escribir_numero
escribir_resto:
add dl,'0'
mov ah,2
int 21h
pop dx
pop ax
ret
escribir_numero ENDP
codigo ends
END main
Descargar