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

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

Licencia

Enlaces