lw
lyszt.net aborda lw e outras instruções RISC-V com mais detalhes.
Formato de codificação
Descrição
lw copia um valor da memória para um registrador. Os 32 registradores formam a pequena e rápida área de trabalho do processador. A memória fica ao lado deles como o grande armazenamento: uma longa fileira de slots numerados que contém arrays, texto e variáveis. O número de um slot é o seu endereço. A computação ocorre nos registradores, e os dados aguardam na memória entre os usos.
O RISC-V faz aritmética apenas em registradores, nunca diretamente na memória, então um valor deve ser carregado em um registrador antes do uso e armazenado de volta depois. lw realiza o carregamento. O nome significa load word, e uma word é um valor de 32 bits, a largura de um registrador.
A forma de lw aparece abaixo. Ela pega o valor em rs1, um registrador que contém um endereço de memória chamado base, adiciona offset, uma pequena constante, e lê o valor no endereço resultante para o registrador de destino rd.
lw rd, offset(rs1)
A próxima linha carrega o valor 8 bytes após o endereço em t0.
lw t1, 8(t0)
O manual do RISC-V chama o RISC-V de arquitetura load-store: as instruções de load e store são as únicas que acessam a memória, e as instruções aritméticas trabalham apenas em registradores. O espaço de endereçamento é de 32 bits e endereçado por byte, e o endereço efetivo de um load é o registrador rs1 mais o offset de 12 bits estendido com sinal. O ambiente de execução, ou seja, o sistema no qual o programa é executado, decide se a memória contém o byte menos significativo primeiro, chamado little-endian, ou o byte mais significativo primeiro, chamado big-endian. Um acesso é naturalmente alinhado quando seu endereço é divisível pelo tamanho do acesso, que é 4 bytes para uma word. Acessos naturalmente alinhados nunca geram um erro de alinhamento. Um acesso desalinhado se comporta conforme o ambiente define e pode executar muito lentamente.
O offset existe porque os itens na memória ficam a distâncias regulares. Uma word tem 4 bytes, então elementos consecutivos de um array ficam a 4 bytes de distância, nos offsets 0, 4, 8 e assim por diante. la coloca o endereço inicial do array em um registrador, e alterar o offset lê os diferentes elementos. O exemplo carrega dois vizinhos de um array. O offset 0 dá o primeiro valor, 10, e o offset 4 dá o próximo valor, 20.
Exemplo
.data arr: .word 10, 20 .text la t0, arr lw t1, 0(t0) # t1 = 10 lw t2, 4(t0) # t2 = 20
