Examen: Parcial 3:2023_12_20:Datos - myTeachingURJC/2019-20-LAB-AO GitHub Wiki
Examen Parcial 3: 2023-05-20. Ingeniería de Datos
- Tiempo: 55 minutos
- Descripción: Examen Parcial 3. Laboratorio. Grado de Ingeniería en Ciencia de Datos
- Temario: Sesiones L9, L910 y L11
Contenido
Enunciado
Escribir un programa que pida al usuario dos números enteros a y b, y calcule la potencia a^b con un algoritmo recursivo. El programa constará de un código principal y dos subrutinas. La primera subrutina (pedir_int.asm) imprimirá un mensaje por pantalla y pedirá un número entero. Tendrá como parámetros de entrada la dirección de memoria de la cadena del mensaje a imprimir, y devolverá el entero leido. La segunda subrutina (exp.asm) calcula la potencia a^b. Tendrá como entrada los valores a y b, y devolverá el resultado de calcular a^b. Esta función se debe implementar de acuerdo al siguiente algoritmo recursivo, descrito en pseudocódigo python:
def exp(a, b):
if b < 1:
return 1
return exp(a, b-1) * a
Las subrutinas deben estar en ficheros separados al programa principal.
Recuerda comprobar que no se incumple el convenio de uso de los registros.
Los nombres de los ficheros a implementar son potencia.asm para el programa principal, exp.asm para la subrutina exp y pedir_int.asm para la subrutina que pide un entero. Recuerda subir también los archivos que utilices en tu código con la directiva .include
Solución
- Fichero potencia.asm
#-- Programa que realiza una potencia de manera recursiva
#-- Pide por teclado dos enteros y llama a la funcion exp(a, b),
#-- que devuelve el resultado de a^b
.include "lib.asm"
.data
msg1: .string "Introduce base: "
msg2: .string "Introduce exponente: "
msg3: .string "El resultado es: "
.text
#-- Imprimir "Introduce base: "
la a0, msg1
jal pedir_int
mv s0, a0
#-- Imprimir "Introduce exponente: "
la a0, msg2
jal pedir_int
#-- Calcular exponente con la subrutina exp
mv a1, a0
mv a0, s0
jal exp
mv s2, a0
#-- Imprimir "El resultado es: "
la a0, msg3
li a7, PRINT_STRING
ecall
#-- Imprimir resultado
mv a0, s2
li a7, PRINT_INT
ecall
#-- Fin
li a7, EXIT
ecall
- Fichero pedir_int.asm
#-- Subrutina que muestra un mensaje por pantalla
#-- y pide por teclado un número entero
#-- Argumentos:
#-- a0 = puntero a la cadena del mensaje
#-- Resultado:
#-- a0 = entero pedido por teclado
.include "lib.asm"
.globl pedir_int
.text
pedir_int:
#-- Mostramos el mensaje apuntado por a0
li a7, PRINT_STRING
ecall
#-- Pedimos un entero por pantalla
li a7, READ_INT
ecall
#-- Salida de la subrutina
ret
- Fichero exp.asm
#-- Subrutina que calcula de forma recursiva una potencia
#-- exp(a, b) devuelve el resultado de hacer a^b
#-- Argumentos:
#-- a0 = base (a)
#-- a1 = exponente (b)
#-- Resultado:
#-- a0 = a^b
.globl exp
.text
#-- Punto de entrada
exp:
#-- if a1 < 1
li t0, 1
bge a1, t0, exp_rec
#-- return 1
li a0, 1
b fin
exp_rec:
#-- Reserva de 16 bytes en la pila
addi sp, sp, -16
#-- Guardado de dirección de retorno
sw ra, 12(sp)
#-- Guardado de base
sw a0, 8(sp)
#-- llamada a exp(a, b-1)
addi a1, a1, -1
jal exp
#-- Recuperación de base
lw t0, 8(sp)
#-- result = exp(a, b-1) * a
mul a0, a0, t0
#-- Recuperación de dirección de retorno
lw ra, 12(sp)
#-- Liberación de 16 bytes en la pila
addi sp, sp, 16
fin:
#-- salida de la subrutina
ret
- Fichero lib.asm
.eqv EXIT 10
.eqv PRINT_INT 1
.eqv READ_INT 5
.eqv PRINT_STRING 4
Autores
- Miguel Ángel de Miguel
- Juan González-Gómez (Obijuan)