Nuevas NORMAS para el foro

Curso Hacker
Bienvenido(a), Visitante. Favor de ingresar o registrarse.
¿Perdiste tu email de activación? - Julio 18, 2008, 11:00:04
Boton Buscar
Inicio Ayuda Ingresar Registrarse
Visita: Articulos - Juegos Gratis - Da Foros

Comunidad Underground Hispana  |  Programacion  |  Programación  |  ASM (Moderador: The Shadow)  |  Tema: [W] Calculadora de polinomios en ensamblador 0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] Ir Abajo Imprimir
Autor Tema: [W] Calculadora de polinomios en ensamblador  (Leído 111 veces)
The Shadow
Moderadores
Colaborador
*****
Desconectado Desconectado

Mensajes: 750


Fucking mnemonic c0d1n6!

shadow@el-hacker.org
Ver Perfil Email
« en: Marzo 22, 2008, 01:40:47 »

Código:
# Práctica 2: Calculadora de polinomios en ensamblador de MIPS
# Última modificación: 13 - 05 - 2002
# Líneas de código: 1055

#############################
#                           #
#       Text Segment        #
#                           #
#############################

.text
.globl menu

main: # comienzo del programa

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_intro # carga la cadena de intro
syscall # imprime la intro

li $v0, 5 # llama al servicio de leer un entero
syscall # imprime la intro

j menu # salta a mostrar el menú

menu: # muestra un menú por pantalla

la $a0, prompt_pol1 # carga el mensaje del prompt del polinomio 1
li $v0, 4 # llamada a imprimir
syscall # imprime el prompt del polinomio 1

la $a1, polinomio_1 # carga el polinomio 1 como argumento
jal mostrar_pol # salta a mostrar el polinomio

la $a0, newline # carga una salto de linea
li $v0, 4 # llamada a imprimir
syscall # imprime el salto de linea

la $a0, prompt_pol2 # carga el mensaje del prompt del polinomio 2
syscall # imprime el prompt del polinomio 2

la $a1, polinomio_2 # carga el polinomio 2 como argumento
jal mostrar_pol # salta a mostrar el polinomio

la $a0, prompt_menu # carga el mensaje del menu principal
li $v0, 4 # llamada a imprimir
syscall # imprime el menu

li $v0, 5 # llamada a leer un entero (opción)
syscall # lee el entero (opción)
move $t7, $v0 # guarda el resultado en $t7

opcion: # switch de la opción ($t7)

beq $t7, 1, intro_pol_1 # si es 1 ir a introducir polinomio 1
beq $t7, 2, intro_pol_2 # si es 2 ir a introducir polinomio 2
beq $t7, 3, s_r_op # si es 3 ir a operación de suma o resta
beq $t7, 4, s_r_op # si es 4 ir a operación de suma o resta
beq $t7, 5, multiplicar_polinomios # si es 5 ir a multiplicar polinomios
beq $t7, 6, dividir_polinomios # si es 5 ir a dividir polinomios
beq $t7, 7, funcion_pto # si es 7 calcula la función en un punto del polinomio 1
beq $t7, 8, raices # si es 8 calcula las raices del polinomio 1
beq $t7, 9, switch # si es 9 hace un switching de los polinomios
beq $t7, 10, fin # si es 10 termina el programa
j menu # si se ha pulsado una opción incorrecta se vuelve a menu



#----------------------------------- Imprimir Flotante ------------------------------------



imprimir_flotante: # imprime un número flotante con los decimales que se
# quiera

li $t0, 0 # inicializa el contador a 0

impr_flotante_loop: # imprime el término número a número

cvt.w.s $f11, $f12 # coge la parte entera del flotante y la guarda en $f11
mfc1 $a0, $f11 # carga esa parte entera como argumento

beqz $t0, primero # si es el primer número se puede imprimir con signo
abs $a0, $a0 # calcula el valor absoluto del número de la parte decimal
li $v0, 1 # llama al servicio de imprimir un entero
syscall # imprime la parte entera

seguir: # sigue imprimiendo la parte decimal

cvt.s.w $f11, $f11 # combierte la parte entera a flotante simple
sub.s $f12, $f12, $f11 # resta el flotante original menos la parte entera
li.s $f11, 10.0 # se carga 10 en $f11
mul.s $f12, $f12, $f11 # se multiplica la parte decimal por 10 para que ahora la
# parte entera corresponda con el primer decimal

beq $t0, 2, fin_bucle # se termina cuando se han mostrado 2 decimales
beqz $t0, pon_punto # si se ha mostrado la parte entera (1ª iteración)
add $t0, $t0, 1 # incrementa el contador
j impr_flotante_loop # salta a procesar el segundo decimal

pon_punto: # se imprime un punto ('.')

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, punto # carga un punto como argumento
syscall # imprime un punto

add $t0, $t0, 1 # incrementa el contador
j impr_flotante_loop # salta a procesar el primer decimal

primero: # escribe el signo en el primer término del polinomio

li.s $f1, 0.0 # carga en $f1 0.0 para hacer la comprobación
c.lt.s $f12, $f1 # comprueba si $f12 es menor que 0
bc1f positivo # si es negativo, se imprime un signo '-'

