call
Pseudoelementlyszt.net behandelt call und andere RISC-V-Befehle ausführlicher.
Beschreibung
call führt eine Funktion aus und behandelt die Rückgabe. Sie springt zur Funktion und speichert die Rücksprungadresse in ra, wodurch die Funktion zurückkehren kann. Es ist eine Pseudoinstruktion, die sich normalerweise zur unten stehenden Instruktion entfaltet.
jal ra, label
Wenn eine Funktion zu weit entfernt ist, um von einem einzelnen Sprung erreicht zu werden, ersetzt der Assembler sie durch eine längere Sequenz, die die Entfernung überbrückt. call mit dem Funktionsnamen zu schreiben, drückt die Absicht aus und überlässt die Wahl der Form dem Assembler. Der Eintrag jal beschreibt den Sprung und das Speichern der Rücksprungadresse. Die Zeile unten ruft die Funktion square auf.
call square
Der Aufruf einer Funktion erfordert außerdem eine Vereinbarung darüber, wie Informationen zwischen Aufrufer und Aufgerufenerm übergeben werden. Diese Vereinbarung ist die Aufrufkonvention. Der Aufrufer legt die Eingaben der Funktion in die Argumentregister, benannt a0, a1 und so weiter, und liest das Ergebnis aus a0, sobald die Funktion zurückkehrt. Beide Seiten befolgen dieselbe Regel, sodass getrennt geschriebener Code weiterhin zusammen funktioniert.
Jeder call überschreibt ra. Eine Funktion, die selbst Aufrufe macht, speichert das ra, das sie erhalten hat, bevor sie diese macht, und stellt diesen Wert vor ihrer eigenen Rückkehr wieder her. Ohne dies ersetzt die Rücksprungadresse des inneren Aufrufs die des äußeren, und die Funktion kann nicht zurückkehren. Eine Funktion, die nichts anderes aufruft, muss ra nicht speichern.
Das RISC-V-Handbuch gibt an, dass die standardmäßige Software-Aufrufkonvention x1 als Rücksprungadressregister verwendet. Ein jal erreicht Ziele innerhalb von plus oder minus 1 MiB, wobei ein MiB 1.048.576 Bytes ist. Ein weiter entferntes Ziel erfordert ein auipc, gefolgt von jalr, das jeden Ort in einem 32-Bit-pc-relativen Adressbereich erreicht.
Das Beispiel ruft square mit 6 in a0 auf und findet danach 36 in a0. Das Argument geht hinein und das Ergebnis kommt durch die Konvention heraus.
Wird erweitert zu
jal ra, label
Der Assembler ersetzt diese Pseudoanweisung durch die oben aufgeführte(n) echte(n) Anweisung(en).
Beispiel
call square # jumps to square; ra holds the return address
Referenzen
- [1]RISC-V International. The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture. Version 20260120. Section 2.5.1, Unconditional Jumps, page 30.
- [2]RISC-V International. The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture. Version 20260120. Section 2.4.1, Integer Register-Immediate Instructions, pages 28 to 29.
