Examen: 2021_07_02:Teleco - myTeachingURJC/2019-20-LAB-AO GitHub Wiki
Examen convocatoria extraordinaria: 2021-07-02. Teleco
- Tiempo: 2h
- Descripción: Examen del Laboratorio de los grados de Teleco. Convocatoria extraordinaria
- Fecha: 2021/Julio/02
Contenido
Enunciado
- Aquí está disponible el Enunciado en PDF
- Aquí están las Plantillas: Plantillas.zip
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 dos ficheros de una posible solución:
- Fichero sumav.s
# ------------------------------------------------
# - Funcion sumav(u_x, u_y, v_x, v_y)
# - w = u + v
# - Suma de los vectores u y v. Cada vector
# - tiene dos componentes: x, y
# -
# - ENTRADAS:
# - a0: Comp. x del primer vector
# - a1: Comp. y del primer vector
# - a2: Comp. x del segundo vector
# - a3: Comp. y del segundo vector
# - SALIDA:
# - a0: Comp. x del vector resultado
# - a1: Comp. y del vector resultado
# -----------------------------------------------
.globl sumav
.text
sumav:
# -- Obtener la componente x del vector resultante
add a0, a0, a2
# -- Obtener la componente y del vector resultante
add a1, a1, a3
# -- Terminar
ret
- Fichero sumav_test.s
# -- Programa sumav_test.s
# -- Prueba de la funcion sumav()
# -- Suma de 3 vectores almacenados en la memoria
# -- El resultado se muestra en la consola
# -- Constantes
.eqv EXIT 10
.eqv PRINT_INT 1
.eqv PRINT_CHAR 11
.data
# -- Array de vectores
vectores: .word 1, 2 #-- Vector v1: (1,2)
.word 3, 5 #-- Vector v2: (3,5)
.text
la s0, vectores #-- Puntero a los vectores
# -- Leer el primero
lw a0, 0(s0) # u.x
lw a1, 4(s0) # u.y
# -- Leer el segundo
lw a2, 8(s0) # v.x
lw a3, 12(s0) # v.y
# -- Realizar la suma
jal sumav
# -- a0,a1 contienen el resultado
# -- w = (a0, a1)
# -- Imprimir componente x resultado
# -- (Esta en a0)
li a7, PRINT_INT
ecall
# -- Imprimir una ',' de separacion
li a0, ','
li a7, PRINT_CHAR
ecall
# -- Imprimir componente y del resultado
# -- (esta en a1, que no se modificado)
mv a0, a1
li a7, PRINT_INT
ecall
# -- Terminar
li a7, EXIT
ecall
Parte II
- Fichero printv_test.s
# -- Programa de prueba de la funcion printv
# -- Se imprimen 5 vectores en la consola
# -- desde el (100, 10) hasta el (105, 15):
# --
# -- SALIDA EN LA CONSOLA:
# --
# -- (100,10)
# -- (101,11)
# -- (102,12)
# -- (103,13)
# -- (104,14)
# ----------------------------------------------------
# Funcion printv_test(n)
# Imprimir una lista de n vectores de prueba
# ENTRADAS:
# a0: Numero de vectores de prueba a imprimir
# SALIDAS:
# Ninguna
# En la consola se imprimen los n vectores de pruebas
# Ej. para n = 3
# (100, 10)
# (101, 11)
# (102, 12)
#----------------------------------------------------
.globl printv_test
.text
printv_test:
# -- Como es una funcion intermedia (Es una funcion que a su
# -- vez llama a otra funcion). Es necesario crear la pila
# -- para guardar la direccion de retorno
addi sp, sp, -16
#-- Guardar direccion de retorno
sw ra, 12(sp)
#-- Como en el trozo de codigo que NO podemos modificiar se estan
#-- usando los registros estaticos s0, s1 y s2, para cumplir con
#-- el convenio de la ABI del RISCV hay que guardarlos en la pila
#-- para no perder su valor. Y recuperarlo antes de retornar
sw s0, 0(sp)
sw s1, 4(sp)
sw s2, 8(sp)
# -- El numero de vectores a imprimir se recibe por a0
.eqv N 5
.text
# -- Numero de vectores a imprimir
# -- Se recibe en a0
mv s2, a0
# ---- [INICIO BLOQUE] NO MODIFICAR
# --- Desde aquí hasta el final del bloque indicado en los comentarios
# -- No puedes modificar nada. Desde aquí hacia arriba puedes cambiar
# -- lo que consideres necesario
# -- Contador para la coordenada x
li s0, 100
#-- Valor coordenada y inicial
li s1, 10
bucle:
#-- Imprimir el vector
mv a0, s0
mv a1, s1
jal printv
# -- Incrementar componentes x, y
addi s0, s0, 1
addi s1, s1, 1
# -- Un vector menos por imprimir
addi s2, s2, -1
#-- Si ya no quedan vectores, terminar
beq s2, zero, fin
#-- Repetir
b bucle
fin:
# ----- [FIN DE BLOQUE]-- Las instrucciones de aqui hacia el inicio del bloque
# ----- no las puedes modificar. De aquí hacia abajo puedes modificar lo que quieras
# -- Recuperar los registros estaticos s0, s1 y s2 para cumpliar
# -- con el convenio de la ABI del RISCV
lw s0, 0(sp)
lw s1, 4(sp)
lw s2, 8(sp)
# -- Recuperar direccion de retorno
lw ra, 12(sp)
# -- Recuperar el puntero de pila
addi sp, sp, 16
# -- Retornar de la funcion
ret
- Fichero main.s
#-- Programa de pruebas de la funcion printv_test()
#-- Hay que pedir al usuario la cantidad de vectores de prueba a imprimir
#-- Esta operacion se repite hasta que el usuario introduce 0
#-- En ese momento se termina
# -- Servicios del sistema operativo
.eqv EXIT 10
.eqv PRINT_STRING 4
.eqv READ_INT 5
.data
msg1: .string "\nIntroduce numero de vectores de test: "
.text
bucle:
#-- Imprimir mensaje 1
la a0, msg1
li a7, PRINT_STRING
ecall
# -- Pedir al usuario el numero de vectores (n)
li a7, READ_INT
ecall
# -- Si se introduce el 0 terminamos
beq a0, zero, fin
# -- Imprimir los vectores
# -- Por a0 se pasa el numero de vectores a imprimir
jal printv_test
#-- Repetir
b bucle
fin:
# Terminar
li a7, EXIT
ecall
Autores
- Katia Leal Algara
- Juan González-Gómez (Obijuan)