addi

addi

RISC-V Assembler Referenz

lyszt.net behandelt addi 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

addi addiert eine Konstante zu einem Register. Der Name steht für add immediate (sofort addieren). Ein Immediate ist ein konstanter Wert, der direkt in die Anweisung geschrieben wird, statt aus einem Register gelesen zu werden. Verwende es, wenn eine der Zahlen beim Schreiben des Programms feststeht, etwa beim Addieren von 1 zu einem Zähler.

Die Form von addi ist unten dargestellt. Sie liest den Wert im Quellregister rs1, addiert die Konstante imm und schreibt das Ergebnis in das Zielregister rd.

addi rd, rs1, imm

Die nächste Zeile liest t0, addiert eins und schreibt das Ergebnis zurück, also t0 = t0 + 1.

addi t0, t0, 1

Die Konstante belegt 12 Bits und ist vorzeichenbehaftet, was einen Bereich von -2048 bis 2047 ergibt. Der Assembler lehnt größere Werte ab. Für eine größere Konstante lade sie zuerst mit li in ein Register. Eine negative Konstante lässt addi auch subtrahieren, weshalb RISC-V keine separate Subtraktions-Immediate-Anweisung hat. Die nächste Zeile zählt herunter.

addi t0, t0, -1

Das RISC-V-Handbuch nennt die Konstante ein vorzeichenerweitertes 12-Bit-Immediate. Es gibt an, dass arithmetischer Überlauf ignoriert wird, sodass das Ergebnis nur seine niedrigen XLEN Bits behält, wobei XLEN die Registerbreite in Bits ist, hier 32. Wenn das Vorzeichen der Konstante bekannt ist, prüft ein Sprung nach der Addition auf vorzeichenbehafteten Überlauf. Die beiden Zeilen unten behandeln den häufigen Fall des Addierens einer positiven Konstante.

addi t0, t1, +imm
blt t0, t1, overflow

Programme verwenden addi für Zähler, zum Verschieben eines Zeigers auf das nächste Element und zum Reservieren von Platz auf dem Stack. Das Beispiel addiert 1, um einen Zähler zu erhöhen, und addiert -16, um 16 Bytes Arbeitsspeicher zu reservieren, womit eine Funktion, die Arbeitsplatz benötigt, üblicherweise beginnt.

Beispiel

addi t0, t0, 1     # t0++
addi sp, sp, -16   # reserve 16 bytes of stack