métodos numéricos con assembler
DESCRIPTION
En el presente documento se describen las herramientas e ideas que hicieron posible la solución de la práctica propuesta para el curso de Arquitectura de Procesadores y Ensambladores. El cual consistía en desarrollar métodos numéricos en el lenguaje de bajo nivel Ensamblador.Se utilizó como herramienta de desarrollo para ASM FASM y los métodos numéricos que se desarrollaron son los siguientes:Método de Newton – RaphsonMétodo de SteffensenMétodo de MüllerNota: debido a la complicación del problema planteado me fue imposible terminar el trabajo, pero espero que la información recopilada pueda ser de mucha ayuda para futuros problemas que sean similares.TRANSCRIPT
Métodos Numéricos en Assembler En el presente documento se describen las herramientas e ideas que hicieron posible la solución de la práctica propuesta para el curso de Arquitectura de Procesadores y Ensambladores. El cual consistía en desarrollar métodos numéricos en el lenguaje de bajo nivel Ensamblador. Se utilizó como herramienta de desarrollo para ASM FASM y los métodos numéricos que se desarrollaron son los siguientes:_ Método de Newton – Raphson Método de Steffensen Método de Müller
2011
Juan Rodríguez 2007-14557
14/03/2011
MACROS
En esta parte se describirá cada uno de los métodos que se utilizaron en el desarrollo de la presente
práctica
imprimir Esta nos sirve para poder mostrar en pantalla lo que nosotros deseemos ya sea un mensaje, como
también un número, se hace uso de la interrupción 21h teniendo en el registro DX el mensaje a imprimir y
en AH 9h
leer Se utiliza para poder leer datos ingresados a través del teclado, utilizando de nuevo la interrupción
21h teniendo en el registro AH 1h y quedando guardado el valor en ascii de lo que leímos en el registro AL.
validar_menu Consiste en un set de instrucciones que básicamente verifican que tecla se presionó en el teclado
para seleccionar una opción a realizar.
menú Con esta se imprime en pantalla las opciones o acciones que puede realizar la aplicación
opción_N esta macros se llama al seleccionar una opción del menú mostrado, y según sea la opción
seleccionada así serán las acciones a realizar por la aplicación.
ingreso_intervalo ó ingreso_iteraciones Estas dos macros como su nombre lo indica permite el ingreso de los datos que se necesitan para
poder realizar el método numérico seleccionado, estos son guardados en variables, para luego poder
utilizar estos datos.
ingreso_polinomio Por medio del teclado se ingresan los coeficientes del polinomio, que van desde X ^5 hasta X^0. De
nuevo estos valores se guardan en variables para luego utilizarlos
derivar Con esta macro se realiza la derivada del polinomio ingresado anteriormente, se hace uso de la
formula siguiente:
coeficiente x exponente = coeficiente
exponente -1 = exponente
mostrar_derivada Con esta opción se despliega la derivada del polinomio ingresado anteriormente en la pantalla.
valuar_funcion Con esta macros se realiza la evaluación del polinomio que se ingresó, el valor por el cual se va a
valuar el polinomio se almacena en la pila en un macros anterior y luego en esta se recupera ese valor para
poder utilizarlo.
printFloat Con esta macros se realiza la impresión de números flotantes en la pantalla, mediante la obtención
primero de la parte entera y luego de la parte flotante con la siguiente formula
obtener_entero = tmp
imprimirNumero (tmp)
imprimirPuntoDecimal
flotante-entero=val
val*10^3=tmp2
obtener_entero= tmp3
imprimirNumero(tmp3)
ImprimirNumero con esta macros se muestran los numero en pantalla, ya que para poder imprimirlos en pantalla se
necesita pasar el código ascii de cada uno de ellos al registro DX, se realiza la suma de 48d a cada digito de
un número y luego pasarlo a DX para que con la macros imprimir se pueda mostrar el numero en la
pantalla.
salir Con esta macros se da por terminada la aplicación
Instrucciones Utilizadas
Etiquetas Estas son utilizadas para separar trozos de código y así poder hacer llamadas o saltos a estas
mismas Ejemplo: menú: [código]
RET Con este nemónico se retorna a la parte del código donde se encontraba luego de hacer una
llamada a una etiqueta.
MOV Con este se realiza copias de datos, o bien de registros dejando el dato o registro del que se copia
intacto y el registro al que se copia con la información del registro o dato anterior. En nuestro caso por
utilizar sintaxis de INTEL el registro o dato del lado izquierdo es el destino y el del lado derecho es del cual
se copia.
Ejemplo: MOV AX, DX MOV [val],DX MOV EAX,[val2]
CALL Con este se hace llamadas a etiquetas, o bien saltos de código.
CMP Realiza una comparación entre registros y/o datos, cambiando los valores de las flags del
procesador dependiendo del resultado. Con estas flags luego se pueden realizar saltos comparativos.
Saltos Condicionales JNE con este salto luego de utilizar CMP significa que se ira a la etiqueta si NO son iguales los datos
a comparar
JE con este salto luego de utilizar CMP significa que se ira a la etiqueta si SON iguales los datos a
comparar.
Existen muchos saltos condicionales mas pero estos fueron los utilizados para la solución de la práctica.
SUB Realiza una resta de los datos o registros que se ponen en el nemónico.
DIV Realiza una división del registro que se pone en el nemónico por el valor que se encuentra
guardado en el registro AX y el resultado se guarda en AX.
MUL Realiza una multiplicación del registro que se pone en el nemónico por el valor que se encuentra
guardado en el registro AX y el resultado se guarda en AX.
PUSH Ingresa un valor a la pila del programa
POP Recupera un valor de la pila del programa y la guarda en el registro destino
FPU Coprocesador con el cual se pueden realizar operaciones aritméticas, trigonométricas, logarítmicas;
ya sea signadas o no, con números reales o con números enteros.
FLD Ingresa un valor real a la pila del FPU, este debe de ser de tipo REAL10
FILD Ingresa un valor entero a la pila del FPU, este debe de ser de tipo REAL10
FADD Realiza la suma de valores reales de la pila del FPU, puede ir con uno o dos parámetros, las
variaciones son las siguientes
FADD st0,st1 // realiza la suma de st0 y st1 y el resultado se guarda en st0
FADD [val] // realiza una suma de la variable val y el valor de st0 y guarda el valor en st0
FADDP Realiza la suma de valores reales de la pila del FPU, y hace pop ósea descarta el valor de st0 de la
pila del FPU
FMUL Realiza la multiplicación de valores reales de la pila del FPU, puede ir con uno o dos parámetros, las
variaciones son las siguientes
FADD st0,st1 // realiza la multiplicación de st0 y st1 y el resultado se guarda en st0
FADD [val] // realiza una multiplicación de la variable val y el valor de st0 y guarda el valor en st0
FMULP Realiza la multiplicación de valores reales de la pila del FPU, y hace pop ósea descarta el valor de
st0 de la pila del FPU
FSTP Obtiene un número real de la pila del FPU en este caso sería siempre st0 es decir la parte alta de la
pila, y lo guarda en la variable de destino tipo REAL10
FSTP [val]
FIST Obtiene un número entero de la pila del FPU en este caso sería siempre st0 es decir la parte alta de
la pila, y lo guarda en la variable de destino tipo REAL10
FIST [val]
Co digo Fuente Documentado
use16
ORG 100h ; usa codigo de 16 bits
CALL menu
imprimir:
MOV AH, 9h
INT 21h
RET
; termina imprimir
leer:
MOV AH, 1
INT 21h
RET
; termina leer
validar_menu:
MOV AH, 1
INT 21h
MOV [skey],AL
CMP [skey], 49 ; opcion del menu #1
JE opcion1
CMP [skey], 50 ; opcion del menu #2
JE opcion2
CMP [skey], 51 ; opcion del menu #3
JE opcion3
CMP [skey], 52 ; opcion del menu #4
JE opcion4
CMP [skey], 53 ; opcion del menu #5
JE salir
RET
skey db ? ; variable donde se guarda lo
leido por el teclado
; termina la parte de validar_menu
menu: ; imprime el menu y espera a que se
pulse una opcion para dirigirse a ella
MOV DX, msg ; pongo lo que se quiere
imprimir en DX
CALL imprimir
CALL validar_menu ; validara la opcion
ingresada en el menu
; termina la parte que muestra el menu
opcion1:
CALL ingreso_intervalo
CALL ingreso_iteraciones
CALL ingreso_polinomio
CALL derivar
CALL mostrar_derivada
CALL metodo_newton
CALL menu
; termina opcion1
opcion2:
CALL ingreso_intervalo
CALL ingreso_iteraciones
CALL ingreso_polinomio
CALL derivar
CALL mostrar_derivada
;CALL metodo_steffensen
CALL menu
; termina opcion2
CALL menu
opcion3:
;CALL ingreso_polinomio
;CALL derivar
;CALL menu
; termina opcion3
CALL menu
opcion4:
; CALL ingreso_polinomio
;CALL derivar
;CALL menu
; termina opcion 4
CALL menu
ingreso_intervalo:
MOV DX, msg_d
CALL imprimir
CALL leer
SUB AL,48
MOV [int_d],AL
MOV DX,msg_i
CALL imprimir
CALL leer
SUB AL,48
MOV [int_i],AL
RET
msg_d db 10,13, 'Ingrese la parte derecha del
intervalo: $'
msg_i db 10,13,'Ingrese la parte izquierda del
intervalo: $'
ingreso_iteraciones:
MOV DX, msg_iter
CALL imprimir
CALL leer
SUB AL,48
MOV [iter],AL
RET
msg_iter db 10,13,'Ingrese el Numero de
Iteraciones: $'
ingreso_polinomio: ;con esta etiqueta se
realiza el ingreso del polinomio que servira
para realizar los calculos y la respectiva
grafica
MOV DX,nl
CALL imprimir
MOV DX, mp5
CALL imprimir
CALL leer
SUB AL,48
MOV [pot5],AL
MOV DX,nl
CALL imprimir
MOV DX, mp4
CALL imprimir
CALL leer
SUB AL,48
MOV [pot4],AL
MOV DX,nl
CALL imprimir
MOV DX, mp3
CALL imprimir
CALL leer
SUB AL,48
MOV [pot3],AL
MOV DX,nl
CALL imprimir
MOV DX,mp2
CALL imprimir
CALL leer
SUB AL,48
MOV [pot2],AL
MOV DX,nl
CALL imprimir
MOV DX,mp1
CALL imprimir
CALL leer
SUB AL,48
MOV [pot1],AL
MOV DX,nl
CALL imprimir
MOV DX,mp0
CALL imprimir
CALL leer
SUB AL,48
MOV [pot0],AL
RET
mp5 db "X^5 $"
mp4 db "X^4 $"
mp3 db "X^3 $"
mp2 db "X^2 $"
mp1 db "X^1 $"
mp0 db "X^0 $"
; termina la parte de ingreso de polinomio
metodo_newton:
PUSH 2d
CALL valuar_funcion
RET
xn dw 0
xn1 dw 0
derivar: ;esta etiqueta es la que realiza la
derivada de la funcion
MOV BL,[pot5]
MOV BH,0h
MOV AX,[val5]
MUL BX
MOV [p_der4],AX
MOV BL,[pot4]
MOV BH,0h
MOV AX,[val4]
MUL BX
MOV [p_der3],AX
MOV BL,[pot3]
MOV BH,0h
MOV AX,[val3]
MUL BX
MOV [p_der2],AX
MOV BL,[pot2]
MOV BH,0h
MOV AX,[val2]
MUL BX
MOV [p_der1],AX
MOV BL,[pot1]
MOV BH,0h
MOV AX,[val1]
MUL BX
MOV [p_der0],AX
RET
; TERMINA DERIVAR
valuar_funcion:
POP [valor_funcion]; obtenemos el valor
para valuar la funcion
MOV AL,[pot0]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu0]
MOV AL,[pot1]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu1]
MOV AL,[pot2]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu2]
MOV AL,[pot3]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu3]
MOV AL,[pot4]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu4]
MOV AL,[pot5]
MOVZX EAX,AL
MOV [t2],EAX
FLD [tmp]
FILD [t2]
FADDP st1,st0
FSTP [valu5]
FLD [valu0]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu0]
FLD [valu1]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu1]
FLD [valu2]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu2]
FLD [valu3]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu3]
FLD [valu4]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu4]
FLD [valu5]
FILD dword[valor_funcion]
FMULP st1,st0
FSTP [valu5]
FLD [valu0]
FLD [valu1]
FADDP st1,st0
FLD [valu2]
FADDP st1,st0
FLD [valu3]
FADDP st1,st0
FLD [valu4]
FADDP st1,st0
FLD [valu5]
FADDP st1,st0
FSTP [valor_funcion]
MOV EAX,[valor_funcion]
MOV [float],EAX
CALL printFloat
RET
tmp dd 0.0001
valor_funcion dd ?
valu5 dd 0
valu4 dd 0
t2 dd ?
valu3 dd 0
valu2 dd 0
valu1 dd 0
valu0 dd 0
valuar_derivada:
RET
valor_derivada dw 0
mostrar_derivada: ; con esta opcion se muestra
l
MOV DX,msg_der
CALL imprimir
MOV DX, nl
CALL imprimir
MOV DX, sm
CALL imprimir
MOV AX,[p_der4]
CALL ImprimirNumero
MOV DX,mp4
CALL imprimir
MOV DX,sm
CALL imprimir
MOV AX,[p_der3]
CALL ImprimirNumero
MOV DX, mp3
CALL imprimir
MOV DX,sm
CALL imprimir
MOV AX,[p_der2]
CALL ImprimirNumero
MOV DX,mp2
CALL imprimir
MOV DX,sm
CALL imprimir
MOV AX, [p_der1]
CALL ImprimirNumero
MOV DX,mp1
CALL imprimir
MOV DX,sm
CALL imprimir
MOV AX,[p_der0]
CALL ImprimirNumero
MOV DX,mp0
CALL imprimir
MOV DX,nl
CALL imprimir
RET
; TEMRINA MOSTRAR DERIVADA
printFloat: ; esta parte imprime un numero
flotante completo con punto y parte decimal
FLDCW [cw] ; cargando la palabra de
control para que trunque los numeros en lugar
de aproximarlos
FLD [float];ingreso el numero de la var
a en la stack FPU
FIST[val] ; extraigo la parte entera
del st0
MOV AX,[val]; imprimo la parte entera
CALL ImprimirNumero
MOV DX,250 ;ascii para el punto
decimal
MOV AH,02
INT 21h
FILD [val] ;st0
FSUB st1,st0 ; resto el valor entero,
para que me queden solo los decimales
FISTP [val]; eliminando de la pila el
valor ingresado
FMUL dword [valDec]; multiplico por
1000 para que me devuelba 3 decimales
FIST [val]; con esto tengo ya la parte
decimal lista para imprimir en consola
MOV AX,[val] ; mando a imprimir la
parte decimal
CALL ImprimirNumero
RET
;TERMINA PRINTFLOAT
ImprimirNumero:; esta parte del codigo imprime
el numero en pantalla, se le envia al registro
eax para que lo imprima
XOR CX,CX
MOV BX, 10d
rep1:
XOR DX,DX
DIV BX
PUSH DX
INC CX
CMP AX,0
JNZ rep1
MOV ah, 02
rep2:
POP DX
ADD DX, 48
INT 21h
DEC CX
JNZ rep2
RET
; TERMINA
;esta etiqueta es la de salida, para poder
finalizar la ejecucion del programa
salir:
INT 20h
pot0 db 0
pot1 db 0
pot2 db 0
pot3 db 0
pot4 db 0
pot5 db 0
p_der0 dw 0
p_der1 dw 0
p_der2 dw 0
p_der3 dw 0
p_der4 dw 0
val5 dw 5
val4 dw 4
val3 dw 3
val2 dw 2
val1 dw 1
msg db 10,13,'Bienvenido al menu escoja una
Opcion: ',10,13,10,13,' 1. Metodo de Newton -
Raphson ',10,13,' 2. Metodo de Steffensen
',10,13,' 3. Metodo de Muller ',10,13,' 4.
Graficar Funciones',10,13,' 5.
Salir',10,13,'$'
msg_der db 10,13,'La Derivada del Polinomio
Ingresado Es: $',10,13
float dd 22.35
valDec dd 1000.00 ;por esto multiplico la pate
flotante para mostrarla
val dw ? ;aca guardo los numeros para
imprimir
cw dw 0ffffh ; palabra de control para FP
nl db 10,13,'$'
sm db '+$'
int_d db 0
int_i db 0
iter db 0