lw

lw

RISC-V Assembler Referenz

lyszt.net behandelt lw und andere RISC-V-Befehle ausführlicher.

Kodierungsformat

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Beschreibung

lw kopiert einen Wert aus dem Speicher in ein Register. Die 32 Register bilden den kleinen, schnellen Arbeitsbereich des Prozessors. Der Speicher liegt daneben als der große Speicher: eine lange Reihe nummerierter Plätze, die Arrays, Text und Variablen enthält. Die Nummer eines Platzes ist seine Adresse. Berechnungen finden in Registern statt, und Daten warten zwischen den Verwendungen im Speicher.

RISC-V führt Arithmetik nur auf Registern aus, niemals direkt auf dem Speicher, daher muss ein Wert vor der Verwendung in ein Register geladen und danach zurückgespeichert werden. lw führt das Laden aus. Der Name bedeutet load word, und ein word ist ein 32-Bit-Wert, die Breite eines Registers.

Die Form von lw erscheint unten. Sie nimmt den Wert in rs1, einem Register, das eine Speicheradresse namens Basis enthält, addiert offset, eine kleine Konstante, und liest den Wert an der resultierenden Adresse in das Zielregister rd.

lw rd, offset(rs1)

Die nächste Zeile lädt den Wert 8 Bytes hinter der Adresse in t0.

lw t1, 8(t0)

Das RISC-V-Handbuch nennt RISC-V eine Load-Store-Architektur: Lade- und Speicherbefehle sind die einzigen, die auf den Speicher zugreifen, und arithmetische Befehle arbeiten nur auf Registern. Der Adressraum ist 32 Bit groß und byte-adressiert, und die effektive Adresse eines Ladevorgangs ist das Register rs1 plus der vorzeichenerweiterten 12-Bit-Offset. Die Ausführungsumgebung, also das System, in dem das Programm läuft, entscheidet, ob der Speicher das niederwertigste Byte zuerst enthält, was little-endian genannt wird, oder das höchstwertige Byte zuerst, was big-endian genannt wird. Ein Zugriff ist natürlich ausgerichtet, wenn seine Adresse durch die Größe des Zugriffs teilbar ist, die für ein word 4 Bytes beträgt. Natürlich ausgerichtete Zugriffe lösen niemals einen Ausrichtungsfehler aus. Ein nicht ausgerichteter Zugriff verhält sich wie von der Umgebung definiert und kann sehr langsam laufen.

Der Offset ist vorhanden, weil Elemente im Speicher in regelmäßigen Abständen liegen. Ein word ist 4 Bytes groß, also liegen aufeinanderfolgende Elemente eines Arrays 4 Bytes auseinander, bei den Offsets 0, 4, 8 und so weiter. la legt die Startadresse des Arrays in ein Register, und das Ändern des Offsets liest die verschiedenen Elemente. Das Beispiel lädt zwei Nachbarn eines Arrays. Offset 0 ergibt den ersten Wert, 10, und Offset 4 ergibt den nächsten Wert, 20.

Beispiel

.data
arr: .word 10, 20
.text
la t0, arr
lw t1, 0(t0)   # t1 = 10
lw t2, 4(t0)   # t2 = 20