Skip to content

Ejercicios III

Juan Gonzalez-Gomez edited this page Jun 18, 2019 · 3 revisions

Solución al examen de prácticas de Junio-2019

El examen de prácticas fue el 18-Junio-2019. Aquí está disponible el enunciado y las soluciones

Contenido

Enunciado

  • IMPORTANTE: El enunciado de un examen se consideran las especificaciones de un mini-proyecto a realizar. En ingeniería partimos siempre de unas especificaciones, y a partir de ellas tenemos que solucionar un problema. Si se implementa otra cosa diferente a lo indicado en estas especificaciones, tu solución NO es válida. Por eso siempre es muy importante dedicar tiempo a entender bien el enunciado, y asegurarse de que cumplimos con las restricciones impuestas en él

Enunciado en PDF

Enunciado en la wiki

AVISO: Asegúrate que tus programas cumplen con los siguientes criterios. Si no se cumple alguno de ellos la nota máxima de tu examen será de 2 puntosCumplimiento de especificaciones. Se deben cumplir las especificaciones indicadas en el enunciado: nombres de funciones, nombres de archivos, funcionalidad, número de parámetros, etc. Compruébalo antes de entregar el examen • Respetar el convenio. Resuelve las preguntas sin violar el convenio del uso de registros • Sin errores en tiempo de ejecución (Runtime errors). Tus programas no deben generar excepciones al ejecutarse

Necesitamos crear la función void upper(char *pstr) que recibe como argumento un puntero a una cadena de caracteres y convierte esa cadena a mayúsculas. Los caracteres que ya estuviesen en mayúsculas se quedan igual, así como el resto de caracteres que NO son letras. Por tanto, sólo hay que convertir los caracteres desde la ‘a’ a la ‘z’ en mayúsculas, dejando el resto como estuviesen Por ejemplo, la cadena “..Summer is coming..-2019\n” se convertirá a “..SUMMER IS COMING..-2019\n” al aplicar esta función (Recuerda que el carácter ‘\n’ es el salto de línea)

Para su implementación, el jefe de proyecto ha determinado que se debe llamar a la función void upper_char(char *c) , la cual realiza el paso a mayúsculas de un único carácter, cuyo puntero se pasa como parámetro (c)

Se pide implementar las siguientes funciones y los programas principales indicados:

  1. Función upper_char (2 ptos): void upper_char(char *c): Pasar a mayúsuclas el carácter apuntado por c. Para pasar un carácter a mayúsuclas basta con restarle 32 a su código ASCII. Esta operación sólo se realiza con los caracteres de la ‘a’ (código ascii 97) a la ‘z’ (código ascii 122). El resto de caracteres se deja como estaban. Esta función se debe implementar en el fichero upper_char.asm

  2. Programa principal de prueba de upper_char (1 pto). Dentro del fichero upper_char.asm se debe incluir un programa principal que compruebe que la función upper_char funciona correctamente. Deberá definirse una cadena en tiempo de compilación, imprimirla en la consola, llamar a la función upper_char para convertir a mayúsuclas el primer carácter, imprimir la nueva cadena y terminar

  3. Función upper (4 ptos): void upper(char *pstr). Convertir a mayúsuclas la cadena apuntada por el puntero pasado como parámetro. Se debe usar un algoritmo iterativo que recorra la cadena, convirtiendo cada uno de los caracteres a mayúsculas llamando a la función upper_char. Se debe implementar en el fichero upper.asm

  4. Programa principal de prueba de upper (1 pto). Dentro del fichero upper.asm se debe incluir un programa principal que compruebe que la función upper funciona correctamente. Deberá definirse la siguiente cadena en tiempo de compilación :“..Summer is coming..-2019\n”, imprimirla en la consola, convertirla a mayúsculas llamando a upper, imprimirla en la consola y terminar

  5. Fichero upper2.asm (2 ptos). Ampliar el programa anterior para que además de la conversión anterior, pida al usuario una cadena en tiempo de ejecución, la imprima en mayúsculas en la consola y termine. Se debe implementar en el fichero upper2.asm (Por tanto, este programa hace dos conversiones a mayúsculas, una de la cadena definida en tiempo de compilación, y otra con la cadena introducida por el usuario en tiempo de ejecución)

Solución

Solución (con explicaciones)

  • upper_char.asm:
##---- Examen practicas de Arquitectura de Ordenadores
##-- Escribe tus datos

##-- NOMBRE: Obijuan
##-- APELLIDOS: 

