Examen: 2021_06_16:Robótica - myTeachingURJC/2019-20-LAB-AO GitHub Wiki

Examen convocatoria extraordinaria: 2021-06-16. Ingeniería en Robótica Software

  • Tiempo: 2h
  • Descripción: Examen del Laboratorio del grado de Ingeniería en Robótica Software. Convocatoria extraordinaria
  • Fecha: 2021/Junio/06

Contenido

Enunciado

Solución comentada

(Por hacer)

Solución

Como siempre ocurre al programar, existen infinitas soluciones. Pero en todas ellas se debe respetar la especificación y no violar el convenio de uso de registros

Parte I

Estos son los tres ficheros de una posible solución:

  • Fichero fib.s
#------------------------
# int fib(a,b): Devolver el siguiente numero de fibonacci, 
# suponiendo que a y b son numero correctos de la fibonacci
# Entradas:
#   a: Numero de fibonacci n
#   b: Numero de fibonacci siguiente a n
# Salidas:
#   Numero de fibonacci siguiente a b:  a+b
#---------------------------------------------

	.globl fib

fib:
	#-- Asumimos que a0 y a1 son numeros de fibonacci consecutivos correctos
	#-- (ESPECIFICACION DEL ENUNCIADO)
	#-- El siguiente numero de fibonacci será a0 + a1
	#-- El resultado hay que devolverlo por a0
	add a0, a0, a1
	
	ret
	
  • Fichero test_fib.s

        # -- Constantes de los servicios del sistema
        # -- operativo (ESPECIFICACIONES ENUNCIADO)
	.include "so.s"
 
        # -- Contador de terminos de fibonacci
        # -- (ESPECIFICACIONES ENUNCIADO)
	.eqv N  10
	
	.text
	
	# -- Contador de terminos de la serie de fibonacci
	# -- sin contar los dos primeros (0, 1)
	li s2, N
	
	# -- valores iniciales de la secuencia de fibonacci
	# -- Estos valores NO se imprimen. Se usan para calcular
	# -- el siguiente trrmino
	li s0, 0
	li s1, 1
	
bucle: 
	# -- Comprobar si quedan terminos por calcular
	# -- Si no quedan, terminar
        beq s2, zero, fin
        
        # -- Queda un término menos
        addi s2, s2, -1
        
        # -- Asignar los valores actuales
        # -- para calcular el siguiente termino de fibonacci
        mv a0, s0
        mv a1, s1
	jal fib
	
	#-- a0 contiene el siguiente numero de fibonacci
	
	# -- Actualizar los terminos de fibonacci actuales
	mv s0, s1
	mv s1, a0
	
	#-- Imprimir nuevo termino
	li a7, PRINT_INT
	ecall
	
	#-- Imprimir un espacio de separacion
	li a0, ' '
	li a7, PRINT_CHAR
	ecall
	
	# -- Repetir bucle
	b bucle
	
	
fin:
	# -- Terminar
	li a7, EXIT
	ecall
  • Fichero so.s
        .eqv EXIT      10
	.eqv PRINT_INT 1
	.eqv PRINT_CHAR 11

Parte II

  • Fichero print_mul5.s

	#-- Constantes usadas
	.eqv FIN 10
	.eqv IMPRIMIR_ENTERO 1
	.eqv IMPRIMIR_CARACTER 11

	.globl print_mul5

	.text
	
print_mul5:

	#-- Es necesario crear la pila para guardar la direccion de retorno
	#-- y los registros estáticos que se están modificando
	addi sp,sp, -16
	
	#-- Guardar direccion de retorno
	sw ra, 12(sp)
	
	#-- Guardar los registros estáticos en la pila
	#-- para recuperarlos al final y respectar así
	#-- el convenio
	sw s0, 0(sp)
	sw s1, 4(sp)	
	
	#-- El registro S0 lo inicializamos con n (a0)
	#-- que es el parametro de entrada
	mv s0, a0
	
# ----------------- ESTE CODIGO NO SE PUEDE MODIFICAR ----------------------------------	
	# -- Contador: 1,2,3....
	li s1, 1
	
bucle:
	beq s0, zero, terminar	
	addi s0, s0, -1
	
	# -- Calcular el siguiente multiplo de 5
	mv a0, s1
	jal mul5
	
	#-- En a0 se encuentra el multiplo
	#-- Lo imprimimos en la consola
	li a7, IMPRIMIR_ENTERO
	ecall
	
	#-- Imprimir un espacio
	li a0, ' '
	li a7, IMPRIMIR_CARACTER
	ecall
	
	#-- Pasar al siguiente multiplo
	addi s1, s1, 1
	b bucle


terminar:
#----------- FIN DEL CODIGO QUE NO SE PUEDE MODIFICAR ------------------

	#-- Recuperar los valores de los registros estáticos
	lw s0, 0(sp)
	lw s1, 4(sp)
	
	#-- Recuperar la direccion de retorno
	lw ra, 12(sp)
	
	#-- Recuperar el puntero de pila
	addi sp, sp, 16
	
	#-- Retornar
	ret
  • Fichero main.s
	.eqv READ_INT 5
	.eqv PRINT_STRING 4
	.eqv EXIT 10

	.data
	
msg1:	.string "\nIntroduce numero de multiplos a imprimir: "

	.text
	
bucle:	
	#-- Imprimir mensaje de solicitud
	la a0, msg1
	li a7, PRINT_STRING
	ecall
	
	#-- Pedir numero al usuario
	li a7, READ_INT
	ecall
	
	#-- a0 contiene el numero introducido por el usuario
	#-- Si este numero es 0 se termina
	beq a0, zero, fin 

	#-- Imprimir los multiplos pedidos, llamando a print_mult()
	jal print_mul5
	
	#-- Repetir el bucle
	b bucle
fin:
	
	#-- Terminar
	li a7, EXIT
	ecall
	

Autores

Licencia

Enlaces