-
Notifications
You must be signed in to change notification settings - Fork 22
Examen: 2019_12_13:Teleco
- Tiempo: 2h
-
Objetivo:
- Resolver el problema de examen de la convocatoria ordinadira de los grados de IST, ITT, IT, IT-ADE y IT-AEROESPACIAL, con fecha 2019/Dic/113
- Aquí está disponible el Enunciado en PDF
- Animación con un ejemplo del funcionamiento del programa:
TODO
Los cuatro ficheros pedidos son los siguientes:
- Fichero atoi.s
#------------------------------------------------------------------------------------
#-- Subrutina atoi1(char): Convertir el caracter a su numero correspondiente
#--
#-- Si el caracter es un digito válido ('0' - '9') se devuelve su valor
#-- Si el caracter no es valido se devuelve -1
#--
#-- ENTRADAS:
#-- a0: Caracter
#--
#-- SALIDA:
#--- a0: Digito convertido a numero ó -1 si no es un digito correcto
#------------------------------------------------------------------------------------
#-- Punto de entrada
.globl atoi1
#-- Código de error
.eqv ERROR -1
.text
atoi1:
#--- Es una función Hoja: No necesitamos almacenar la
#-- direccion de retorno al nivel superior
#-- Tampoco necesitamos preservar el valor de ningún registro
#-- Por tanto no creamos pila
#--- Por a0 os llega el parametro de entrada
#--- El carácter a convertir
#-- Comprobamos primero si es un dígito correcto
#-- Si a0 < '0' ó a0 > '9', es un digito incorrecto, y hay
#-- que devolver -1
#-- Si a0 < '0' se retorna error
li t1, '0'
blt a0, t1, error
#-- Si a0 > '9' se retorna error
li t1, '9'
bgt a0, t1, error
#-- Es un digito valido. Convertirlo a numero
#-- Para ello hay que restar '0'
li t1, '0'
sub a0, a0, t1
#-- En a0 está el numero convertido (0 - 9)
b ok
error:
li a0, ERROR
ok:
ret
- Fichero evaluar.s
#----------------------------------------------------
#-- SUBRUTINA int evaluar(cad)
#--
#-- Evaluar la cadena, que debe estar compuesta por números
#-- de un solo digito y el caracter + de la suma
#--
#-- Ejemplo de cadenas correctas: "1+2", "1+2+3+4+5+5", "9+0+0+1+2+3"
#--
#-- ENTRADAS:
#-- a0: PUntero a la cadena con la expresion
#--
#-- SALIDAS:
#-- a0: Valor de la expresion
#-- -1 en caso de error
#----------------------------------------------------
#-- Punto de entrada
.globl evaluar
#-- Código de error
#-- Es valido tanto para lo que devuelve atoi
#-- como para lo que devuelve evaluar
.eqv ERROR -1
.text
evaluar:
#-- Es una funcion intermedia (recursiva) por lo que necesitaremos la pila para
#-- almacenar la direccion de retorno
#-- Además, la necesitamos para preservar el valor de algunos registros, ya que
#-- hay llamadas a subrutinas
#--- Crear la pila
addi sp, sp, -16
#-- Guardar la direccion de retorno
sw ra, 12(sp)
#-- Guardar la direccion del primer caracter,
#-- para no perderlo a0 para no perderlo (puntero al primer caracter)
sw a0, 0(sp)
#-- Leer el primer caracter. Es el operando 1 (op1)
lb t0, 0(a0)
#-- if cad=="\n":
#-- return -1
li t1, '\n'
beq t0, t1, error
#-- Convertir el primer digito a numero (op1)
#-- op1 = atoi(cad[0])
mv a0, t0
jal atoi1
#-- Si la conversion falla, se devuelve error
#-- if op1 == -1:
# return -1
li t0, ERROR
beq a0, t0, error
#-- El primer digito es un numero ok
#-- Lo preservamos en la pila
sb a0, 4(sp)
#-- Si el siguiente carácter es “\n”, la expresion
#-- tiene solo un digito: devolvermos su valor
# if cad[1]=="\n":
# return op1;
lw a1, 0(sp) #-- Recuperar puntero a la expresion
lb t0, 1(a1) #-- Leer el segundo caracter
#-- Si es \n, devolver el numero
li t1, '\n'
beq t0, t1, fin_op1
#-- Si el segundo carácter NO es '+', se devuelve error
# if cad[1]!='+':
# return -1 #-- Error
li t1, '+'
bne t0, t1, error
#-- Evaluar la expresion contenida en la subcadena desde el
#-- tercer carácter hasta el final, llamando a evaluar(recursivo)
#-- op2 = evaluar(cad[2:])
addi a0, a1, 2
#-- Llamar a evaluar
jal evaluar
#-- si op2 es -1 ha habido un error
# if op2 == -1:
# return -1
li t0, ERROR
beq a0, t0, error
#-- Evaluar la suma del primer digito más el valor de la subcadena
# return op1 + op2
#-- Metemos en a1 el op1, que estaba en la pila
lb a1, 4(sp)
#-- Hacemos la suma de op1 + op2
#-- a0 = a0 + a1
add a0, a0, a1
b fin
#-- Retornar el operando 1 (que ya esta en a0)
fin_op1:
b fin
#-- Retornar el codigo de error
error:
li a0, ERROR
b fin
fin:
#-- Recueprar la direcciond e retorno
lw ra, 12(sp)
#-- Liberar la pila
addi sp, sp, 16
ret
- Fichero procesar.s
#-------------------------------------------
#-- Funcion int procesar()
#--
#-- Pedir cadena al usuario, evaluarla, imprimir el resultado y retornar, devolviendo el valor calculado
#-- Si el usuario introduce la cadena nula, se termina con codigo de error -2
#-- Si hay un error al evaluar, se imprime mensaje de error y se devuelve código -1
#--
#-- ENTRADAS:
#-- Ninguna
#--
#-- SALIDAS:
#-- * Si la cadena introducida por el usuario es nula, se retorna el código -2
#-- * Si la evaluacion da un error, se retorna -1
#-- * En caso contrario se devuelve el valor calculado
#-------------------------------------------------------------------
#-- Codigos de los servicios del Sistema operativo
.eqv EXIT 10
.eqv PRINT_STRING 4
.eqv READ_STRING 8
.eqv PRINT_INT 1
#-- Codigos de retorno
.eqv TERMINAR -2
.eqv ERROR -1
#-- Valor máximo de la cadena
.eqv MAX 100
#-- Punto de entrada
.globl procesar
.data
#-- Cadena que se pide al usuario, con la expresion a evaluar
msg1: .string "\n\nIntroduce expresion a calcular: "
msg2: .string "Resultado: "
msg_err: .string "Error!\n"
exp: .space MAX
.text
procesar:
#-- Es una funcion intermedia. Necesitamos crear la pila
#-- para guardar la direccion de retorno
addi sp, sp, -16
#-- Guardar la direccion de retorno
sw ra, 12(sp)
#--- Imprimir mensaje 1
la a0, msg1
li a7, PRINT_STRING
ecall
#-- Pedir cadena
la a0, exp
li a1, MAX
li a7, READ_STRING
ecall
#-- Comprobar si es la cadena vacia
lb t0, 0(a0)
li t1, '\n'
beq t0, t1, cad_nula
#-- Llamar a evaluar
jal evaluar
#-- comprobar si la hay error o no
li t0, ERROR
beq a0, t0, error
#-- Todo ok. a0 contiene el valor de la evaluacion
mv t0, a0
#-- Imprimir mensaje 2
la a0, msg2
li a7, PRINT_STRING
ecall
#-- Imprimir resultado de la evaluacion
mv a0, t0
li a7, PRINT_INT
ecall
#-- a0 contiene el valor evaluado
#-- Retornar
b fin
#-- Error de evaluacion
error:
la a0, msg_err
li a7, PRINT_STRING
ecall
#-- MEter en a0 el codigo de error
li a0, ERROR
b fin
#-- Terminar indicando codigo de retorno de cadena nula
cad_nula:
li a0, TERMINAR
fin:
#-- Recuperar la direccion de retorno
lw ra, 12(sp)
#-- Liberar la pila
addi sp, sp, 16
ret
- Fichero main.s
#------------------------------------------------------------------------------
#--- Programa principal
#------------------------------------------------------------------------------
#-- Codigos de los servicios del Sistema operativo
.eqv EXIT 10
.eqv PRINT_STRING 4
.eqv READ_STRING 8
.eqv PRINT_INT 1
#-- Codigos de retorno
.eqv TERMINAR -2
.eqv ERROR -1
#-- Longitud maxima de la expresion
.eqv MAX 100
.data
msg1: .string "EVALUACION DE EXPRESIONES\n"
msg2: .string "\nEvaluaciones ok: "
exp: .space MAX
.text
#-- Imprimir mensaje 1
la a0, msg1
li a7, PRINT_STRING
ecall
#-- Contador de expresiones evaluadas correctamente evaluadas
li s0, 0
bucle:
#-- Llamar a procesar
jal procesar
#-- a0 contiene el codigo de retorno
#-- Si se recibe el codigo TERMINAR
#-- se sale del bucle
li t0, TERMINAR
beq a0, t0, fin
#-- Comprobar si se ha evaluado correctamente o no
li t1, ERROR
beq a0, t1, bucle
#-- Se ha evaluado ok. Incrementamos el contador
addi s0, s0, 1
#-- Repetir
b bucle
fin:
#--- Imprimir mensaje 2
la a0, msg2
li a7, PRINT_STRING
ecall
#-- Imprimir el contador de evaluaciones ok
mv a0, s0
li a7, PRINT_INT
ecall
#-- Terminar
li a7, EXIT
ecall
- Katia Leal Algara
- Juan González-Gómez (Obijuan)
L1: Práctica 1-1. RARs
L2: Práctica 1-2. Ensamblador
L3: Práctica 1-3. Variables
L4: Pract 2-1. E/S mapeada
L5: Práctica 2-2: Inst. ecall
L6: Prác 2-3: Cadenas
L7: Práct 3-1: Bucles y saltos
L8: Práct 3-2: Cadenas II
L9: Pract 4-1: Subrut. Nivel-1
L10: Pract 4-2: La pila
L11: Pract 4-3: Recursividad
L12: Pract 5-1. Heap. Listas
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
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