Memoria: cargar y almacenar
La memoria es una gran fila de ranuras de almacenamiento numeradas, y cada ranura contiene un byte (8 bits). El número de una ranura es su dirección. Los registros son el pequeño conjunto de ranuras rápidas de la CPU. La memoria es mucho más grande pero más lenta, y contiene todo lo que no cabe en los registros, como los arreglos y las cadenas. Para trabajar con un valor en memoria, lo cargas en un registro, lo modificas y lo vuelves a almacenar.
Los registros son pocos y la memoria es grande. (load word) copia una palabra desde la memoria a un registro, y (store word) la copia de vuelta. La dirección se escribe como offset(register).
La memoria de RISC-V está direccionada por bytes, por lo que cada byte tiene su propia dirección en secuencia. Una palabra es de 32 bits, o 4 bytes, así que avanzas un puntero de memoria en 4 para llegar a la siguiente palabra. Por eso los desplazamientos de los arreglos son 0, 4, 8, etc. En hardware real, cargar una palabra desde una dirección que no es múltiplo de 4 puede ser lento o puede provocar una trampa. Este simulador lo permite, pero deberías formar el hábito de mantener las palabras alineadas a 4 bytes.
lw t0, 0(a1) # t0 = memoria en la dirección a1sw t0, 4(a1) # memoria en la dirección a1+4 = t0
En offset(register), el número de desplazamiento pequeño se suma a la dirección contenida en el registro. 0(a1) es la dirección en a1 mismo, y 4(a1) está 4 bytes más allá. Esto te permite alcanzar valores cercanos sin cambiar el registro base.
| Address | Value |
|---|---|
| 0x100C | 0x00000000 |
| 0x1008 | 0x00000000 |
| 0x1004 | 0x00000000 |
| 0x1000 | 0x00000000 |
| 0x0FFC | 0x00000000 |
Los registros y la memoria comienzan en cero.
a0 permanece igual. Solo aumenta el desplazamiento literal escrito en la instrucción, avanzando a la siguiente dirección de memoria objetivo.
Para crear memoria que coincida con este patrón, reserva memoria con nombre en la sección de datos con .word (uno o más valores de 32 bits) o .space N (N bytes en blanco). Cada palabra ocupa 4 bytes, por lo que los elementos consecutivos se sitúan en los desplazamientos 0, 4, 8, que son los mismos números usados en tus instrucciones de almacenamiento.Usa .word (uno o más valores de 32 bits) o .space N (N bytes en blanco) para reservar memoria con nombre en la sección de datos. Cada palabra ocupa 4 bytes, por lo que los elementos consecutivos están en los desplazamientos 0, 4, 8, etc.
.datanums: .word 10, 20, 30, 40 # cuatro palabras.textla t1, nums # t1 = dirección del arregloli t2, 4 # contadorli t0, 0 # suma acumuladaloop:beq t2, zero, donelw t3, 0(t1) # carga el elemento actualadd t0, t0, t3 # suma al totaladdi t1, t1, 4 # avanza a la siguiente palabra (4 bytes)addi t2, t2, -1 # uno menosj loopdone:mv a0, t0 # imprime el total (100)li a7, 1ecallli a7, 10ecall
pone la dirección del arreglo en t1, t2 cuenta los 4 elementos restantes, y t0 contiene la suma acumulada. En cada pasada, detiene el bucle cuando no quedan elementos. carga el elemento al que apunta t1, lo suma a la suma, avanza el puntero una palabra, y reduce el contador. Tras los cuatro elementos (10 + 20 + 30 + 40), done imprime 100.
