Memória: leitura e gravação

Memória: leitura e gravação

A memória é uma grande fileira de slots de armazenamento numerados, e cada slot contém um byte (8 bits). O número de um slot é o seu endereço. Os registradores são o pequeno conjunto de slots rápidos da CPU. A memória é muito maior, mas mais lenta, e contém tudo o que não cabe nos registradores, como arrays e strings. Para trabalhar com um valor na memória, você o carrega em um registrador, altera-o e o armazena de volta.

Os registradores são poucos e a memória é grande. (load word) copia uma palavra da memória para um registrador, e (store word) a copia de volta. O endereço é escrito como offset(register).

A memória RISC-V é endereçada por byte, então cada byte tem seu próprio endereço em sequência. Uma palavra tem 32 bits, ou 4 bytes, então você avança um ponteiro de memória em 4 para alcançar a próxima palavra. É por isso que os offsets de array são 0, 4, 8 e assim por diante. Em hardware real, carregar uma palavra de um endereço que não é múltiplo de 4 pode ser lento ou causar um trap. Este simulador permite isso, mas você deve criar o hábito de manter as palavras alinhadas a 4 bytes.

Sintaxe das instruções de leitura e gravação
lw t0, 0(a1) # t0 = memória no endereço a1
sw t0, 4(a1) # memória no endereço a1+4 = t0

Em offset(register), o pequeno número de offset é somado ao endereço contido no registrador. 0(a1) é o endereço no próprio a1, e 4(a1) é 4 bytes depois dele. Isso permite alcançar valores próximos sem alterar o registrador base.

Armazenando na memória
CPU
li t0, 0x11111111
li t1, 0x22222222
li a0, 0x1000
sw t0, 0(a0)
sw t1, 8(a0)
Registers
t00x00000000
t10x00000000
a00x00000000
Random Access Memory (RAM)
AddressValue
0x100C0x00000000
0x10080x00000000
0x10040x00000000
0x1000
0x00000000
0x0FFC0x00000000

Os registradores e a memória começam em zero.

Na animação, o registrador base a0 permanece o mesmo. Apenas o offset literal escrito na instrução aumenta, movendo-se para o próximo endereço de memória alvo. Para criar memória que corresponda a esse padrão, reserve memória nomeada na seção data com .word (um ou mais valores de 32 bits) ou .space N (N bytes em branco). Cada palavra tem 4 bytes, então itens consecutivos ficam nos offsets 0, 4, 8, que são os mesmos números usados nas suas instruções de store.

Use .word (um ou mais valores de 32 bits) ou .space N (N bytes em branco) para reservar memória nomeada na seção data. Cada palavra ocupa 4 bytes, então itens consecutivos ficam nos offsets 0, 4, 8 e assim por diante.

Somar um array na memória
.data
nums: .word 10, 20, 30, 40 # quatro palavras
.text
la t1, nums # t1 = endereço do vetor
li t2, 4 # contagem
li t0, 0 # soma corrente
loop:
beq t2, zero, done
lw t3, 0(t1) # carrega o elemento atual
add t0, t0, t3 # soma ao total
addi t1, t1, 4 # avança para a próxima palavra (4 bytes)
addi t2, t2, -1 # um a menos
j loop
done:
mv a0, t0 # imprime o total (100)
li a7, 1
ecall
li a7, 10
ecall

coloca o endereço do array em t1, t2 conta os 4 elementos restantes, e t0 mantém a soma corrente. A cada passagem, interrompe o loop quando não restam elementos. carrega o elemento apontado por t1, o adiciona à soma, avança o ponteiro em uma palavra, e reduz a contagem. Após os quatro elementos (10 + 20 + 30 + 40), done imprime 100.

💡
Use o botão de alternância HEX/DEC na barra de ferramentas do simulador para mudar como endereços e valores são exibidos. Escolha a base que torna o passo atual mais fácil de acompanhar.