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ötigen Sie den write-Systemaufruf.
Was ist der write-Syscall?
Der write-Syscall weist das Betriebssystem an, Text auf dem Bildschirm auszugeben (oder in eine Datei zu schreiben). So erzeugt Ihr Programm Ausgaben.
Die Syscall-Nummer für write ist 1.
Wie write funktioniert:
Im Gegensatz zum exit-Syscall (der nur ein Argument benötigt), benötigt write drei Argumente:
| Argument | Register | Funktion | Beispiel |
|---|---|---|---|
| Dateideskriptor | rdi | Wohin geschrieben werden soll (1 = Bildschirm) | mov rdi, 1 |
| Pufferadresse | rsi | Wo sich der Text im Speicher befindet | mov rsi, message |
| Byte-Anzahl | rdx | Wie viele Bytes ausgegeben werden sollen | mov rdx, 13 |
Der write-Syscall in Aktion:
mov rax, 1 ; Syscall-Nummer für write
mov rdi, 1 ; Dateideskriptor 1 = stdout (Bildschirm)
mov rsi, msg ; Adresse des zu druckenden Strings
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 schreiben wir die Syscall-Nummer 1 in rax für write. Dann schreiben wir 1 in rdi, 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 Sie write ausführen:
- Die CPU springt in den Linux-Kernel
- Der Kernel sieht: „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
Schreiben Sie ein Programm, das die Nachricht "Hi" gefolgt von einem Zeilenumbruch ausgibt. Verwenden Sie den write-Systemaufruf.
Der String ist bereits im Test-Harness für Sie definiert. Sie müssen nur das Setup für den Systemaufruf 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