beqz $a0, pon_menos # si el número es negativo, y mayor que -1 hay que imprimir
# un signo '-'

j signo_menos_puesto # si no, imprime el número negativo directamente

pon_menos:

li $v0, 4 # llama al servicio de imprimir una cadena
move $t3, $a0 # guarda el entero en $t3
la $a0, menos # carga como argumento la cadena menos ("-")
syscall # imprime un signo negativo
move $a0, $t3 # recupera el entero

signo_menos_puesto:

j imp_pri # imprime el primer número

positivo: # si es positivo, se imprime un signo '+'

beqz $a2, imp_pri # si no queremos que se muestre la primera cifra si es
# positiva, no imprimimos el signo '+'

li $v0, 4 # llama al servicio de imprimir una cadena
move $t3, $a0 # guarda el entero en $t3
la $a0, mas # carga como argumento la cadena mas ("+")
syscall # imprime un signo positivo
move $a0, $t3 # recupera el entero

imp_pri:

li $v0, 1 # llama al servicio de imprimir un entero
syscall # imprime la parte entera

j seguir # se siguen imprimiendo los demás números (parte decimal)



#--------------------------------- Inicializar Polinomio ----------------------------------



borrar: # inicializa el polinomio

add $a0, $a0, 80 # calcula la última posición del polinomio a inicializar
li $t0, 0 # se pone el contador a 0
j borrar_loop # se inicializa el polinomio

borrar_loop: # va borrando término a término

sw $zero, ($a0) # se pone a 0 el coeficiente de la posición marcada por $a0
beq $t0, 20, fin_bucle # se salta cuando se han inicializado todos los términos
add $t0, 1 # se incrementa el contador
sub $a0, 4 # se pasa al siguiente término del polinomio
j borrar_loop # siguiente iteración (siguiente término)



#----------------------------------- Igualar Polinomios -----------------------------------



igualar: # iguala el polinomio que está en la dirección $a0 al
# polinomio que está en la dirección $a1

li $t0, 0 # inicializa el contador a 0
add $a0, 80 # calcula la última posición del polinomio de $a0
add $a1, 80 # calcula la última posición del polinomio de $a1

igualar_loop: # se va igualando término a término

l.s $f12, ($a1) # almacena el término que hay en $a1 en $f12
s.s $f12, ($a0) # guarda el término $a0
beq $t0, 20, fin_bucle # se para cuando se han igualado todos los términos
sub $a0, $a0, 4 # calcula la posición del siguiente término del polinomio
# que está en $a0
sub $a1, $a1, 4 # calcula la posición del siguiente término del polinomio
# que está en $a1
add $t0, $t0, 1 # se incrementa el contador
j igualar_loop # se iguala el siguiente término



#----------------------------------- Grado de Polinomio -----------------------------------



grado: # determina el grado de un polinomio guardado en $a0 y
# guarda el resultado en $v0

li $v0, 20 # inicializa el contador
add $a0, $a0, 80 # se pone el polinomio en la última posición

grado_loop: # comprueba el grado término a término, del mayor al menor

beq $v0, -1, fin_bucle # si el polinomio está vacío, se devuelve -1
l.s $f12, ($a0) # guarda el término que hay en $a0 en $f12
li.s $f1, 0.0 # pone el flotante en $f1 a 0
c.eq.s $f12, $f1 # comprueba si el término es 0
bc1f fin_bucle # si no es 0 sale del bucle
sub $v0, $v0, 1 # si el término no es 0 se decrementa el grado
sub $a0, $a0, 4 # y se calcula la posición del término anterior
j grado_loop # se comprueba el término anterior



#---------------------------------- Calcular Exponente ------------------------------------

exp: # calcula $f12 elevado a $a0

li.s $f0, 1.0 # cargamos $f0 a 1.0 por si el término no es 0
beqz $a1, fin_bucle # si el exponente es 0, salimos y en $f0 queda 1.0
li $t0, 1 # si no inicializamos el contador a 1
mov.s $f0, $f12 # cargamos el término en $f0

exp_loop:

beq $t0, $a1, fin_bucle # salimos cuando el contador sea igual que el exponente
mul.s $f0, $f0, $f12 # guarda la multiplicación de $f0 por $f12 en $f0
add $t0, $t0, 1 # incrementamos el contador
j exp_loop # volvemos a multiplicar



#----------------------- Algoritmo logarítmico de radicalización --------------------------



radi: # comienzo del programa

mov.s $f1, $f12 # guarda el radicando de la raíz en $f1

li.s $f0 1.0 # carga 1.0 en $f0
c.eq.s $f1, $f0 # comprueba si el flotante a radicalizar es igual que 1
bc1t inm # si es igual que 1, sale devolviendo 1

li.s $f0 0.0 # carga 0.0 en $f0
c.eq.s $f1, $f0 # comprueba si el flotante a radicalizar es igual que 0
bc1t inm # si es igual que 0, sale devolviendo 0

li.s $f0 1.0 # carga $f0 con 1.0 si el número es menor que 1
li.s $f2 2.0 # carga $f2 con 2.0
j raiz_loop # salta a calcular la raíz para un número menor que 1



