Skip to content

Examen: Parcial 3:2026_01_09:GISAM

Juan Gonzalez-Gomez edited this page Jan 19, 2026 · 12 revisions

Examen Parcial 3: 2026-1-9. GISAM

  • Tiempo: 1 hora
  • Descripción: Examen Parcial 3. Laboratorio. Grado en Ingeniería de Sistemas Audiovisuales y Multimedia
  • Fecha: 2026/Enero/9
  • Temario: Sesiones L9,L10

Contenido

Enunciado

El examen se ha realizado a través de Aula virtual. Hay que realizar un programa para el riscv, siguiendo las especificaciones

  • Puntuación: 10 puntos
  • Tiempo: 1 hora

Especificaciones

Se deben implementar las siguientes funciones en un RV32I

  • Función hex_digit(n): Recibe como parámetro de entrada un número entre 0 y 15, y devuelve un carácter con el digito hexadecimal correspondiente ('0' - 'F'). Por ejemplo, hex_digit(5) devuelve el carácter '5' y hex_digit(10) devuelve 'A'

    Esta funcion se debe implementar siguiente este algoritmo:

  1. Si n > 9, saltar al paso 4
  2. Calcular: dig = n + '0'
  3. Saltar al paso 5
  4. Calcular: dig = n - 10 + 'A'
  5. Devolver dig y terminar
  • Funcion print_hex1(n): Recibe como parámetro de entrada un número entre 0 y 15 y lo imprime en hexadecimal, colocando el prefijo "0x" delante. Esta función NO retorna ningúna valor. Por ejemplo, print_hex1(5) imprime en la consola "0x5" y print_hex(10) imprime "0xA". NO se imprime ningún salto de línea al final

    La funcion print_hex1(n) debe llamar a hex_digit(n) para convertir el numero n a un carácter con el dígito hexadecimal, que es el que se imprime. El pseudo-código de esta función es el siguiente:

    • Imprimir prefijo "0x" en la consola
    • Llamar a hex_digit(n)
    • Imprimir el carácter devuelto
    • Terminar

Finalmente, necesitamos un programa principal que imprima los números del 0 al 15 en hexadecimal, llamando a la función print_hex1(n). Cada número se imprime en una linea separada. Este es el resultado que debe aparecer en la consola al ejecutarlo:

Se pide:

a) (3 ptos). Implementar la función hex_digit(n) en el fichero hex_digit.s

b) (4 ptos). Implementar la función print_hex1(n) en el fichero print_hex1.s. Las constantes del sistema operativo utilizadas se deben definir dentro de este fichero

c) (3 ptos). Implementar el programa principal en el fichero main.s. Las constantes del sistema operativo utilizadas se deben definir dentro de este fichero

  • Ficheros a entregar:

    • hex_digit.s
    • print_hex1.s
    • main.s
  • NOTA: No hay ningún fichero externo con las constantes del sistema operativo. Se definen dentro de cada función y programa principal que los necesite. El programa principal debe funcionar sólo con los ficheros entregados, y ninguno más

Solución

  • Fichero hex_digit.s

La clave para la resolución de este apartado es seguir al pie de la letra los pasos indicados en el algoritmo. Como se trata de una función hoja (no llama a otras funciones), no hay que crear la pila ni almacenar la dirección de retorno

	.text
	
	.global hex_digit
#---------------------------------------
#-- hex_digit(n)
#--
#-- Convertir un numero (0-15) a su digito
#-- hexadecimal correspondiente '0'-'F'
#--
#-- Ejemplos: 
#--    hex_digit(5) = '5'
#--    hex_digit(10) = 'A'
#--
#-- ENTRADA:
#--   - a0 (n): Numero a convertir (0<= n <=15)
#--
#-- SALIDA:
#--   - a0: Caracter ASCII del digito correspondiente
#------------------------------------------
hex_digit:

	#-- 1. Si n > 9, saltar al paso 4
	#-- a0: Variable n
	li t0, 9
	bgt a0, t0, paso_4
	
	#-- 2. Calcular: dig = n + '0'
	#-- t1 = Variable dig
	addi t1, a0, '0'
	
	#-- 3. Saltar al paso 5
	j paso_5
	