##-- Antes de empezar a escribir código leemos el enunciado
##-- Después, lo volvemos a leer. Hay que dedicar tiempo a pensar
##-- Lo que no esté especificado, lo tendrás que decidir tu
##-- Tú eres el ingeniero/a. Tendrás que decidir que es lo más 
##-- adecuado, sin violar especificaciones
#-- 

#---------------------------------------------------
#--  IMPLEMENTA AQUI EL PROGRAM PRINCIPAL
#---------------------------------------------------

	.data
	
	 #-- ESPECIFICACION DEL ENUNCIADO: Cadena definida en tiempo de compilacion
	 #-- Es la que queremos pasar a Mayusculas 
	 #-- Podemos elegir cualquier cadena. Lo unico que necesitamos
	 #-- es que tenga al menos un carácter, ya que en este programa
	 #-- principal sólo vamos a probar la función upper_char()
	 #-- para convertir el primer carácter a mayúsculas
test:   .asciz "test\n"

	 #-- Para el examen basta con hacer un caso de prueba
	 #-- Pero yo aprovecharia para comprobar más casos, antes de
	 #-- de pasar a la implementacion de upper().
	 #-- ¿Que pasa si el primer caracteres es una mayusucula?
	 #-- La deberia dejar tal cual, sin nmodificar
	 #-- Que pasa si es un caracter que no es letra, como el asterisco por ejemplo?
	 #-- ¿Funciona mi funcion en esos casos?


        #-- Aquí empieza nuestro código del programa principal
	.text
	
	#-- ESPECIFICACION DEL ENUNCIADO:
	#-- Imprimir cadena original de test
	la a0, test
	li a7, 4
	ecall
	
	#-- ESPECIFICACION DEL ENUNCIADO:
	#-- Llamar a la funcion upper_char con el primer caracter
	#-- de la cadena
	la a0, test     #-- Direccion del primer caracter de la cadena
	jal upper_char
	
	#-- ESPECIFICACION DEL ENUNCIADO:
	#-- Imprimir la cadena con el primer caracter en mayusculas
	la a0, test
	li a7, 4
	ecall
	
	#-- Para mayor legibilidad de las pruebas, si se imprimen las 
	#-- lineas por separado es mejor. Por eso  he añadido un \n al 
	#-- final de la cadena test. Pero esto es decision de cada uno
	
	#-- ESPECIFICACION DEL ENUNCIADO: Terminar
	#-- Pero aunque el enunciado no me lo dijese, sabemos que SIEMRPRE
	#-- tenermos que terminar nuestros programas devolviendo el 
	#-- control al sistema operativo
	li a7, 10  #-- Servicio exit
	ecall



#----------------------------------------------------
#- IMPLEMENTA AQUI LAS FUNCIONES NECESARIAS
#----------------------------------------------------


#------------------------------------------------------------
#- Funcion upper_char(): Convertir un caracter a mayusculas  
#- Entradas:
#-   a0: Direccion del caracter a convertir a mayusculas
#- Devuelve:
#-   Nada
#------------------------------------------------------------
upper_char:

        #--- No hace falta crear ninguna pila porque desde esta
        #--- funcion no llamamos a niguna otra, y por tanto no hace
        #--- falta guardar el registro ra
        #--- Tambpoco necesitamos guardar en la pila ninugna
        #-- otra información relevante
        
        #-- ¿Y si se pone unna pila? Bueno, no es crítico,
        #--  Lo único que tu programa estará ejecutando
        #-- instrucciones que realmente no son necesarias (no es óptimo)
	
	#-- Leer el caracter que queremos pasar a mayusculas
	#-- Este caracter está almacenado en memoria, en la dirección
	#-- indicada por a0, que es el puntero pasado como argumento
	lb t0, 0(a0)
	
	#---- Comprobar si el caracter esta en el rango ['a' - 'z']: ASCII: [97, 122]
	#-- Si Es menor que 'a' (97): No convertir
	li t1, 'a'
	blt t0, t1, fin_upper_char
	
	#-- Comprobar si es mayor que 'z'
	li t1, 'z'
	addi t1, t1, 1
	bge t0, t1, fin_upper_char
	
	#-- Si llegamos aqui es porque el caracter esta
	#-- en minusculas (entre 'a' y 'z')
	#-- Restamos 32 y lo guardamos
	
	addi t0, t0, -32
	sb t0, 0(a0)
	
	#--- Esta comprobacion hay multiples formas de hacerla
	
	#-- Retornar de la funcion
fin_upper_char:	
	ret
  • upper.asm:
##---- Examen practicas de Arquitectura de Ordenadores
##-- Escribe tus datos

##-- NOMBRE: Obijuan
##-- APELLIDOS:

