beq
lyszt.net behandelt beq und andere RISC-V-Befehle ausführlicher.
Kodierungsformat
Beschreibung
beq ermöglicht es einem Programm, eine Entscheidung zu treffen. Der Prozessor führt Anweisungen normalerweise in der Reihenfolge aus, in der sie in der Liste erscheinen. Diese Reihenfolge allein kann nichts auswählen oder wiederholen. Ein Sprung ändert die Reihenfolge. Er prüft eine Bedingung, und wenn die Bedingung zutrifft, fährt der Prozessor an einer anderen Stelle fort statt mit der nächsten Zeile. Alle if-Anweisungen und Schleifen werden aus Sprüngen aufgebaut.
Die andere Stelle wird durch ein Label benannt, einen Namen gefolgt von einem Doppelpunkt, der eine Position im Code markiert, wie das Label done im Beispiel. beq (branch if equal, springe wenn gleich) vergleicht zwei Register. Wenn sie denselben Wert enthalten, springt es zur beschrifteten Position; wenn sie sich unterscheiden, wird die Ausführung mit der nächsten Anweisung fortgesetzt. Die Form erscheint unten.
beq rs1, rs2, label
beq ändert nur, welche Anweisung als Nächstes ausgeführt wird. Das Ja-oder-Nein-Ergebnis eines Vergleichs als Zahl zu speichern erfordert eine andere Anweisung, die auf der Seite slt beschrieben wird.
Der Prozessor verfolgt seine Position mit einem Register namens Programmzähler, das die Adresse der gerade ausgeführten Anweisung enthält. Ein genommener Sprung ändert diese Adresse, sodass die nächste Anweisung vom Label kommt.
Das RISC-V-Handbuch gibt an, dass ein bedingter Sprung seinen Offset als einen 12-Bit-Wert speichert, der in Vielfachen von 2 Bytes gezählt wird. Der Offset wird vorzeichenerweitert und zur Adresse der Sprunganweisung addiert, was einen Bereich von plus oder minus 4 KiB ergibt, wobei ein KiB 1024 Bytes ist. Sprunganweisungen vergleichen zwei Register direkt und verwenden keine Bedingungscodes. Das Handbuch nennt als Grund, dass eine kombinierte Vergleichs- und Sprunganweisung in eine reguläre Pipeline passt und keinen zusätzlichen Zustand oder temporäres Register benötigt. Es rät Software außerdem, den häufigsten Pfad als geraden Code beizubehalten und zu erwarten, dass Rücksprünge als genommen und Vorwärtssprünge als nicht genommen vorhergesagt werden, zumindest beim ersten Auftreten.
Ein Sprung vergleicht zwei Register und kann keine in der Anweisung geschriebene Konstante verwenden, daher existiert eine Form wie beq t0, 5, label nicht. Um ein Register mit einer Konstante zu vergleichen, laden Sie die Konstante zuerst mit li in ein Register und vergleichen Sie dann die beiden Register.
li t1, 5 beq t0, t1, done
Der Wert 0 muss nicht geladen werden, weil das Register zero ihn immer enthält.
Eine häufige Verwendung vergleicht ein Register mit zero, dem Register, das immer 0 enthält, um zu fragen, ob ein Wert null erreicht hat. Dies beendet Countdown-Schleifen und prüft Ergebnisse. Das Beispiel springt zu done, wenn a0 bis auf null heruntergezählt hat. beq und Labels reichen aus, um jede Entscheidung und jede Schleife in einem Programm aufzubauen.
Beispiel
beq a0, zero, done # if a0 == 0, jump to 'done'