# ***** CALCULAR LA RAÍZ DEL NÚMERO *****



raiz_loop: # bucle que va comprobando si un número es el que estamos
# buscando

add.s $f3, $f1, $f0 # carga en $f3 la suma de $f1 y $f0
div.s $f4, $f3, $f2 # carga en $f4 la distancia media entre $f3 y $f2

mul.s $f5, $f4, $f4 # guarda en $f5 el cuadrado de la media entre $f1 y $f0
move $t0, $a0 # carga

comprobar_indice: # si el índice es distinto de 2

beq $t0, 2, seguir_radi # cuando se haya multiplicado el posible radicando por si
# mismo tantas veces como indique el índice, se sigue el
# proceso de determinar si ese radicando es el que buscamos
mul.s $f5, $f5, $f4 # multiplica el radicando por si mismo
sub $t0, $t0, 1 # decrementa el índice
j comprobar_indice # vuelve a multiplicar el posible radicando por si mismo

seguir_radi: # continúa con la comprobación del posible radicando

c.eq.s $f5, $f12 # comprueba si el radicando elevado al índice $a0 es el que
# buscamos
bc1t encontrado # si es el que buscamos, no comprobamos mas, saltamos a
# encontrado

c.eq.s $f0, $f4 # comprobamos que no estamos comprobando el mismo número
# que el anterior (error de precisión)
bc1t encontrado # si se ha llegado al límite de precisión, el resultado
# (aproximado) es $f4
c.eq.s $f1, $f4 # comprobamos que no estamos comprobando el mismo número
# que el anterior (error de precisión)
bc1t encontrado # si se ha llegado al límite de precisión, el resultado
# (aproximado) es $f4

c.lt.s $f5, $f12 # si el posible radicando que hemos analizado elevado al
# índice es menor que $f12
bc1t menor # analizamos un número mayor
j mayor # si no, analizamos un número menor

menor: # si el término que hemos analizado es menor que el que
# estamos buscando

c.lt.s $f1, $f0 # determina si $f1 es menor que $f0
bc1t guardar_f0 # guarda el término mayor (que está en $f0)
j guardar_f1 # guarda el término mayor (que está en $f1)

mayor: # si el término que hemos analizado es mayor que el que
# estamos buscando

c.lt.s $f1, $f0 # determina si $f1 es menor que $f10
bc1t guardar_f1 # guarda el término menor (que está en $f1)
j guardar_f0 # guarda el término menor (que está en $f10)

guardar_f0: # guarda $f0

mov.s $f1, $f4 # guarda en $f1 $f4 para hacer la siguiente comprobación
j raiz_loop # comprueba el siguiente número

guardar_f1: # guarda $f1

mov.s $f0, $f4 # guarda en $f0 $f4 para hacer la siguiente comprobación
j raiz_loop # comprueba el s



# ***** RESULTADOS INMEDIATOS *****



inm: # si son raices inmediatas (0 ó 1) con cualquier índice

mov.s $f0, $f12 # carga como resultado de la raíz el radicando
j fin_bucle # termina el proceso



# ***** MOSTRAR EL RESULTADO *****



encontrado: # si ha encontrado ya la raíz, o ha encontrado un resultado
# aproximado

mov.s $f0, $f4 # carga en $f0 el resultado que estaba en $f4
j fin_bucle # termina el proceso



#----------------------------------- Mostrar Polinomio ------------------------------------



mostrar_pol: # muestra un polinomio por pantalla

li $t1, 20 # inicializa el contador a 20
add $a1, $a1, 80 # calcula la posición del último término del polinomio
li $a2, 0 # carga 0 en $a2 para que no se muestre el signo de la
# primera cifra si éste es positivo

mostrar_pol_loop: # muestra el polinomio término a término, desde el último
# hasta el primero

move $t2, $ra # guarda la dirección de quien llama a la rutina en $t2

l.s $f12, ($a1) # se guarda el coeficiente del array como argumento en $f12
li.s $f1, 0.0 # pone el flotante en $f1 a 0
c.eq.s $f12, $f1 # si el coeficiente es 0
bc1t escero # no se imprime el término

jal imprimir_flotante # imprime el flotante almacenado en $f12 por pantalla
li $a2, 1 # carga un 1 en $a2 para que ahora se muestre el signo de
# todas las cifras

li $v0, 4 # llamada a imprimir una cadena
la $a0, x # carga la cadena x ('x')
syscall # imprime una x

li $v0, 4 # llamada a imprimir una cadena
la $a0, elevado # carga la cadena elevado ('^')
syscall # imprime un signo de elevado entre la x y la potencia

li $v0, 1 # llamada a imprimir un entero
move $a0, $t1 # carga el exponente, que viene dado por el contador
syscall # imprime el exponente

escero: # si el coeficiente del término es cero, éste no se imprime

move $ra, $t2 # recupera la dirección de quien llamó a la rutina

beq $t1, 0, fin_bucle # cuando se hallan mostrado todos los términos, se acaba el
# bucle

sub $a1, $a1, 4 # accede al siguiente término del polinomio
sub $t1, $t1, 1 # decrementa el contador

j mostrar_pol_loop # analiza el siguiente término



#-------------------------------- Finalización de Procesos --------------------------------



