auipc
lyszt.net behandelt auipc und andere RISC-V-Befehle ausführlicher.
Kodierungsformat
Beschreibung
auipc ist mit lui verwandt, und der Name benennt den Unterschied. Er bedeutet „add upper immediate to PC“ (oberes Immediate zum PC addieren). Wie lui nimmt er eine 20-Bit-Konstante als oberen Teil eines Werts. auipc addiert diesen Wert zum Programmzähler, also der Adresse der gerade ausgeführten Instruktion (siehe die Seite beq). Das Ergebnis ist eine Adresse, die relativ zu der Stelle gemessen wird, an der diese Instruktion im Speicher liegt.
Relative Adressen lösen ein echtes Problem. Ein Programm weiß nicht immer, wohin im Speicher es geladen wird. Code, der seine Daten über feste absolute Adressen anspricht, versagt, wenn er woanders geladen wird. Code, der Adressen relativ zur aktuellen Instruktion berechnet, funktioniert überall, wo er platziert wird. Diese Eigenschaft heißt Positionsunabhängigkeit.
auipc liefert den groben Teil einer solchen Adresse, und eine nachfolgende Instruktion addiert den feinen 12-Bit-Rest. Die Instruktion la, die die Adresse eines Labels lädt, wird aus diesem Paar gebildet, ebenso Aufrufe weit entfernter Funktionen.
Das RISC-V-Handbuch sagt, dass der aktuelle pc erhalten werden kann, indem man die Konstante von auipc auf 0 setzt. Ein auipc, gefolgt von einem jalr, kann die Kontrolle an jede 32-Bit-pc-relative Adresse übergeben, und ein auipc, gefolgt von einem Load oder Store mit einem 12-Bit-Offset, kann auf jede 32-Bit-pc-relative Datenadresse zugreifen.
la und call existieren, damit Sie auipc nicht von Hand schreiben müssen, und es erscheint häufig im Trace des Simulators und in disassembliertem Code. Ein auipc, gefolgt von einer Instruktion mit einem kleinen Offset, die zusammen eine Adresse bilden, ist ein nützliches Muster zum Erkennen.
Beispiel
auipc t0, 1 # t0 = pc + 0x1000
