Skip to content

L2: SOLUCIONES

Juan Gonzalez-Gomez edited this page Oct 1, 2025 · 20 revisions

Introducción

Solución a los ejercicios de la Sesión L2

Contenido

Ejercicio 1

(Ver enunciado)

  1. El programa suma-enteros.s tiene 5 instrucciones en código máquina. Para comprobarlo hay que ensamblar el programa y contar el número de filas de la columna que pone Code

  1. El programa tiene 5 instrucciones. Cada instrucción ocupa 4 bytes. Por tanto, su tamaño es de 5 * 4 = 20 bytes

  2. Para completar la tabla sólo hay que mirar en la columna que pone Address. Esa columna nos indica las direcciones donde se almacena cada una de las instrucciones. Como las instrucciones son siempre de 4 bytes (32-bits) estas direcciones siempre serán múltiplos de 4

Así es como queda la tabla que nos piden:

Direccion (alineada) Instrucción en código máq.
0x00400000 00000293
0x00400004 00000313
0x00400008 00128293
0x0040000c 00530333
0x00400010 ff9ff06f
  1. Lo que nos piden es que indiquemos qué byte es el que está almacenado en cada una de las posiciones de memoria. Dado que el byte es la unidad mínima de información en Informática, las memorias siempre tienen granularidad de bytes: es decir, que aunque almacenemos números mayores de 8-bits, siempre podemos acceder a los bytes individuales

Para completar la tabla tanemos que saber que el procesador RISC-V utiliza una ordenación de tipo Little-endian, lo que significa que el byte de menor peso de la instruccion siempre se almacena en la dirección más baja

Así es como queda la tabla pedida:

Dirección Byte
0x004000 93
0x004001 02
0x004002 00
0x004003 00
0x004004 13
0x004005 03
0x004006 00
0x004007 00
0x004008 93
0x004009 82
0x00400a 12
0x00400b 00
0x00400c 33
0x00400d 03
0x00400e 53
0x00400f 00
0x004010 6f
0x004011 f0
0x004012 9f
0x004013 ff
  1. El objetivo de este ejercicio es que practiques ejecutando el programa paso a paso. Pero para facilitar la depuración de estos programas, resulta muy útil colocar un Breakpoint en la instrucción j y ver lo que ocurre en la pasada número 25. Basta con darle al botón de play hasta que veamos que el registro x5 toma el valor 25. El resultado acumulado hasta el momento lo tenemos en x6, cuyo valor es de 325

Ejercicio 2

(Ver enunciado)

  1. Este es el programa que calcula la suma de los enteros pares
#-- Solucion al ejercicio 2
#-- Calcular la suma de los numeros pares
#-- 2 + 4 + 6 + 8 + 10 + ....

	.text

	#-- Inicializamos los registros x5,x6 a 0
	addi x5, x0, 0
	addi x6, x0, 0
	
	#-- Bucle principal
bucle:
	#-- Incrementar contador principal en dos unidades
	addi x5, x5, 2   #-- x5 = x5 + 2
	
	#-- Obtener termino i-esimo
	add x6, x6, x5  #-- x6 = x6 + x5
	
	#-- Repetir el bucle
	j bucle
  1. El número de instrucciones varía de una implementación a otra (Tu programa puede tener un número diferente). Este tiene 5 instrucciones

  2. Tiene 5 instrucciones. Cada instrucción ocupa 4 bytes. El tamaño que ocupa es de 5 * 4 = 20 bytes

  3. La tabla con las instrucciones en código máquina, y en qué dirección se encuentra cada una se muestra en esta tabla. Esta es la tabla del programa implementado en el punto 1 (tu programa puede tener otras instrucciones diferentes)

Direccion (alineada) Instrucción en código máq.
0x00400000 00000293
0x00400004 00000313
0x00400008 00228293
0x0040000c 00530333
0x00400010 ff9ff06f
  1. El valor obtenido es: 650

