Examen: 2020_07_03:GISAM - myTeachingURJC/2019-20-LAB-AO GitHub Wiki
Examen convocatoria extraordinaria: 2020-07-03. GISAM
- Tiempo: 1.5h
- Objetivo:
- Problema de examen de la convocatoria extraordinadira de GISAM, con fecha 2020/Jul/03
Contenido
Enunciado
- Aquí está disponible el Enunciado en PDF
- Plantillas entregadas
Solución comentada
PENDIENTE
Solución
Los cuatro ficheros pedidos son los siguientes:
- Fichero mult.s
.text
.globl mult
# -----------------------------------------------------
# --- Funcion mult(a,b): Calcular a * b
# -- Entradas:
#-- a0: Primero operando
#-- a1: Segundo operando
#-- Salidas
#-- a0: a*b
#-------------------------------------------------------
mult:
#-- Se trata de una funcion hoja, por lo que no es necesario
#-- crear la pila para almacenar la direccion de retorno
# -- El resultado de la multiplicacion se calcula
# -- en el registro temporal t0
li t0, 0
# -- Se utiliza un bucle para realizar a0 veces la operación
# -- t0 = t0 + a1
bucle:
#--- Si a0 = 0, terminar
beq a0, zero, fin
# -- Calcular t0 = t0 + a1
add t0, t0, a1
#-- Decremebtar a0
addi a0, a0, -1
b bucle
fin:
#-- Devolver el resultado
mv a0, t0
ret
- Fichero test_mult.s
##---------------------------------------------
# Programa de prueba de la multiplicacion
#----------------------------------------------
# -- Servicio de Exit del S.O
.eqv EXIT 10
.eqv PRINT_STRING 4
.eqv PRINT_INT 1
.eqv READ_INT 5
.eqv PRINT_CHAR 11
.data
msg1: .string "Introduce un numero entero no negativo: "
msg2: .string " * "
msg3: .string " = "
.text
# -- Pedir un numero al usuario
la a0, msg1
li a7, PRINT_STRING
ecall
li a7, READ_INT
ecall
#-- Almacenar el numero en s0
mv s0, a0
#-- Bucle para calcular la tabla de multiplicar
#-- Se usa el registro s1 como contador (0...10)
li s1, 0
bucle:
#--- Imprimir el mensaje del calculo: "Digito" * "numero" = "Resultado"
#-- Imprimir el numero del usuario
mv a0, s0
li a7, PRINT_INT
ecall
#-- Imprimir la cadeba " * "
la a0, msg2
li a7, PRINT_STRING
ecall
#-- Imprmir el contador
mv a0, s1
li a7, PRINT_INT
ecall
#-- Imprimir el igual
la a0, msg3
li a7, PRINT_STRING
ecall
# -- Realizar la multiplicacion s0 * s1
mv a0, s0
mv a1, s1
jal mult
mv t0, a0
# ------ Imprimir el resultado
# -- Resultado
mv a0, t0
li a7, PRINT_INT
ecall
# --- Imprimir un salto de linea
li a0, '\n'
li a7, PRINT_CHAR
ecall
#--- Incrementar el contador
addi s1, s1, 1
# -- Si s1 es menor a 11, repetir
li t0, 11
blt s1, t0, bucle
# -- La tabla está completa
# -- Terminar
li a7, EXIT
ecall
- Fichero exp.s
.text
.globl exp
# ---------------------------------------------
# - Funcion exp(a, n): Calcula a elevado a n
# * ENTRADAS
# a0: base (>=0)
# a1: Exponente (>0)
# * SALIDAS:
# a0: Devuelve el resultado (a elevado a n)
#----------------------------------------------
exp:
#-- Se trata de una funcion intermdia, que llama a otra función
#-- Por tanto debemos crear la pila para guardar la direcion de retorno
addi sp, sp, -16
#-- Guardar la direccion de retorno
sw ra, 12(sp)
#-- El registro s0 lo usamos para almacenar la base
#-- El registro s1 para el exponenete
#-- Para NO violar el convenio, tenemos que guardarlos en la pila
#-- ya que deben tener su valor original al terminar
sw s0, 8(sp)
sw s1, 4(sp)
#-- El calculo intermedio lo guardamos en s2, por lo que
#-- hay que preservar s2 primero en la pila
sw s2, 0(sp)
mv s0, a0 #-- Mover la base a s0
mv s1, a1 #-- Mover el exponente a s1
#-- El resultado de los calculos intermedios lo guardamos
#-- en s2, Inicialmente s2 = 1
li s2, 1
#-- Bucle que realiza el cálculo
bucle:
# -- Calcular base * s2 (Multiplicar la base por el resultado parcial)
mv a0, s0 #-- Base
mv a1, s2 #-- Resultado parcial
jal mult
#-- El resultado lo guardamos en s2
mv s2, a0
#-- Decrementar el exponente (que lo usamos de contador)
addi s1, s1, -1
#-- Cuando sea 0 hemos terminado
bgt s1, zero, bucle
#-- Hemos terminado
#-- El resultado se devuelve por a0
mv a0, s2
#-- Recuperar los registros estáticos de la pila
lw s0, 8(sp)
lw s1, 4(sp)
lw s2, 0(sp)
#- Recuperar la direccion de retorno
lw ra, 12(sp)
# -- Recuperar la pila
addi sp, sp, 16
ret
- Fichero: test_exp.s
##---------------------------------------------
# Programa de prueba de la multiplicacion
#----------------------------------------------
# -- Servicio de Exit del S.O
.eqv EXIT 10
.eqv PRINT_STRING 4
.eqv PRINT_INT 1
.eqv READ_INT 5
.eqv PRINT_CHAR 11
.data
msg1: .string "Introduce la base (no negativo): "
msg2: .string " ^ "
msg3: .string " = "
.text
# -- Pedir un numero al usuario
la a0, msg1
li a7, PRINT_STRING
ecall
li a7, READ_INT
ecall
#-- Almacenar el numero en s0
mv s0, a0
#-- Bucle para calcular la tabla de potencias
#-- Se usa el registro s1 como contador (1...10)
li s1, 1
bucle:
#--- Imprimir el mensaje del calculo: "base" ^ "exp" = "Resultado"
#-- Imprimir la base
mv a0, s0
li a7, PRINT_INT
ecall
#-- Imprimir la cadeba " elevado a "
la a0, msg2
li a7, PRINT_STRING
ecall
#-- Imprmir el contador (exponente)
mv a0, s1
li a7, PRINT_INT
ecall
#-- Imprimir el igual
la a0, msg3
li a7, PRINT_STRING
ecall
# -- Realizar la operacion s0 elevaod a s1
mv a0, s0
mv a1, s1
jal exp
mv t0, a0
# ------ Imprimir el resultado
# -- Resultado
mv a0, t0
li a7, PRINT_INT
ecall
# --- Imprimiir un salto de linea
li a0, '\n'
li a7, PRINT_CHAR
ecall
#--- Incrementar el contador
addi s1, s1, 1
# -- Si s1 es menor a 11, repetir
li t0, 11
blt s1, t0, bucle
# -- La tabla está completa
# -- Terminar
li a7, EXIT
ecall
Autores
- Katia Leal Algara
- Juan González-Gómez (Obijuan)