fin_bucle: # termina un bucle que ha sido llamado por jal

jr $ra # salta a la dirección que está en $ra

fin: # fin del programa

li $v0, 10 # llama a la finalización del programa
syscall # termina el programa

resultado: # muestra por pantalla el resultado de una operación

beq $t7, 6, fin_bucle # si se había multiplicado/restado en la división, se
# vuelve a donde se estaba

li $v0, 4 # llamada a imprimir una cadena
la $a0, prompt_resul # carga la cadena prompt_resul ("\nel resultado es: ")
syscall # imprime la cadena prompt_resul

la $a1, pol_resultado # se carga el polinomio resultado en $a1
jal mostrar_pol # mostramos el resultado por pantalla

li $v0, 4 # llamada a imprimir cadena
la $a0, newline # carga un retorno de carro
syscall # imprime la nueva línea
syscall # imprime otra nueva línea

j menu # se vuelve al menu principal



#............................
#                           .
#   Introducir Polinomios   .
#                           .
#............................



intro_pol_1: # se carga el polinomio 1 para modificarlo

la $a0, polinomio_1 # carga el polinomio 1 como argumento para borrarlo
jal borrar # salta a borrar el polinomio 1
la $t0, polinomio_1 # guarda el polinomio inicializado en $t0
j intro_pol # se introduce el polinomio 1

intro_pol_2: # se carga el polinomio 2 para modificarlo

la $a0, polinomio_2 # carga el polinomio 2 como argumento para borrarlo
jal borrar # salta a borrar el polinomio 2
la $t0, polinomio_2 # guarda el polinomio inicializado en $t0

intro_pol: # permite introducir un polinomio

la $a0, intro_coef # carga el mensaje de introducir coeficiente del polinomio
li $v0, 4 # llamada a imprimir
syscall # imprime el mensaje de introducir coeficiente

li $v0, 6 # llamada a leer un flotante (coeficiente)
syscall # lee el coeficiente

li.s $f1, 0.0 # pone el flotante en $f1 a 0
c.eq.s $f0, $f1 # si se introduce un 0
bc1t menu # se dejan de introducir términos

la $a0, intro_exp # carga el mensaje de introducir exponente del polinomio
li $v0, 4 # llamada a imprimir
syscall # imprime el mensaje de introducir exponente

li $v0, 5 # llamada a leer un entero (exponente)
syscall # lee el exponente
bgt $v0, 20, novalid_ex # el exponente es no válido si es mayor de 21
bltz $v0, novalid_ex # o menor que 0
move $t2, $v0 # guarda el resultado en $t2

mul $t2, $t2, 4 # multiplica la posición por los 4 bytes de los enteros

add $t0, $t0, $t2 # mueve la posición del polinomio a la posición del
# exponente

s.s $f0, ($t0) # guarda el coeficiente en la posición del exponente

sub $t0, $t0, $t2 # se vuelve al principio del polinomio
j intro_pol # se introduce el siguiente término

novalid_ex: # si el exponente introducido no es válido (es menor que 0
# o mayor que 21)

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_novalid # carga la cadena ("\nel exponente tiene que estar entre 0
# y 21\n\n")
syscall # imprime la cadena por pantalla

j menu # vuelve al menú principal


#............................
#                           .
#  Operación de Suma/Resta  .
#                           .
#............................



s_r_op: # operación de suma/resta que guarda el resultado en
# pol_resultado

la $t0, pol_resultado # se carga en $t0 el polinomio inicializado
la $t1, polinomio_1 # carga el polinomio 1 en $t1
la $t2, polinomio_2 # carga el polinomio 2 en $t2
li $t3, 0 # inicializa el contador a 0

s_r_loop: # realiza la suma/resta de los polinomios término a término

beq $t3, 21, fin_s_r_op # se salta cuando se han sumado todos los términos
l.s $f2, ($t1) # guarda el flotante que hay en $t1 en $f2
l.s $f3, ($t2) # guarda el flotante que hay en $t2 en $f3
beq $t7, 3, suma # si hay que hacer la resta, se restan los términos

resta: # operación de resta

sub.s $f4, $f2, $f3 # resta el término del polinomio 1 menos el del polinomio 2
j s_r_loop_cnt # se siguen restando términos

suma: # operación de suma

add.s $f4, $f2, $f3 # se guarda la suma del término en $f4

s_r_loop_cnt: # continúa el bucle de suma/resta

s.s $f4, ($t0) # se guarda el resultado de la suma/resta en el polinomio
# resultado
add $t3, 1 # se incrementa el contador
add $t0, 4 # siguiente posición del polinomio resultado
add $t1, 4 # siguiente posición del polinomio 1
add $t2, 4 # siguiente posición del polinomio 2
j s_r_loop # siguiente iteración (suma del siguiente término)

fin_s_r_op: # cuando se termina la suma/resta se muestra el resultado

sub $t0, $t0, 84 # volvemos al principio del polinomio resultado
j resultado # imprimimos el resultado por pantalla



#............................
#                           .
#  Multiplicar Polinomios   .
#                           .
#............................



multiplicar_polinomios: # multiplica los polinomios y guarda el resultado en
# pol_resultado