Ejercicio 3

(Ver enunciado)

  1. Programa que calcula la sucesión de Fibonacci:
# Sesion L2
#-- Solucion al ejercicio 3
#-- Calculo de la serie de fibonacci: 0, 1, 1, 2, 3, 5, 8, 21...
#-- La serie se puede ver en el registro x7
#-- x5 y x6 se utilizan para los calculos intermedios
	.text
	
	#-- Valores iniciales, 1, 1
	addi x5, x0, 0
	addi x6, x0, 1

bucle:		
	#-- Calcular siguiente término en t2
	add x7, x5, x6   # x7 = x5 + x6
	
	#-- Actualizar registros
	add x5, x6, x0  #-- x5 = x6
	add x6, x7, zero  #-- x6 = x7
	
	j bucle
  1. El valor del término 10 de fibonacci es 55 (Se obtiene cuando el bucle ha dado 8 vueltas porque en la primera se tiene el término 3. Los términos 1 y 2 son 0 y 1 respectivamente, que son los valores iniciales)

  2. Esta implementación del programa tiene 6 instrucciones. La tuya puede tener un número diferente

  3. Como tiene 6 instrucciones, y cada instrucción ocupa 4 bytes, el tamaño del programa es de 6 * 4 = 24 Bytes

  4. Tabla con el código máquina:

Direccion (alineada) Instrucción en código máq.
0x00400000 0x00000293
0x00400004 0x00100313
0x00400008 0x006283b3
0x0040000c 0x000302b3
0x00400010 0x00038333
0x00400014 9xff5ff06f
  1. Tabla con los bytes del programa
Dirección Byte
0x004000 93
0x004001 02
0x004002 00
0x004003 00
0x004004 13
0x004005 03
0x004006 10
0x004007 00
0x004008 b3
0x004009 83
0x00400a 62
0x00400b 00
0x00400c b3
0x00400d 02
0x00400e 03
0x00400f 00
0x004010 33
0x004011 83
0x004012 03
0x004013 00
0x004014 6f
0x004015 f0
0x004016 5f
0x004017 ff

Ejercicio 4

(Ver enunciado)

# Sesion L2
## Programa para calcular la expresion: 
##  f = (a + b + c) - [(d - a) + (e + 3) - 30]
##  Valores iniciales de prueba: a=2, b=4, c=6, d=8, e=10

	.text
	
	#-- Valores iniciales
	addi x5,x0,2  #-- x5 = a = 2
	addi x6,x0,4  #-- x6 = b = 4
	addi x7,x0,6  #-- x7 = c = 6
	addi x8,x0,8  #-- x8 = d = 8
	addi x9,x0,10 #-- x9 = e = 10
	
	#-- Calcular la expresion. Resultado en X10
	add x11, x5, x6  #-- x11 = a + b
	add x11, x11,x7  #-- x11 = (a + b + c)
	sub x12, x8, x5  #-- x12 = (d - a)
	addi x13, x9, 3 #-- x13 = (e + 3)
	addi x14, x13, -30  #-- x14 = (e + 3) - 30
	add x15, x12, x14   #-- x15 = [(d - a) + (e + 3) - 30]
	
	#-- Resultado final
	sub x10, x11, x15    #-- x10 =   (a + b + c) - [(d - a) + (e + 3) - 30]
	
	#-- Terminar
	li a7, 10
	ecall

Para el valor de las variables a=2, b=4, c=6, d=8, e=10, se obtiene que f = 23

Ejercicio 5

(Ver enunciado)

  1. La expresión que se calcula es: x10 = 2x5 + 4x6 - (x7 - x8) + 15

El término 2*x5 se obtiene porque se suma x5 con x5:

add x5, x5, x5   #-- x5 = X5 + X5 = 2*x5

El término 4*x6 se obtiene por estas dos instrucciones:

add x6, x6, x6  #-- x6 = 2*x6
add x6, x6, x6  #-- x6 = 2* (2*x6)

