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

Licencia

Enlaces