la $a0, pol_resultado # carga el polinomio resultado como argumento para borrar
jal borrar # se inicializa el polinomio resultado
la $t0, pol_resultado # guarda el polinomio inicializado en $t0
la $t1, polinomio_1 # carga el polinomio 1 en $t1
la $t2, polinomio_2 # carga el polinomio 2 en $t2

la $a0, polinomio_1 # carga el polinomio 1 como argumento para determinar el
# grado
jal grado # calcula el grado del polinomio 1
move $t3, $v0 # guarda el grado del polinomio 1 en $t3

la $a0, polinomio_2 # carga el polinomio 2 como argumento para determinar el
# grado
jal grado # calcula el grado del polinomio 2

add $t3, $t3, $v0 # determina el grado del polinomio resultado
bgt $t3, 20, excede # si el grado del polinomio resultado excede el del espacio
# disponible no se puede realizar la multiplicación

li $t3, 0 # inicializa el contador 1 a 0
li $t4, 0 # inicializa el contador 2 a 0

mul_loop_1: # se recorre el polinomio 1, y si el término es distinto de
# 0 se pasa al segundo bucle (recorrer el polinomio 2)

beq $t3, 21, resultado # si se han multiplicado todos los términos, se sale de
# la multiplicación

l.s $f2, ($t1) # se guarda el término del polinomio 1 en $f2
li.s $f1, 0.0 # pone el flotante en $f1 a 0
c.eq.s $f2, $f1 # si el término es 0
bc1t ter1_cero # se pasa al siguiente término del polinomio 1

mul_loop_2: # y si no es 0, se pasa al bucle 2 que multiplica el
# término del polinomio 1 por todos los del polinomio 2

beq $t4, 21, fin_ter1 # si se han multiplicado todos los términos del polinomio
# 2 se multiplica el siguiente término del polinomio 1

l.s $f3, ($t2) # se guarda el término del polinomio 2 en $f3
li.s $f1, 0.0 # pone el flotante en $f1 a 0
c.eq.s $f3, $f1 # si el término es 0
bc1t fin_ter2 # se pasa al siguiente término del polinomio 2

mul.s $f4, $f2, $f3 # se multiplican los términos de los 2 polinomios y se
# guarda el resultado en $f4
add $t5, $t3, $t4 # se calcula el exponente y se guarda en $t5
mul $t5, $t5, 4 # se calculan los bytes de desplazamiento
add $t0, $t0, $t5 # mueve el polinomio resultado a donde le indica el
# exponente
l.s $f5, ($t0) # se guarda el anterior coeficiente en $t5
add.s $f4, $f4, $f5 # se calcula el nuevo coeficiente
s.s $f4, ($t0) # guarda el coeficiente en la posición que le indica el
# exponente
sub $t0, $t0, $t5 # se vuelve a apuntar al principio del polinomio resultado

fin_ter2: # si el término del polinomio 2 era 0 o ya se han terminado
# de multiplicar los términos

add $t4, 1 # se incrementa el segundo contador
add $t2, $t2, 4 # se calcula la posición del siguiente término
j mul_loop_2 # se pasa a multiplicar el siguiente término

fin_ter1: # si el término ya se ha multiplicado por todos los del
# polinomio 2

sub $t2, $t2, 84 # se vuelve a apuntar al principio del polinomio 2
li $t4, 0 # se pone el segundo contador a 0

ter1_cero: # si el término del polinomio 1 era 0 o se ha terminado
# con el término del polinomio 1

add $t1, $t1, 4 # se calcula la posición del siguiente término
add $t3, $t3, 1 # se incrementa el primer contador
j mul_loop_1 # se pasa a multiplicar el siguiente término

excede: # si el grado del polinomio resultado excede el del espacio
# disponible no se puede realizar la multiplicación

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_exceed # carga como argumento la cadena exceed ("\nel grado del
  # polinomio resultado excede de 20\n\n")
syscall # imprime la cadena

j menu # vuelve al menú principal



#............................
#                           .
#    Dividir Polinomios     .
#                           .
#............................



dividir_polinomios: # divide el polinomio 1 entre el polinomio 2 y guarda el
# cociente en pol_cociente y el resto en resta_tmp

la $a0, resta_tmp # carga resta tmp como argumento para grabar
la $a1, polinomio_1 # carga el polinomio 1 como argumento para cargar
jal igualar # copia el polinomio 1 en resta tmp

la $a0, cociente_tmp # carga cociente tmp como argumento para grabar
la $a1, polinomio_1 # carga el polinomio 1 como argumento para cargar
jal igualar # copia el polinomio 1 en cociente tmp

la $a0, pol_cociente # carga el polinomio cociente como argumento para borrarlo
jal borrar # borra el polinomio cociente

div_loop: # divide término a término del polinomio 1

la $a0, cociente_tmp # carga el cociente tmp como argumento para borrarlo
jal borrar # borra el cociente tmp

la $s4, cociente_tmp # carga el polinomio cociente temporal en $s4
la $s2, polinomio_2 # carga el polinomio 2 en $s2
la $s3, resta_tmp # carga el polinomio resta temporal en $s3
la $s1, polinomio_1 # carga el polinomio 1 en $s1
la $s0, pol_cociente # carga el polinomio cociente en $s0

