jalr

jalr

RISC-V Assembler Referenz

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

jalr gehört zur selben Familie wie jal, wobei das r für Register steht. Beide Anweisungen springen und speichern eine Rücksprungadresse, wie auf der jal-Seite beschrieben. Der Unterschied ist das Sprungziel. jal springt zu einer Marke, die beim Schreiben des Programms festgelegt wird, während jalr zu einer Adresse springt, die in einem Register gehalten wird, was es ermöglicht, das Ziel zur Laufzeit zu berechnen.

Dies ist es, was es einer Funktion ermöglicht, zurückzukehren. Der Aufrufer legt eine Rücksprungadresse in das Register ra, und die Funktion springt zurück, indem sie jalr verwendet, um die Adresse in ra zu erreichen. Die Anweisung ret ist ein jalr nach ra.

Dieselbe Fähigkeit gilt immer dann, wenn das Ziel im Voraus unbekannt ist. Sie deckt Aufrufe einer Funktion ab, deren Adresse übergeben wurde, und die Auswahl unter Routinen, die in einer Adresstabelle aufgeführt sind, was die Art und Weise ist, wie eine große switch-Anweisung oder ein Interpreter verteilt.

Laut dem RISC-V-Handbuch addiert jalr das vorzeichenerweiterte 12-Bit-Immediate zum Register rs1 und löscht dann das niederwertigste Bit des Ergebnisses. Es speichert die Adresse der nächsten Anweisung, pc plus 4, in rd, und x0 kann als Ziel dienen, wenn keine Rücksprungadresse benötigt wird. Ein lui gefolgt von jalr erreicht jede 32-Bit-Absolutadresse, und ein auipc gefolgt von jalr erreicht jede 32-Bit-pc-relative Adresse. Beide Sprunganweisungen lösen eine Ausnahme aus, wenn die Zieladresse nicht an einer Vier-Byte-Grenze ausgerichtet ist.

Das Format von jalr erscheint unten. Es springt zur Adresse im Register rs plus einem optionalen kleinen Offset und speichert die Rücksprungadresse in rd.

jalr rd, rs, offset

Wie bei jal wird das Register, das es schreibt, überschrieben, sodass dieselbe Sorgfalt beim Bewahren von ra gilt.

Beispiel

la t0, target
jalr ra, t0, 0   # jump to target; ra holds the return address