paso_4:
	#-- 4. Calcular: dig = n - 10 + 'A'
	#-- t1: Variable dig
	#-- a0: Variable n
	addi t1, a0, -10  #-- dig = n - 10
	addi t1, t1, 'A'  #-- dig = n - 10 + 'A'

paso_5:
    #-- 5. Devolver dig
    mv a0, t1
	ret
  • Fichero print_hex1.s

Se trata de una función intermedia. Por tanto hay que crear la pila para guardar la dirección de retorno. Luego hay que seguir los pasos indicados por el algoritmo (pseudocódigo) proporcionado

	
	.global print_hex1
	
	#-- Servicios del sistema operativo
	.eqv PRINT_STRING 4
	.eqv PRINT_CHAR 11
	
	.data
prefijo_0x: .string "0x"
	
	.text
#-----------------------------------------------------------------
#-- print_hex1(n)
#--
#--  Imprimir un numero hexadecimal con el prefijo '0x'
#--
#-- ENTRADA:
#--   - a0 (n): Numero hexadecimal (0-15) a imprimir
#--
#-- SALIDA:
#--   - Ninguna. La funcion no devuelve ningun valor
#----------------------------------------------------------------
print_hex1:

	#-- Crear la pila
	addi sp, sp, -16
	
	#-- Guardar direccion de retorno
	sw ra, 12(sp)

	#-- Guardar a0 (n) en la pila para no perderlo
	sw a0, 0(sp)

	#-- Imprimir prefijo
	la a0, prefijo_0x
	li a7, PRINT_STRING
	ecall
	
	#-- Recuperar a0 de la pila
	lw a0, 0(sp)

	#-- Convertir n a caracter
	jal hex_digit
	#-- a0: Caracter con el digito
	
	#-- Imprimir el digito hexadecimal
	li a7, PRINT_CHAR
	ecall
	
	#-- Recuperar direccion de retorno
	lw ra, 12(sp)

	#-- Liberar la pila
	addi sp, sp, 16
	ret
  • Fichero main.s

El programa principal debe mostrar los números del 1 al 15, en hexadecimal, llamando a la función print_hex1(). Basta con realizar un bucle del 0 al 15

	#-- Servicios del sistema operativo
	#-- Deben estar aqui por ESPECIFICACIONES
	.eqv EXIT 10
	.eqv PRINT_CHAR 11

	.text
	
	#-- Programa principal
	#-- Imprimir los numeros del 1 al 15 en hexadecimal
	
	#-- Inicializar contador de numeros (s0)
	li s0, 0
	
bucle:
	#-- Imprimir numero actual
	mv a0, s0
	jal print_hex1
	
	#-- Imprimir salto de linea
	li a0, '\n'
	li a7, PRINT_CHAR
	ecall
	
	#-- Incrementar contador
	addi s0, s0, 1
	
	#-- Si contador <= 15, repetir bucle
	li t0, 15
	ble s0, t0, bucle
	
	#-- Terminar
	li a7, EXIT
	ecall

Evaluación