#---------------------------------------------------
#--  IMPLEMENTA AQUI EL PROGRAM PRINCIPAL
#---------------------------------------------------
	.data
	
	####---- ESPECIFICACION DEL ENUNCIADO: Nos indicas que se use esta cadena
	####---- definida en tiempo de compilacion
	####--- Tiene que ser esta cadena por ESPECIFICACION.
	####--- Si además queremos añadir alguna más, adelante
cad:	.asciz "**Summer is coming**-2019\n"

	.text
	
	
	#--- ESPECIFICACION DEL ENUNCIADO: Imprimir la cadena originl
	la a0, cad
	li a7, 4
	ecall

	#-- ESPECIFICACION DEL ENUNCIADO: Llamar a upper()
	#-- Llamar a upper() para convertirla a mayusculas
	la a0, cad
	jal upper
	
	#-- Imprimir la nueva cadena
	#-- ESPECIFICACION DEL ENUNCIADO: Imprimir la nueva cadena
	la a0, cad
	li a7, 4
	ecall
	
	#-- No se dice nada del formato de cómo deben salir en pantalla, así que
	#-- podemos elegir el que nostros queramos.
	#-- Para que sea más legible, lo más lógico es imprimir una cadena y debajo
	#-- la otra, para compararlas mejor. Pero esto es decisión de cada uno
			
	#-- Terminar
	li a7, 10
	ecall
	
	
#----------------------------------------------------
#- IMPLEMENTA AQUI LAS FUNCIONES NECESARIAS
#----------------------------------------------------		

#----------------------------------------------------------
#-- Funcion upper(a0): Pasar una cadena a mayusculas
#-- Entradas:
#--   a0: Puntero a la cadena
#-- Devuelve:
#--   nada
#-----------------------------------------------------------
upper:

	#-- Tenemos que usar pila obligatoriamente, porque
	#-- se debe llamar a la funcion upper_char()

	addi sp, sp, -32
	sw ra, 28(sp)
	sw s0, 24(sp)
	addi s0,sp,28

upper_loop:	
			
	#-- ESPECIFICACION DEL ENUNCIADO: Algoritmo iterativo
			
	#-------- Recorrer la cadena hasta llegar al final
	lb t0, 0(a0)  #-- Leer caracter actual
	beq t0, zero, fin_upper  #-- Es 0? hemos terminado
	
	#-- No hemos llegado al final de la cadena
	#-- Convertir el caracter actual a mayusculas
	#-- Almacenar a0 en la pila para no perderlo (No violar el convenio)
	sw a0, -20(s0)
	
	##-- ESPECIFICACION DEL ENUNCIADO: Hay que llamar a la funcion upper_char
	jal upper_char
	
	#-- Recuperar a0 de la pila
	lw a0, -20(s0)
	
	#-- Apuntar al siguiente caracter
	addi a0, a0, 1
	
	#-- Repetir
	b upper_loop
	

fin_upper:			
	lw ra, 28(sp)
	lw s0, 24(sp)
	addi sp,sp,32

	ret

#--- Esta es la misma funcion upper_char que tenemos en el fichero upper_char.asm
#--- Para que funcione el programa completo la ponemos aqui
#--- (hacemos copy & paste)

#------------------------------------------------------------
#- Funcion upper_char(): Convertir un caracter a mayusculas  
#- Entradas:
#-   a0: Direccion del caracter a convertir a mayusculas
#- Devuelve:
#-   Nada
#------------------------------------------------------------
upper_char:
	
	#-- Leer el caracter que queremos pasar a mayusculas
	lb t0, 0(a0)
	
	#---- Comprobar si el caracter esta en el rango ['a' - 'z']: ASCII: [97, 122]
	#-- Es menor que 'a' (97): No convertir
	li t1, 'a'
	blt t0, t1, fin_upper_char
	
	#-- Es mayor que 'z'
	li t1, 'z'
	addi t1, t1, 1
	bge t0, t1, fin_upper_char
	
	#-- El caracter esta en minusculas
	#-- Restamos 32 y lo guardamos
	
	addi t0, t0, -32
	sb t0, 0(a0)
	
fin_upper_char:	
  • upper2.asm:
##---- Examen practicas de Arquitectura de Ordenadores
##-- Escribe tus datos

##-- NOMBRE: Obijuan
##-- APELLIDOS: 

#---------------------------------------------------
#--  IMPLEMENTA AQUI EL PROGRAM PRINCIPAL
#---------------------------------------------------



	.data
cad:	.asciz "**Summer is coming**-2019\n"