la $a0, resta_tmp # carga el polinomio resta tmp como argumento
jal grado # comprueba el grado de resta tmp
move $t1, $v0 # guarda el grado de resta tmp en $t9

la $a0, polinomio_2 # carga el polinomio 2 como argumento
jal grado # comprueba el grado del polinomio 2
move $t2, $v0 # guarda el grado del polinomio 2 en $s1

blt $t1, $t2, fin_div # si el polinomio a dividir es de menor grado que el
# polinomio divisor, no se puede dividir más, y lo que
# queda en resta tmp es es resto

mul $t1, $t1, 4 # calcula los bytes de desplazamiento para llegar al
# coeficiente de mayor término de resta tmp
add $s3, $s3, $t1 # calcula la posición del término de mayor grado de resta
# tmp

mul $t2, $t2, 4 # calcula los bytes de desplazamiento para llegar al
# coeficiente de mayor término del polinomio 2
add $s2, $s2, $t2 # calcula la posición del término de mayor grado del
# polinomio 2

sub $t1, $t1, $t2 # calcula la posición en la que se tiene que guardar el
# coeficiente del polinomio cociente
add $s4, $s4, $t1 # calcula la posición donde guardar el coeficiente en el
# cociente tmp
add $s0, $s0, $t1 # calcula la posición donde guardar el coeficiente en el
# polinomio cociente

l.s $f1, ($s3) # guarda el término de mayor grado de resta tmp en $f1
l.s $f2, ($s2) # guarda el término de mayor grado del polinomio 2 en $f2
div.s $f3, $f1, $f2 # guarda su división en $f3

s.s $f3, ($s4) # guarda el término en cociente tmp
s.s $f3, ($s0) # también lo guarda en el polinomio cociente

sub $s4, $s4, $t1 # recalcula la posición del cociente tmp
sub $s2, $s2, $t2 # recalcula la posición del polinomio 2

la $a0, pol_resultado # carga el cociente tmp como argumento para borrar
jal borrar # se inicializa el polinomio resultado

la $t0, pol_resultado # carga el pol_resultado en $t0 para guardar el resultado
# de la multiplicación
la $t1, cociente_tmp # carga el cociente tmp para multiplicarlo
la $t2, polinomio_2 # por el polinomio 2
li $t3, 0 # inicializa el contador 1 a 0
li $t4, 0 # inicializa el contador 2 a 0
jal mul_loop_1 # multiplica el cociente tmp por el polinomio2

la $a0, cociente_tmp # carga resta tmp como argumento para grabar
la $a1, pol_resultado # carga el resultado de la resta como argumento para cargar
jal igualar # copia el resultado de la multiplicación en cociente tmp

la $t0, pol_resultado # carga el cociente tmp en $t0 para guardar el resultado de
# la resta
la $t1, resta_tmp # carga resta tmp en $t1
la $t2, cociente_tmp # carga cociente tmp en $t2
li $t3, 0 # inicializa el contador a 0
jal s_r_loop # resta resta tmp menos cociente tmp

la $a0, resta_tmp # carga resta tmp como argumento para grabar
la $a1, pol_resultado # carga el resultado de la resta como argumento para cargar
jal igualar # copia el resultado de la resta en resta tmp

j div_loop # vuelve a dividir hasta que el grado del resto sea menor
# que el grado del polinomio 2

fin_div: # cuando se ha terminado de dividir

li $v0, 4 # llamada a imprimir una cadena
la $a0, prompt_coc_div # carga la cadena prompt_coc_div ("\nel cociente es: ")
syscall # imprime la cadena prompt_coc_div

la $a1, pol_cociente # se carga el polinomio cociente en $a1
jal mostrar_pol # mostramos el cociente por pantalla

li $t1, 0 # inicializamos $t1 como contador para mostrar el resto
li $v0, 4 # llamada a imprimir una cadena
la $a0, prompt_res_div # carga la cadena prompt_rest_div ("\nel resto es: ")
syscall # imprime la cadena prompt_rest_div

la $a1, resta_tmp # se carga el polinomio resta_tmp en $a1
jal mostrar_pol # mostramos el resto por pantalla

li $v0, 4 # llamada a imprimir cadena
la $a0, newline # carga un retorno de carro
syscall # imprime la nueva línea
syscall # imprime otra nueva línea

j menu # se vuelve al menu principal



#............................
#                           .
#    Función en un Punto    .
#                           .
#............................



funcion_pto: # halla el valor de la función en un punto

li $v0, 4 # llamada a imprimir una cadena
la $a0, intro_valor # carga la cadena ("\nIntroduzca el valor de 'x': ") como
# argumento
syscall # muestra la cadena por pantalla

li $v0, 6 # llama al servicio de introducir un flotante
syscall # se espera a que el usuario introduzca un entero
mov.s $f12, $f0 # carga lo que ha introducido el usuario como argumento
# para elevarlo

la $s0, polinomio_1 # guarda el polinomio 1 en el registro $s0
li $t1, 0 # inicializa el contador a 0
li.s $f1, 0.0 # inicializa el flotante que almacenará el valor

