Skip to content

Examen: 2022_06_29:GISAM:TELECO

Juan Gonzalez-Gomez edited this page Jun 30, 2022 · 14 revisions

Examen convocatoria extraordinaria: 2022-06-293. GISAM y TELECO

  • Tiempo: Una hora y media
  • Descripción: Examen final de laboratorio. Grados de ISAM y TELECO
  • Fecha: 2022/Junio/29
  • Comentarios:
    • Acceso a Internet permitido
    • Entrega por Aula Virtual

Contenido

Enunciado

El examen se ha realizado a través de Aula virtual. Consta de dos programas

AVISO

Asegúrate que tus programas cumplen con los siguientes criterios. Si no se cumple alguno de ellos la nota será 0 en ese apartado

  • Cumplimiento de especificaciones. Se deben cumplir las especificaciones indicadas en el enunciado: nombres de funciones, nombres de archivos, parámetros de las funciones, constantes, funcionalidad, etc. Compruébalo antes de entregar el examen
  • Respetar el convenio. Resuelve las preguntas sin violar el convenio del uso de registros (ABI del RISC-V)
  • Sin errores en tiempo de ejecución (Runtime errors). Tus programas no deben generar excepciones al ejecutarse
  • Sin errores al ensamblar. Los ficheros entregados NO deben dar errores al ensamblarlos. Si una función la has dejado a medio hacer, asegúrate que al menos se ensambla sin errores

Programa 1 (5 ptos)

El siguiente programa calcula el término de fibonacci indicado en la constante N, y lo imprime en la consola

#---------------------------
#-- Sucesion de Fibonacci
#-- Calcular el término n
#---------------------------
#-- fib(0) = 0
#-- fib(1) = 1
#-- fib(2) = 1
#-- fib(3) = 2
#-- fib(4) = 3
#-- fib(5) = 5
#-- fib(6) = 8
#-- fib(n) = fib(n-1) + fib(n-2)

	#-- Servicios del sistema operativo
  	.eqv PRINT_INT    1
	.eqv PRINT_STRING 4
	.eqv EXIT         10
	
	#-- Termino de fibonacci a Calcular: fib(N)
	#-- (Debe ser > 1)
	.eqv N 6

	.data
msg1: .string "\nFibonacci de "
msg2: .string " ---> "

	.text
	
	#-- Meter en t6 el termino a calcular
	li t6, N  
	
	#-- El registro t5 se usa para indicar el numero del termino 
	#-- de fibonacci actual (n)
	li t5, 1  #-- Termino final a calcular
	
	
	#-- Los registros t0 y t1 contienen fib(n) y fib(n+1)
	li t0, 0
	li t1, 1

bucle:		
	#-- Comprobar si hemos calculado el termino pedido
	beq t5,t6, fin
	
	#-- Calcular el siguiente termino: t2 = t1 + t0
	add t2, t1, t0
	
	#-- Actualizar los valores recordados
	mv t0, t1   #-- t0 = t1 (termino anterior)
	mv t1, t2   #-- t1 = t2 (nuevo termino)
	
	#-- Incrementar el termino actual
	addi t5, t5, 1
	
	#-- Repetir bucle
	b bucle
	
	
	#-- Mostrar el termino calculado
	#-- El termino esta almacenado en t2
fin:
	#-- Imprimir mensaje en consola
	la a0, msg1
	li a7, PRINT_STRING
	ecall
	
	#-- Imprimir n
	mv a0, t6
	li a7, PRINT_INT
	ecall
	
	#-- Mensaje 2
	la a0, msg2
	li a7, PRINT_STRING
	ecall 
	
	#-- Imprimir el numero de fibonacci
	mv a0, t2
	li a7, PRINT_INT
	ecall
	
	#-- Terminar
	li a7, EXIT
	ecall

Tras su ejecución esta es la salida que obtenemos en la consola:

Se ha calculado el valor del término 6 de fibonnaci (N=6). Cambiando la constante, se imprime su término correspondiente

Queremos separar este programa en dos ficheros, uno el programa principal y otro con la función fib(n) que calcula el térnimo n de fibonacci. La función fib() tiene un argumento de entrada, n, que es el término a calcular, y devuelve el valor de ese término

Se pide:

a) (2.5) Implementa la función de fibonacci en el fichero 01_fib.s
b) (2.5) Implementa el programa principal en el fichero 01_main.s. Para ello, modifica el programa original para que llame a la función de fibonacci para calcular el término N. La salida en consola de este programa debe ser exactamente la misma que el programa original

NOTA: Este programa sólo consta de esos dos ficheros indicados. Debe funcionar correctamente sólo con esos dos ficheros. No puedes añadir ninguno más