#---- ESPECIFICACION DEL ENUNCIADO: Cadena definida en tiempo de ejecutacion
#---- La itnroduce el usuario
#---- El enunciado no nos dice nada del tamaño máximo. Usamos el que nosotros queramos
#--- aplicando el sentido común para poder probar
cad2:   .space 200

	.text
	
	
	#--- ESPECIFICACION DEL ENUNCIADO: Debe hacer lo mismo que
	#-- el programa principal de upper.asm
	
	#-- Imprimir la cadena completa
	la a0, cad
	li a7, 4
	ecall

	#-- Llamar a upper() para convertirla a mayusculas
	la a0, cad
	jal upper
	
	#-- Imprimir la nueva cadena
	la a0, cad
	li a7, 4
	ecall
	
	
	#---- Ampliacion------------------------
	
	#-- Pedir al usuario la cadena
	la a0, cad2
	li a1, 200
	li a7, 8
	ecall

	#-- Llamar a upper() para convertirla a mayusculas
	la a0, cad2
	jal upper
	
	#-- Imprimir la nueva cadena
	la a0, cad2
	li a7, 4
	ecall
			
	#-- Terminar
	li a7, 10
	ecall
	
	
#----------------------------------------------------
#- IMPLEMENTA AQUI LAS FUNCIONES NECESARIAS
#----------------------------------------------------	
		
#-- Hacemos copy&paste de las funciones upper() y upper_char() para
#-- realizar las pruebas				
				
				
#----------------------------------------------------------
#-- Funcion upper(a0): Pasar una cadena a mayusculas
#-- Entradas:
#--   a0: Puntero a la cadena
#-- Devuelve:
#--   nada
#-----------------------------------------------------------
upper:

	addi sp, sp, -32
	sw ra, 28(sp)
	sw s0, 24(sp)
	addi s0,sp,28

upper_loop:	
			
	#-------- Recorrer la cadena hasta llegar al final
	lb t0, 0(a0)  #-- Leer caracter actual
	beq t0, zero, fin_upper  #-- Es 0? hemos terminado
	
	#-- No hemos llegado al final de la cadena
	#-- Convertir el caracter actual a mayusculas
	#-- Almacenar a0 en la pila para no perderlo (No violar el convenio)
	sw a0, -20(s0)
	jal upper_char
	
	#-- Recuperar a0 de la pila
	lw a0, -20(s0)
	
	#-- Apuntar al siguiente caracter
	addi a0, a0, 1
	
	#-- Repetir
	b upper_loop
	

fin_upper:			
	lw ra, 28(sp)
	lw s0, 24(sp)
	addi sp,sp,32

	ret

#------------------------------------------------------------
#- Funcion upper_char(): Convertir un caracter a mayusculas  
#- Entradas:
#-   a0: Direccion del caracter a convertir a mayusculas
#- Devuelve:
#-   Nada
#------------------------------------------------------------
upper_char:
	
	#-- Leer el caracter que queremos pasar a mayusculas
	lb t0, 0(a0)
	
	#---- Comprobar si el caracter esta en el rango ['a' - 'z']: ASCII: [97, 122]
	#-- Es menor que 'a' (97): No convertir
	li t1, 'a'
	blt t0, t1, fin_upper_char
	
	#-- Es mayor que 'z'
	li t1, 'z'
	addi t1, t1, 1
	bge t0, t1, fin_upper_char
	
	#-- El caracter esta en minusculas
	#-- Restamos 32 y lo guardamos
	
	addi t0, t0, -32
	sb t0, 0(a0)
	
fin_upper_char:	
	ret

Autores

Licencia

Enlaces

Página principal


Sesiones de Prácticas

Práctica 1: Simulador RARs

L1: Práctica 1-1. Rars
L2: Práctica 1-2. Ensamblador
L3: Práctica 1-3. Formato

Práctica 2: Llamadas al sistema

L4: Práctica 2-1
L5: Práctica 2-2. Datos

Práctica 3: Bucles. Saltos Condicionales

L6: Práctica 3-1
L7: Práctica 3-2

Práctica 4: LLamada a subrutina

L8: Práctica 4-1
L9: Práctica 4-2. Pila
L10: Práctica 4-3. Recursividad

Práctica 5: Memoria dinámica

L11: Práctica 5

Ejercicios

Ejercicios I
Solución examen Abril-2019
Solución examen Junio-2019

Exámenes

  • Ordinario (Lab): 26-Abril-2019. L3.202/3. 11-13h
  • Ordinario (Teoría): 6-Mayo-2019. L3.210. 9h - 12h
  • Final (Teoría y Lab): 18-Junio-2019. L3.210. 9h-11h Teoría. 11-13h Práctica

Material de apoyo

Simulador RARS

Clone this wiki locally