Si asignamos las variables a los registros de esta forma: x10 = f, x5=a, x6=b, x7=c, x8=d, tenemos que la expreión es: f = 2a + 4b - (c - d) + 15

  1. Se prueba con los valores a=3, b=5, c=7, d=9, que son los que se utilizan al comienzo para inicializar los registros x5,x6,x7 y x8

  2. El resultado es 43

  3. El valor de la posición de memoria 0x00400015 es 03. Lo comprobamos muy fácilmente buscando la palabra alineada inferior (Dirección 0x00400014) y aplicando el criterio Little endian sacamos el valor

  1. El programa tiene 13 instrucciones. Cada instrucción es de 4 bytes. Por tanto ocupa 13 * 4 = 52 bytes

Ejercicio 6

  1. Obtener el código máquina de las instrucciones es muy sencillo usando directamente el ensamblador. Las copiamos al RARs, las ensamblamos y obtenemos el código máquina:

Estas son las dos instrucciones en código máquina

addi x0, x0, 0  -----> 0x00000013
addi x0, x0, 0xFA ---> 0x0FA00013
  1. Solo se diferencian en los caracteres hexadecimales FA. Parece
    que esos bits codifican el valor inmediato de la instrucción addi

Si eso es cierto, el código máquina de la instruccio addi x0,x0,0xBB seria 0x0BB00013. Vamos a comprobarlo con el simulador:

¡Exacto! ¡es esa misma! 😄

  1. Obtenemos el código máquina de las dos instrucciones, usando el simulador:
addi x0, x1, 0  --> 0x00008013 --> 0000 0000 0000 0000 1000 0000 0001 0011
addi x0, x2, 0  --> 0x00010013 --> 0000 0000 0000 0001 0000 0000 0001 0011
                                   ==== ==== ==== ===x x=== ==== ==== ====

Solo se diferencian en 2 bits: el 15 y el 16. Parece que esos bits codifican el número de registro

  1. Obtenemos el código máquina de las dos instrucciones, con el simulador:
addi x0, x0, 0 ---> 0x00000013 --> 0000 0000 0000 0000 0000 0000 0001 0011
addi x31, x0, 0 --> 0x00000F93 --> 0000 0000 0000 0000 0000 1111 1001 0011
                                   ==== ==== ==== ==== ==== xxxx x=== ====

Parece que el número de registro se codifica los bits 7-11 (5 bits)

El registro 0 tiene esos 5 bits a 0: 00000
El registro 31 tiene esos 5 bits a 1: 11111

Ejercicio 7

Por definición, la etiqueta es un símbolo que se corresponde con una dirección de memoria. Los humanos, en vez de trabajar con direcciones numéricas, que nos resultan complejas, trabajamos con etiquetas. Es el ensamblador el que tiene una tabla de símbolos en la que hace la conversion de humano a máquina

Etiqueta Dirección
ini 0x00400000
a 0x00400000
b 0x0040000C
c 0x0040001C
d 0x00400028
fin 0x00400030
last 0x00400034

Ejercicio 8

El PC vale 0x0040000C. Esto significa que la siguiente instrucción que
se ejecutará será la que esté en esa dirección... que es: addi x8, x8, 9

Podemos ver rápidamente qué instrucción está en cada dirección ensamblando el programa y viendo la instrucción de la dirección 0x0040000C

Ejercicio 9

Como la etiqueta vale 0x00502020, sabemos que esa es la direccion
de la primera instrucción del fragmento. A partir de ese valor
podemos calcular las demás:

Etiqueta Direccion
b 0x00502020
c 0x00502030
d 0x0050203C
fin 0x00502044

Ejercicio 10

