Eingabe & Ausgabe
verarbeitet alle Ein- und Ausgaben. Ein (Environment Call) fordert das Betriebssystem oder den Simulator auf, einen Dienst für Ihren Assembler-Code auszuführen. Der Bildschirm und die Tastatur sind zwei der auf diese Weise verfügbaren Dienste.
Setzen Sie die Dienstnummer in a7, ein Argument in a0, und lösen Sie dann aus. Die Dienste, die dieser Simulator kennt:
1 # Ganzzahl ausgeben (a0 = Zahl)4 # Zeichenkette ausgeben (a0 = Adresse des Texts)5 # Ganzzahl einlesen (Ergebnis in a0 zurückgegeben)10 # Programm beenden32 # Pause (a0 = Millisekunden)
a7 = 1 wählt den Druckdienst aus.
a7 gibt an, welcher Dienst ausgeführt werden soll, und a0 enthält alles, was dieser Dienst benötigt: einen Wert zum Ausgeben, eine Adresse zum Auslesen, eine Wartezeit. Die Liste ist fest vorgegeben und kurz – sie umfasst fünf Einträge –, sodass man mit dem einmaligen Erlernen dieses Handshakes alle Möglichkeiten abdeckt, wie dieser Simulator mit der Außenwelt kommuniziert. Ein echtes Betriebssystem erweitert dasselbe Prinzip auf eine viel längere Liste.li a7, 5 # Ganzzahl einlesen -> a0ecalladd a0, a0, a0 # verdoppelnli a7, 1 # Ganzzahl ausgebenecallli a7, 10ecall
wählt das Einlesen einer Ganzzahl und pausiert für die Eingabe und gibt deine Zahl in a0 zurück. addiert a0 zu sich selbst und verdoppelt es an Ort und Stelle. Dann geben und das Ergebnis aus, und und beenden das Programm. Wenn du es ausführst, öffnet der Simulator ein Eingabefeld. Gib eine Zahl ein und sieh zu, wie sie verdoppelt zurückkommt.
Text drucken
Zunächst zwei neue Begriffe. Ein Abschnitt ist ein beschrifteter Bereich Ihres Programms: Befehle befinden sich im .text-Abschnitt, während feste Daten wie Text im .data-Abschnitt gespeichert sind. Und eine Adresse ist einfach eine Zahl, die einen Speicherplatz identifiziert. Anstatt eine ganze Zeichenkette mitzuführen, kann ein Register die Adresse enthalten, an der die Zeichenkette beginnt, und der Druckdienst liest von dort aus.
Der Text kommt in den Datenabschnitt. Du hängst ein Label daran und verwendest dann ("load address"), um die Adresse dieses Labels zu laden, und Service 4, um ihn auszugeben.
.datamsg: .string "Hello, RISC-V!\n".textla a0, msg # a0 = Adresse des Textsli a7, 4 # Zeichenkette ausgebenecallli a7, 10ecall
In .data reserviert die Direktive Speicherplatz für den Text und hängt das Label msg an. .string speichert die Zeichen und fügt \n an, einen Zeilenumbruch. In .text legt die Adresse des Textes in a0, wählt den Service zum Ausgeben einer Zeichenkette, und gibt Zeichen ab dieser Adresse aus, bis das Ende der Zeichenkette erreicht ist. Danach beendet sich das Programm wie gewohnt.