Programa 2 (5 Ptos)

La función linea(car) imprime en la consola una línea de 5 caracteres. Tiene un parámetro de entrada, car, que indica el carácter a usar para dibujar la línea. No tienen ningún parámetro de salida

La implementación de esta función se encuentra en el fichero 02_linea.s, cuyo contenido es:

#----------------------------------------
#-- Funcion linea(car)
#--
#-- Dibujar una linea de 5 caracteres
#-- ENTRADAS:
#--   a0: caracter a usar para dibujar la linea
#--
#-- SALIDAS: Ninguna
#----------------------------------------

	.globl linea
	
	#-- Servicios del sistema operativo
	.eqv PRINT_CHAR   11
	
	
	#-- Numero de caracteres en la linea
	.eqv N 5
	
	.text
	
	#-- Punto de entrada de la funcion
linea:

	#-- Contador de caracteres en la linea
	li t0, 0
	
	#-- Comprobar si la linea se ha completado
bucle:
	li t1, N
	beq t0,t1,fin
	
	#-- Imprimir el caracter
	li a7, PRINT_CHAR
	ecall
	
	#-- Incrementar el contador de caracteres
	addi t0,t0,1
	
	b bucle
	
fin:
	#-- Imprimir un salto de linea
	li a0, '\n'
	li a7, PRINT_CHAR
	ecall
	
	#-- Retornar
	ret

La función bloque(car, lineas) imprime varias líneas de caracteres, una debajo de la otra. Tiene dos parámetros de entrada: el carácter a usar para dibujar las líneas, y el número de líneas a dibujar. No devuelve ningún valor. La función bloque() llama a la función linea() para dibujar cada una de las líneas

Además se quiere hacer un programa principal cuya salida en consola sea la siguiente:

El programa imprime en la consola dos bloques, llamando a la función bloque(). El primero está formado por 3 líneas con asteriscos, y el segundo por 4 líneas con el carácter 'X'. Ambos bloques están separados por un salto de línea

Se pide:

a) (2.5 ptos) Implementar la función bloque en el fichero 02_bloque.s
b) (2.5 ptos) Implementar el programa principal en el fichero 02_main.s

NOTA: Este programa está formado únicamente por tres ficheros: 02_linea.s, 02_bloque.s y 02_main.s. Debe funcionar sin añadir ninguno más

Solución del examen

Solución al programa 1

  • Fichero 01_fib.s:
#------------------------------------------------
#-- Funcion de fibonacci
#-- ENTRADA:
#--   a0:  Termino a calcular (n > 1)
#--
#-- SALIDA:
#--   a0: Termino de fibonacci pedido fib(n)
#------------------------------------------------

    .globl fib
	.text
	
fib:
	#-- Meter en t6 el termino a calcular
	mv t6, a0  
	
	#-- El registro t5 se usa para indicar el numero del termino 
	#-- de fibonacci actual (n)
	li t5, 1  #-- Termino final a calcular
	
	
	#-- Los registros t0 y t1 contienen fib(n) y fib(n+1)
	li t0, 0
	li t1, 1

bucle:		
	#-- Comprobar si hemos calculado el termino pedido
	beq t5,t6, fin
	
	#-- Calcular el siguiente termino: t2 = t1 + t0
	add t2, t1, t0
	
	#-- Actualizar los valores recordados
	mv t0, t1   #-- t0 = t1 (termino anterior)
	mv t1, t2   #-- t1 = t2 (nuevo termino)
	
	#-- Incrementar el termino actual
	addi t5, t5, 1
	
	#-- Repetir bucle
	b bucle
	
	
	#-- Devolver el numero de fibonacci
	#-- calculado
fin:
	mv a0, t2
	
	ret
  • Fichero 01_main.s:
#---------------------------
#-- Sucesion de Fibonacci
#-- Calcular el término n
#---------------------------
#-- fib(0) = 0
#-- fib(1) = 1
#-- fib(2) = 1
#-- fib(3) = 2
#-- fib(4) = 3
#-- fib(5) = 5
#-- fib(6) = 8
#-- fib(n) = fib(n-1) + fib(n-2)

	#-- Servicios del sistema operativo
  	.eqv PRINT_INT    1
	.eqv PRINT_STRING 4
	.eqv EXIT         10
	
	#-- Termino de fibonacci a Calcular: fib(N)
	#-- (Debe ser > 1)
	.eqv N 7

	.data
msg1: .string "\nFibonacci de "
msg2: .string " ---> "

	.text
	
	#-- Calcular el termino N de fibonacci
	li a0, N
	jal fib
	
	#-- a0 contiene fib(N)
	#-- Guadar a0 en t0
	mv t0, a0
	
	
	#-- Mostrar el termino calculado