funcion_pto_loop: # halla el valor de la función término a término

move $a1, $t1 # guarda el contador como argumento del exponente
jal exp # calcula $f12 elevado al expnente $a1
l.s $f3, ($s0) # guarda el término al que apunta $s0 en $f12
mul.s $f3, $f3, $f0 # multiplica el término por el valor en el punto

add.s $f1, $f1, $f3 # añade a lo que ya había lo que se ha calculado
beq $t1, 20, fin_f_pto # cuando se ha terminado se salta
add $s0, $s0, 4 # pasa al siguiente término
add $t1, $t1, 1 # incrementa el contador
j funcion_pto_loop # si no se analiza el siguiente término

fin_f_pto: # cuando se han analizado todos los términos

li $v0, 4 # llama a imprimir una cadena
la $a0, prompt_f_pto # carga como argumento la cadena ("\nel valor de la función
# en el punto es: ")
syscall # imprime la cadena

li $a2, 0 # carga 0 en $a2 para que no se muestre el signo del valor
# del punto

mov.s $f12, $f1 # carga el valor como argumento
jal imprimir_flotante # muestra el valor por pantalla

li $v0, 4 # llama a imprimir una cadena
la $a0, newline # carga como argumento una nueva línea (retorno de carro)
syscall # imprime la nueva línea
syscall # imprime otra nueva línea

j menu # vuelve al menú principal



#............................
#                           .
#          Raices           .
#                           .
#............................



raices: # calcula las raíces para polinomios de grado 2

la $a0, polinomio_1 # carga el polinomio 1 como argumento para hallar el grado
jal grado # halla el grado del polinomio 1
bne $v0, 2, no_dos # si el grado es distinto de 2, no se pueden hallar las
# raices

la $s0, polinomio_1 # carga el polinomio 1 en $s0
add $s0, $s0, 4 # calcula la posicion de x^1
l.s $f12, ($s0) # carga en $f12 como argumento el término de x^1 del
# polinomio 1 (B)
li $a1, 2 # carga como argumento 2 que es a lo que queremos elevar el
# término de x^1
jal exp # eleva al cuadrado el término de x^1 del polinomio 1
mov.s $f1, $f0 # guarda el resultado en $f1 (B^2)

sub $s0, $s0, 4 # recalcula la dirección del polinomio 1
l.s $f2, ($s0) # guarda en $f2 el término de x^0 del polinomio 1 (C)
add $s0, $s0, 8 # calcula la dirección del término de x^2
l.s $f3, ($s0) # guarda en $f3 el término de x^2 del polinomio 2 (A)

mul.s $f4, $f2, $f3 # guarda en $f4 la multiplicación entre $f2 y $f3 (AC)
li.s $f2, -4.0 # almacena en $f2 -4.0
mul.s $f4, $f4, $f2 # guarda en $f4 la multiplicación entre $f4 y $f2 (-4AC)

add.s $f4, $f4, $f1 # suma $f4 (-4AC) mas $f1 (B^2) y almacena el resultado en
# $f4

li.s $f2, 0.0 # carga 0.0 en $f2 para comprobar si $f4 es mayor que 0
c.lt.s $f4, $f2 # comprueba si lo que hay dentro de la raíz ($f4) es menor
# que 0 (B^2-4AC < 0)
bc1t imaginarias # si es menor que 0 las soluciones son imaginarias

la $a0, 2 # carga como argumento del índice de la raíz el 2
mov.s $f12, $f4 # carga $f4 como radicando de la raíz
jal radi # halla la raíz de $f4 (sqrt (B^2-4AC))
mov.s $f1, $f0 # guarda el resultado de la raíz en $f1

sub $s0, $s0, 4 # calcula la posición del término de x^1
l.s $f2, ($s0) # guarda en $f2 el término de x^1 del polinomio 1
neg.s $f2, $f2 # niega $f2 (-B)

add.s $f3, $f2, $f1 # suma $f2 (-B) mas $f1 (sqrt(B^2-4AC))
add $s0, $s0, 4 # calcula la posición del término de x^2
l.s $f4, ($s0) # guarda en $f4 el término de x^2 del polinomio 1 (A)

li.s $f5, 2.0 # carga en $f5 2.0 para multiplicarlo por $f4 (A)
mul.s $f4, $f4, $f5 # multiplica $f4 por 2 y guarda el resultado en $f4 (2A)

div.s $f6, $f3, $f4 # guarda el resultado de dividir $f3 entre $f4 en $f6
# ((-B+sqrt(B^2-4AC)/2A))

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_raices # carga la cadena ("\nlas raíces son: ")
syscall # imprime la cadena

sub.s $f3, $f2, $f1 # resta $f2 (-B) menos $f1 (sqrt(B^2-4AC))
div.s $f7, $f3, $f4 # guarda el resultado de dividir $f3 entre $f4 en $f7
# ((-B-sqrt(B^2-4AC)/2A))

li $a2, 0 # carga 0 en $a2 para que no se muestre el signo del
# resultado si es positivo

mov.s $f12, $f6 # carga la primera raíz como argumento
jal imprimir_flotante # imprime la primera raíz

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, y # carga la cadena (" y ")
syscall # imprime la cadena


