Write-Syscall (1)
Teil des Abschnitts Grundlagen der Assembly-Journey von Coddy. Lektion 35 von 45.
Du weißt bereits, wie man ein Programm beendet. Aber ein lautloses Beenden ist nicht besonders hilfreich. Du möchtest, dass dein Programm eine Ausgabe ausgibt, damit der Benutzer etwas sehen kann.
Dafür benötigst du den write-Systemaufruf.
Was ist der write-Systemaufruf?
Der write-Systemaufruf weist das Betriebssystem an, Text auf dem Bildschirm auszugeben (oder in eine Datei zu schreiben). So erzeugt dein Programm eine Ausgabe.
Die Syscall-Nummer für write ist 1.
So funktioniert write:
Im Gegensatz zum exit-Systemaufruf (der nur ein Argument benötigt) braucht write drei Argumente:
| Argument | Register | Was es tut | Beispiel |
|---|---|---|---|
| Dateideskriptor | rdi | Wohin geschrieben werden soll (1 = Bildschirm) | mov rdi, 1 |
| Pufferadresse | rsi | Wo sich der Text im Speicher befindet | mov rsi, message |
| Byteanzahl | rdx | Wie viele Bytes ausgegeben werden sollen | mov rdx, 13 |
Der write-Systemaufruf in Aktion:
mov rax, 1 ; Syscall-Nummer für write
mov rdi, 1 ; Dateideskriptor 1 = stdout (Bildschirm)
mov rsi, msg ; Adresse der zu druckenden Zeichenkette
mov rdx, 13 ; Anzahl der zu druckenden Bytes
syscall ; das Betriebssystem bitten zu druckenUm eine Nachricht auf dem Bildschirm auszugeben, benötigen wir 5 Zeilen. Zuerst legen wir die Syscall-Nummer 1 für write in rax ab. Dann legen wir 1 in rdi ab, um dem Betriebssystem mitzuteilen, dass es auf dem Bildschirm ausgeben soll.
Als Nächstes schreiben wir die Adresse des Strings (msg) in rsi. Danach schreiben wir die Anzahl der Bytes (13) in rdx. Schließlich führen wir syscall aus, um das Betriebssystem zum Drucken aufzufordern.
Was passiert, wenn du write ausführst:
- Die CPU springt in den Linux-Kernel
- Der Kernel erkennt: „write syscall“
- Er liest
rdi(wohin geschrieben werden soll),rsi(wo sich der Text befindet) undrdx(wie viele Bytes)
- Es gibt den Text auf dem Bildschirm aus
- Es gibt die Steuerung an Ihr Programm zurück
Zusammenfügen mit einem String:
section .data
msg db 'Hello', 0x0a ; String mit Zeilenumbruch
section .text
global _start
_start:
mov rax, 1 ; write Syscall
mov rdi, 1 ; stdout
mov rsi, msg ; Adresse des Strings
mov rdx, 6 ; Länge (Hello + Zeilenumbruch = 6 Bytes)
syscall
mov rax, 60 ; exit Syscall
mov rdi, 0
syscallDieses Programm gibt Hello aus und wird dann beendet.
Aufgabe
Schreibe ein Programm, das die Nachricht "Hi" gefolgt von einem Zeilenumbruch ausgibt. Verwende den write-Systemaufruf.
Die Zeichenkette ist bereits für dich in der Testumgebung definiert. Du musst nur die Einrichtung des Systemaufrufs schreiben.
Probier es selbst
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: Den write-Syscall einrichten und aufrufen, um msg auszugeben
; Verwende rax=1, rdi=1, rsi=msg, rdx=msgLen
; Beende das Programm
mov rax, 60
mov rdi, 0
syscallDiese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Grundlagen
1Die Maschine
Was ist eine CPUSpeicherRegister vs. SpeicherWie Befehle funktionierenZwei-Dateien-MusterDie x86-64 ArchitekturÜbe selbstständig: Assembly-Playground