fin:
	#-- Imprimir mensaje en consola
	la a0, msg1
	li a7, PRINT_STRING
	ecall
	
	#-- Imprimir n
	li a0, N
	li a7, PRINT_INT
	ecall
	
	#-- Mensaje 2
	la a0, msg2
	li a7, PRINT_STRING
	ecall 
	
	#-- Imprimir el numero de fibonacci
	mv a0, t0
	li a7, PRINT_INT
	ecall
	
	#-- Terminar
	li a7, EXIT
	ecall

Solución al programa 2

  • Fichero 02_bloque.s:
#--------------------------------------------------
#-- Funcion bloque(car, lineas)
#--
#-- ENTRADAS:
#--
#--   a0: (car) Caracter a usar en la linea
#--   a1: (lineas) Numero de lineas del bloque
#--
#-- SALIDAS:
#--   Ninguna
#--------------------------------------------------

	.globl bloque

	.text
	
bloque:
	#-- Es una funcion intermedia
	#-- Hay que crear la pila para guardar la direccion de retorno
	addi sp,sp,-16
	
	#-- Guardar la direccion de retorno
	sw ra, 12(sp)
	
	#-- Usamos registros estaticos para no perder la informacion
	#-- al llamar a la funcion linea
	#-- Para cumplir el convenio guardamos estos registros
	#-- en la pila
	sw s0, 0(sp)
	sw s1, 4(sp)
	sw s2, 8(sp)


	mv s0,a0  #-- Guardar el caracter de la linea
	mv s1,a1  #-- Guardar el numero de lineas
	
	#-- Contador de lineas
	li s2,0  
	
bucle:
	#-- Comprobar si se han impreso todas las lineas del bloque
	beq s2,s1,fin
	
	#-- Imprimir la linea
	mv a0,s0
	jal linea
	
	#-- Incrementar contador de linea
	addi s2,s2,1
	
	b bucle

fin:

	#-- Recuperar los registros estáticos para no violar
	#-- el convenio de uso de registros
	lw s0, 0(sp)
	lw s1, 4(sp)
	lw s2, 8(sp)

	#-- Recueprar la direccion de retorno
	lw ra, 12(sp)
	
    #-- Recuperar la pila
	addi sp,sp,16
	ret
  • Fichero 02_main.s:
	#-- Servicios del sistema operativo
	.eqv PRINT_CHAR   11
	.eqv EXIT         10

	.text
	
	#-- Imprimir primer bloque
	li a0, '*'
	li a1, 3
	jal bloque
	
	#-- Imprimir salto de linea
	li a0, '\n'
	li a7, PRINT_CHAR
	ecall
	
	#-- Imprimir segundo bloque
	li a0, 'X'
	li a1, 4
	jal bloque
	
	#-- Terminar
	li a7,EXIT
	ecall

Evaluación

La evaluación de cada apartado (2.5 ptos) de un programa se hace en dos fases:

  • Funcionalidad (1 ptos): Se comprueba si el programa funciona, y si cumple con las especificaciones (Nombre del fichero correcto, ensablado sin errores, sin errores en tiempo de ejecución, resultado correcto, variables definidas en sus posiciones de memoria especificadas, etc). Esto se hace mediante un script de test, que automatiza el proceso

  • Código (1.5 ptos): Se inspecciona visualmente cómo está hecho el código: código limpio, claro, con comentarios, instrucciones correctas, fallos de programación, etc...

TEST automáticos

La comprobación de las especificaciones se hace mediante programas de test independientes. Cada apartado se prueba de forma independiente. Si por ejemplo en un apartado me piden que implemente una función, esta se prueba contra un programa principal de prueba (NO el proporcionado por el estudiante). Y al revés, si se pide un programa principal, se prueba contra las funciones correctas (no las proporcionadas por el estudiante). Esto permite determiar si la interfaz implementada es al correcta, así como si se ha violado algún convenio

Para hacer ejecutar los scripts de prueba se deben descomprimir los ficheros test1.zip y test2.zip en el directorio donde están nuestros programas. La estrucutra de directorios será la siguiente:

> Mis programas.s
  +-- TEST1
  |   +-- Scripts de prueba para problema 1
  +-- TEST2
      +-- Scripts de prueba para problema 2

Ficheros a descargar:

Ejemplo

Por ejemplo, supongamos que tenemos los ficheros el programa 1 en la carpeta programa-1. Para comprobar el apartado a ejecutamos este comando:

obijuan@Hoth:~/Examen/Programa-1/TEST1$ bash TEST-a.sh

La salida que aparecerá en la pantalla, si el fichero del apartado a es correcto, será similar a esta:

-----Ejecutando TEST-a-1-----
> ✅️ rars1_5.jar existe
> ✅️ 01_fib.s existe

> ➡️  PROBANDO: 01_fib.s
java -jar rars1_5.jar nc me ic 10000 01_main_TB.s ../01_fib.s

> COMPROBANDO VALORES recibidos
> ✅️ Fib(3)=2. OK!
> ✅️ Convenio OK!
> ✅️ Fib(6)=8. OK!
> ✅️ Convenio OK!
> ✅️ Fib(10)=55. OK!
> ✅️ Convenio OK!

> Salida en consola: 
2
Convenio OK!!
8
Convenio OK!!
55
Convenio OK!!
> Ciclos de ejecución: 407
> ✅️ El programa termina llamando a EXIT

------FIN-------

Autores

Licencia

Enlaces

Página principal


Sesiones de Prácticas

P1: Simulador RARs

L1: Práctica 1-1. RARs
L2: Práctica 1-2. Ensamblador
L3: Práctica 1-3. Variables

P2: E/S mapeada. Llamadas al sistema

L4: Pract 2-1. E/S mapeada
L5: Práctica 2-2: Inst. ecall
L6: Prác 2-3: Cadenas

P3: Bucles y Saltos condicionales

L7: Práct 3-1: Bucles y saltos
L8: Práct 3-2: Cadenas II

P4: Subrutinas

L9: Pract 4-1: Subrut. Nivel-1
L10: Pract 4-2: La pila
L11: Pract 4-3: Recursividad

P5: Memoria Dinámica

L12: Pract 5-1. Heap. Listas

VÍDEO DE DESPEDIDA

Ejercicios de examen

Simulacro examen 1
GISAM. Ordinario. 2019-Dic-11
GISAM. Extra. 2020-Jul-03
GISAM. Ordinario. 2021-Ene-21
GISAM. Ordinario. 2022-Ene-10
GISAM. Extra. 2022-Jun-29
GISAM. Parcial 1. 2022-Oct-26
GISAM. Parcial 2. 2022-Nov-30
GISAM. Parcial 3. 2022-Dic-21
GISAM. Parcial 1. 2023-Oct-09
GISAM. Parcial 2. 2023-Nov-11
GISAM. Parcial 3. 2023-Dic-20
GISAM. Extra. 2024-Jun-17
GISAM. Parcial 1. 2024-Oct-14
GISAM. Parcial 2. 2024-Nov-13
GISAM. Parcial 3. 2024-Dic-16
TELECO. Ordinario. 2019-Dic-13
TELECO. Extra. 2020-Jul-07
TELECO. Ordinario. 2021-Ene-21
TELECO. Extra. 2021-Jul-02
TELECO. Ordinario. 2022-Ene-10
TELECO. Extra. 2022-Jun-29
TELECO. Ordinario. 2023-Ene-10
TELECO. Extra. 2023-Jun-29
TELECO. Parcial 1. 2023-Oct-20
TELECO. Parcial 2. 2023-Nov-17
TELECO. Parcial 3. 2023-Dic-22
TELECO. Extra. 2024-Jun-17
TELECO. Parcial 1. 2024-Oct-10
TELECO. Parcial 2. 2024-Nov-21
TELECO. Parcial 3. 2024-Dic-19
Robótica. Ordinario. 2020-Jun-1
Robótica. Extra. 2020-Jul-13
Robótica. Ordinario. 2021-Mayo-20
Robótica. Extra. 2021-Junio-16
Robótica. Parcial 1. 2022-Feb-25
Robótica. Parcial 2. 2022-Abril-1
Robótica. Parcial 3. 2022-Mayo-6
Robótica. Parcial 1. 2023-Feb-27
Robótica. Parcial 2. 2023-Mar-27
Robótica. Parcial 3. 2023-May-08
Robótica. Parcial 1. 2024-Feb-26
Robótica. Parcial 2. 2024-Mar-20
Robótica. Parcial 3. 2024-May-06
Robótica. Extra. 2024-Junio-24
Datos. Parcial 1. 2023-Oct-09
Datos. Parcial 2. 2023-Nov-15
Datos. Parcial 3. 2023-Dic-20
Datos. Parcial 1. 2024-Oct-09
Datos. Parcial 2. 2024-Nov-13
Datos. Parcial 3. 2025-Ene-17

SOLUCIONES

Práctica 1: Sesiones 1,2 y 3
Práctica 2: Sesiones 4, 5 y 6
Práctica 3: Sesiones 7 y 8
Práctica 4: Sesiones 9, 10 y 11
Práctica 5: Sesión 12

Clone this wiki locally