mov.s $f12, $f7 # carga la segunda raíz como argumento
jal imprimir_flotante # imprime la segunda raíz

li $v0, 4 # llamada a imprimir cadena
la $a0, newline # carga un retorno de carro
syscall # imprime la nueva línea
syscall # imprime otra nueva línea

j menu # se vuelve al menu principal

no_dos: # si el grado del polinomio es distinto de 2, no se pueden
# hallar las raíces

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_no_dos # carga la cadena ("\nsólo se pueden hallar raíces de
# polinomios de grado 2\n\n")
syscall # imprime la cadena

j menu # se vuelve al menu principal

imaginarias: # si las soluciones son imaginarias

li $v0, 4 # llama al servicio de imprimir una cadena
la $a0, prompt_imag # carga la cadena ("\nlas raíces son imaginarias\n\n")
syscall # imprime la cadena

j menu # se vuelve al menu principal


#............................
#                           .
#         Switching         .
#                           .
#............................



switch: # intercambia el polinomio 1 y el polinomio 2

la $a0, pol_resultado # carga el polinomio resultado como argumento para guardar
la $a1, polinomio_1 # carga el polinomio 1 como argumento para cargar
jal igualar # guarda en polinomio resultado el polinomio 1

la $a0, polinomio_1 # carga el polinomio 1 como argumento para guardar
la $a1, polinomio_2 # carga el polinomio 2 como argumento para cargar
jal igualar # guarda en polinomio 1 el polinomio 2

la $a0, polinomio_2 # carga el polinomio 2 como argumento para guardar
la $a1, pol_resultado # carga el polinomio resultado como argumento para cargar
jal igualar # guarda en polinomio 2 el polinomio resultado

j main # vuelve al menú principal



#############################
#                           #
#       Data Segment        #
#                           #
#############################

.data

newline: .asciiz "\n"
elevado: .asciiz "^"
x: .asciiz "x"
y: .asciiz " y "
punto: .asciiz "."
menos: .asciiz "-"
mas: .asciiz "+"

prompt_pol1: .asciiz "polinomio 1: "
prompt_pol2: .asciiz "polinomio 2: "
prompt_resul: .asciiz "\nel resultado es: "
prompt_exceed: .asciiz "\nel grado del polinomio resultado excede de 20\n\n"
prompt_novalid: .asciiz "\nel exponente tiene que estar entre 0 y 21\n\n"
prompt_coc_div: .asciiz "\nel cociente es: "
prompt_res_div: .asciiz "\nel resto es: "
prompt_f_pto: .asciiz "\nel valor de la función en el punto es: "
prompt_raices: .asciiz "\nlas raíces son: "
prompt_no_dos: .asciiz "\nsólo se pueden hallar raíces de polinomios de grado 2\n\n"
prompt_imag: .asciiz "\nlas raíces son imaginarias\n\n"

prompt_menu: .asciiz "\n\nPulsa 1 para introducir el polinomio 1
\nPulsa 2 para introducir el polinomio 2
\nPulsa 3 para sumar los polinomios
\nPulsa 4 para restar los polinomios
\nPulsa 5 para multiplicar los polinomios
\nPulsa 6 para dividir los polinomios
\nPulsa 7 para la función en un punto del polinomio 1
\nPulsa 8 para hallar las raices del polinomio 1 (sólo grado 2)
\nPulsa 9 para intercambiar los polinomios (switching)
\nPulsa 10 para salir del programa\n"

prompt_intro: .asciiz "          !

\n         !__.     ;     '_
\n        !____.   ._,  `!__
\n     ^;  ,____'  ;__` ;___
\n    ,__   _____ .___,`___,
\n   '__'   `;___' ;__`,_;^                 Estructura de computadores
\n   ___.     ____.._, '   
\n   __^       ___! ;   `'^                 Práctica 2. Calculadora de polinomios Mips
\n   ^,         ^___   ,___
\n  `          `___.  ;__^
\n              ;__. ,__!
\n              ___. ;!`  '
\n              ___.   _;___!.
\n              ___.  .;____;,
\n              ___.     .,
\n              ___.
\n              ___.
\n              ___.
\n              ___.
\n              ___.
\n              ___.                        - Pulsa intro para continuar -
\n              ___.
\n              ___.
\n              ___.
\n              ___."

intro_coef: .asciiz "\nIntroduzca el coeficiente (0 para salir)\n"
intro_exp: .asciiz "\nIntroduzca el exponente\n"
intro_valor: .asciiz "\nIntroduzca el valor de 'x': "

.align 4
polinomio_1: .space 84
polinomio_2: .space 84
pol_resultado: .space 84

resta_tmp: .space 84
cociente_tmp: .space 84
pol_cociente: .space 84

#
# fin de polinomios.asm
#

Fuente: LWP
Autor: Anonimo
« Última modificación: Marzo 28, 2008, 05:11:49 por The Shadow » En línea


Para ver los enlaces debes ser usuario Crear Usuario o Hacer Sesion





Para ver los enlaces debes ser usuario Crear Usuario o Hacer Sesion
Reglamento del Foro
     Linux  Registered User #473016
Páginas: [1] Ir Arriba Imprimir