#-- Programa en ensamblador para calcular la expresion:
#-- f = (d - c) + 15 - (a + b)
#-- Probarlos con las siguientes secuencias de valores:
#-- a=1,2,3,4,5...
#-- b=2,3,4,5,6..
#-- c=3,4,5,6,7..
#-- d=4,5,6,7,8..
	
	.text
	
	#--- Inicializacion
	addi x5,x0,1  #-- x5 = a
	addi x6,x0,2  #-- x6 = b
	addi x7,x0,3  #-- x7 = c
	addi x8,x0,4  #-- x8 = d
	 
bucle:	 
	#-- calcular la expresion 
	sub x11, x8, x7  #-- x11 = (d - c)
	addi x11,x11,15  #-- x11 = (d - c) + 15
	add x12,x5,x6    #-- x12 = (a + b)
	sub x13, x11,x12 #-- x13 = (d - c) + 15 - (a + b)
	
	nop  #-- No hace nada. Se usa para poner aqui el Breakpoint
	
	#-- Incrementar x5,x6,x7 y x8
	addi x5,x5,1  #-- a = a+1
	addi x6,x6,1  #-- b = b+1
	addi x7,x7,1  #-- c = c+1
	addi x8,x8,1  #-- d = d+1
	
	#-- Repetir. Siguiente iteraccion
	j bucle

En la decima iteracion, los valores iniciales son:

a=10,
b=11,
c=12,
d=13

El valor calculado es -5, que es correcto

Autores

Licencia

Enlaces

Página principal


Sesiones de Prácticas

P1: Simulador RARs

L1: El simulador RARs
L2: Calculando expresiones
L3: Práctica 1-3. Variables

P2: E/S mapeada. Llamadas al sistema

L4: Pract 2-1. E/S mapeada
L5: Práctica 2-2: Inst. ecall
L6: Prác 2-3: Cadenas

P3: Bucles y Saltos condicionales

L7: Práct 3-1: Bucles y saltos
L8: Práct 3-2: Cadenas II

P4: Subrutinas

L9: Pract 4-1: Subrut. Nivel-1
L10: Pract 4-2: La pila
L11: Pract 4-3: Recursividad

P5: Memoria Dinámica

L12: Pract 5-1. Heap. Listas

VÍDEO DE DESPEDIDA

SESIONES ADICIONALES

L13: RV32I: Resto de instrucciones
L14: Macros
L15: Entrada/Salida a bajo nivel
L16: Multiplicaciones/divisiones. Unit Tests 🚧
L17: Biblioteca stdio: salida a alto nivel 🚧
Los registros de estado y control (CSR)
Interrupciones y excepciones
Borrador

SOLUCIONES

Soluciones a los ejercicios planteados en cada sesión para practicar:
Sesión L1
Sesión L2
Sesión L3
Sesión L4
Sesión L5
Sesión L6
Sesión L7
Sesión L8
Sesión L9
Sesión L10
Sesión L11
Sesión L12

Ejercicios de examen

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
GISAM. Extra. 2025-Jun-17
GISAM. Parcial 1. 2025-Oct-20
GISAM. Parcial 2. 2025-Nov-19
GISAM. Parcial 3. 2026-Enero-9
GISAM. Parcial 1. 2026-Oct-21
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
TELECO. Extra. 2025-Jun-17
TELECO. Parcial 1. 2025-Oct-10
TELECO. Parcial 2. 2025-Nov-13
TELECO. Parcial 3. 2026-Ene-21
TELECO. Extra. 2026-Jun-25
TELECO. Parcial 1. 2026-Oct-09
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
Robótica. Parcial 1. 2025-Feb-25
Robótica. Parcial 2. 2025-Mar-31
Robótica. Parcial 3. 2025-May-19
Robótica. Parcial 1. 2026-Feb-23
Robótica. Parcial 2. 2026-Abr-13
Robótica. Parcial 3. 2026-May-11
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
Datos. Parcial 3. 2025-Ene-17
Datos. Parcial 1. 2025-Oct-15
Datos. Parcial 2. 2025-Nov-19

Clone this wiki locally