La evaluación del programa se hace en dos fases:

  • Funcionalidad (2.5 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. Se quitan puntos según los errores encontrados:

    • Violación de especificaciones: -0.5
    • Programa no ensambla: -0.5
    • Error en tiempo de ejecución al pasar las pruebas: Runtime error: -0.5
    • Retraso en la entrega: -0.5
    • No hay segmento de código: -0.5
    • Variable no contiene el valor correcto: -0.5
    • El programa no termina (-0.5): No se llama al servicio exit del sistema operativo para terminar el programa de forma controlada
  • Código (2.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... Se restan puntos por errores encontrados en el código:

    • Código sin sentido (-0.5): Se ha introducido una instrucción, o directiva, que no tiene relación con el enunciado y no se da una explicación explícita de porqué se ha puesto
    • Comentario contradictorio (-0.5): La instrucción hace una cosa, pero en los comentarios se indica otra distinta
    • Comentarios no coherentes (-0.5): Se indica algo en los comentarios que no tiene nada que ver con el código que se está escribiendo
    • Uso de un registro NO inicializado (-0.5)
    • Violacion de especificaciones (-0.5)
    • Dato inventado (-0.5). El código añade algo, o supone algo que no tiene sentido según lo que dice el enunciado
    • Error en calculos (-0.5)
    • No hay comentarios, o son muy escasos (-0.5)

TEST automático

Para comprobar la funcionalidad se utiliza la herramienta Arquibot, que son un conjunto de programas python que ejecutan el simulador RARS en línea de comando y comprueban el funcionamiento correcto del programa en ensamblador entregado por el estudiantado

Para comprobar tu solución sigue estas instrucciones:

  1. Descarga este fichero: arquibot-0.5.zip
  2. Crea un directorio donde se realizarán las pruebas. Por ejemplo Parcial3
  3. Pon en ese directorio el programa realizado. Ficheros hex_digit.s, print_hex1.s y main.s, o puedes bajarte los ficheros ya solucionados: hex_digit.s, print_hex1.s, main.s
  4. Descomprime en ese directorio el fichero arquibot-0.5.zip

La estructura queda así:

Parcial3/
├── arquibot-0.5
│   ├── 2026-01-09-hex_digit_SOL.s
│   ├── 2026-01-09-hex_digit_TB.s
│   ├── 2026-01-09-print_hex1_SOL.s
│   ├── 2026-01-09-print_hex1_TB.s
│   ├── arquibot
│   │   ├── ansi.py
│   │   ├── __pycache__
│   │   │   ├── ansi.cpython-312.pyc
│   │   │   ├── rars.cpython-312.pyc
│   │   │   └── util.cpython-312.pyc
│   │   ├── rars.py
│   │   └── util.py
│   ├── run1.py
│   ├── run2.py
│   ├── run3.py
│   ├── so.h
│   └── test.h
├── hex_digit.s
├── main.s
└── print_hex1.s

Ejecutamos el script run1.py:

obijuan@JANEL:~/test/Parcial3/arquibot-0.5$ ./run1.py 
────────────────────────────────────────
ARQUI-BOT 0.5
────────────────────────────────────────
> 🤚 RARS no existe
  > Descargando RARS
  > OK! 

> ☑️  RARS EXISTE
> ✅️ 2026-01-09-hex_digit_TB.s existe
> ✅️ ../hex_digit.s existe
> Probando: 2026-01-09-hex_digit_TB.s
> Ejecutando: java -jar rars1_6.jar x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 nc me ic 10000 dump 0x10010000-0x10010100 HexText data.hex dump .text HexText text.hex 2026-01-09-hex_digit_TB.s ../hex_digit.s
> ☑️  Hay segmento de datos
> ✅️ Hay segmento de código
  ──────── Salida en consola
* hex_digit(5): OK
* Convenio: OK
* hex_digit(10): OK
* Convenio: OK

  ──────── Resultado
> ✅️ Test 1 OK
> ✅️ Test 2 OK
> ✅️ Test convenio OK
────────────────────────────────────────

Este script primero comprueba si en el directorio está el fichero rars_1.6.jar. Si no es así, lo baja del repositorio. A continuación analiza los ficheros del programa y muestra en la salida los resultados

  • Ejecutamos el script run2.py:
obijuan@JANEL:~/test/Parcial3/arquibot-0.5$ ./run2.py 
────────────────────────────────────────
ARQUI-BOT 0.5
────────────────────────────────────────
> ☑️  RARS EXISTE
> ✅️ 2026-01-09-print_hex1_TB.s existe
> ✅️ ../print_hex1.s existe
> ✅️ 2026-01-09-hex_digit_SOL.s existe
> Probando: 2026-01-09-print_hex1_TB.s
> Ejecutando: java -jar rars1_6.jar x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 nc me ic 10000 dump 0x10010000-0x10010100 HexText data.hex dump .text HexText text.hex 2026-01-09-print_hex1_TB.s ../print_hex1.s 2026-01-09-hex_digit_SOL.s
> ☑️  Hay segmento de datos
> ✅️ Hay segmento de código
  ──────── Salida en consola
0x5
* Convenio: OK
0xA
* Convenio: OK

  ──────── Resultado
> ✅️ prueba 1 OK!
> ✅️ prueba 2 OK!
> ✅️ Uso correcto de registros estaticos
> ✅️ PERFECTO!!
  ──────── Comprobaciones finales
> ✅️ Se termina con EXIT
> Instrucciones totales: 242
> Ciclos de ejecución: 269
────────────────────────────────────────
  • Ejecutamos el script run3.py
obijuan@JANEL:~/test/Parcial3/arquibot-0.5$ ./run3.py 
────────────────────────────────────────
ARQUI-BOT 0.5
────────────────────────────────────────
> ☑️  RARS EXISTE
> ✅️ ../main.s existe
> ✅️ 2026-01-09-hex_digit_SOL.s existe
> ✅️ 2026-01-09-print_hex1_SOL.s existe
> Probando: ../main.s
> Ejecutando: java -jar rars1_6.jar x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 nc me ic 10000 dump 0x10010000-0x10010100 HexText data.hex dump .text HexText text.hex ../main.s 2026-01-09-hex_digit_SOL.s 2026-01-09-print_hex1_SOL.s
> ☑️  Hay segmento de datos
> ✅️ Hay segmento de código
  ──────── Salida en consola
0x0
0x1
0x2
0x3
0x4
0x5
0x6
0x7
0x8
0x9
0xA
0xB
0xC
0xD
0xE
0xF

  ──────── Comprobando salida en consola
0x0
0x1
0x2
0x3
0x4
0x5
0x6
0x7
0x8
0x9
0xA
0xB
0xC
0xD
0xE
0xF

> ✅️ ¡Salida exacta!
  ──────── Comprobaciones finales
> ✅️ Se termina con EXIT
> Instrucciones totales: 53
> Ciclos de ejecución: 770
────────────────────────────────────────

Autores

Licencia

Enlaces

Página principal


Sesiones de Prácticas

P1: Simulador RARs

L1: El simulador RARs
L2: Calculando expresiones
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

SESIONES ADICIONALES

L13: RV32I: Resto de instrucciones
L14: Macros
L15: Entrada/Salida a bajo nivel
L16: Multiplicaciones/divisiones. Unit Tests 🚧
L17: Biblioteca stdio: salida a alto nivel 🚧
Los registros de estado y control (CSR)
Interrupciones y excepciones
Borrador

SOLUCIONES

Soluciones a los ejercicios planteados en cada sesión para practicar:
Sesión L1
Sesión L2
Sesión L3
Sesión L4
Sesión L5
Sesión L6
Sesión L7
Sesión L8
Sesión L9
Sesión L10
Sesión L11
Sesión L12

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
GISAM. Extra. 2025-Jun-17
GISAM. Parcial 1. 2025-Oct-20
GISAM. Parcial 2. 2025-Nov-19
GISAM. Parcial 3. 2026-Enero-9
GISAM. Parcial 1. 2026-Oct-21
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
TELECO. Extra. 2025-Jun-17
TELECO. Parcial 1. 2025-Oct-10
TELECO. Parcial 2. 2025-Nov-13
TELECO. Parcial 3. 2026-Ene-21
TELECO. Extra. 2026-Jun-25
TELECO. Parcial 1. 2026-Oct-09
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
Robótica. Parcial 1. 2025-Feb-25
Robótica. Parcial 2. 2025-Mar-31
Robótica. Parcial 3. 2025-May-19
Robótica. Parcial 1. 2026-Feb-23
Robótica. Parcial 2. 2026-Abr-13
Robótica. Parcial 3. 2026-May-11
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
Datos. Parcial 1. 2025-Oct-15
Datos. Parcial 2. 2025-Nov-19

Clone this wiki locally