Das erste Programm "Hello World": Unterschied zwischen den Versionen
KKeine Bearbeitungszusammenfassung |
KKeine Bearbeitungszusammenfassung |
||
| (8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
== Das erste Programm == | |||
In der Programmierung ist es traditionell, mit einem einfachen Programm zu beginnen, das "Hello World" auf dem Bildschirm ausgibt. In Assembler für ARM64 können wir dies auch tun. | |||
Hier ist der vollständige Code und eine Erklärung, was jeder Abschnitt macht. | |||
<syntaxhighlight lang="asm"> | |||
.globl _start // Definition der Einsprungadresse als GLOBAL, also der Startpunkt des Programms | |||
_start: // Label, das den Start des Programms markiert | |||
mov x0, #1 // Setze das Register x0 auf 1, was StdOutput (Standardausgabe, wie der Bildschirm) bedeutet | |||
ldr x1, =helloworld // Lade die Adresse des Strings "helloworld" in das Register x1 | |||
mov x2, #13 // Setze das Register x2 auf 13, die Länge des Strings "Hello World!\n" | |||
mov x8, #64 // Systemcall für Output (Schreiben auf den Bildschirm) | |||
svc 0 // Führe den Systemcall aus | |||
mov x0, #0 // Setze das Register x0 auf 0, was "keine Fehler" bedeutet | |||
mov x8, #93 // Systemcall für Exit (Programm beenden) | |||
svc 0 // Führe den Systemcall aus | |||
.data // Definition des Datenbereichs | |||
helloworld: // Label für den String, der angezeigt werden soll | |||
.ascii "Hello World!\n" // Der String selbst, der ausgegeben wird | |||
</syntaxhighlight> | |||
=== Schritt-für-Schritt-Erklärung === | |||
==== Globaler Startpunkt ==== | |||
<syntaxhighlight lang="asm"> | |||
.global _start | |||
</syntaxhighlight> | |||
Dies definiert _start als global, sodass es vom Betriebssystem als der Startpunkt des Programms erkannt wird. | |||
==== Programmstart ==== | |||
<syntaxhighlight lang="asm"> | |||
_start: | |||
</syntaxhighlight> | |||
Dieses Label (_start:) markiert den Beginn des Programms. Bei Programmausführung beginnt der Prozessor hier. | |||
==== Ausgabe auf Standardausgabe vorbereiten ==== | |||
<syntaxhighlight lang="asm"> | |||
mov x0, #1 | |||
</syntaxhighlight> | |||
Der Inhalt des Registers x0 wird auf 1 gesetzt, was den Standardausgabegerät (meistens der Bildschirm) symbolisiert. | |||
==== Adresse des Strings in ein Register laden ==== | |||
<syntaxhighlight lang="asm"> | |||
ldr x1, =helloworld | |||
</syntaxhighlight> | |||
Der Speicherort (die Adresse) des “helloworld”-Strings wird in das Register x1 geladen. | |||
==== Die Länge des Strings spezifizieren ==== | |||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x2, #13 | |||
</syntaxhighlight> | |||
Der Wert 13 wird in das Register x2 geladen, was die Länge des Strings "Hello World!\n" (12 Zeichen + neues Zeilenzeichen) darstellt. | |||
==== Systemcall für Output (Schreiben) definieren ==== | |||
<syntaxhighlight lang="asm"> | |||
mov x8, #64 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Der Wert 64 wird in das Register x8 geladen. Dies ist der Befehlscode für den Systemcall write (zum Schreiben auf den Bildschirm). | |||
==== Systemcall ausführen ==== | |||
<syntaxhighlight lang="asm"> | |||
svc 0 | |||
</syntaxhighlight> | |||
Dies führt den Systemcall aus und schreibt den String auf den Bildschirm. | |||
==== Erfolg melden und Programm beenden ==== | |||
<syntaxhighlight lang="asm"> | |||
mov x0, #0 | |||
</syntaxhighlight> | |||
Setzt x0 auf 0, was "keine Fehler" bedeutet. | |||
==== Systemcall für Exit (Beenden) setzen ==== | |||
<syntaxhighlight lang="asm"> | |||
mov x8, #93 | |||
</syntaxhighlight> | |||
Der Wert 93 wird in x8 geladen, was der Befehlscode für exit (Programm beenden) ist. | |||
==== Systemcall ausführen ==== | |||
<syntaxhighlight lang="asm"> | |||
svc 0 | |||
</syntaxhighlight> | |||
Führt den Systemcall aus, um das Programm zu beenden. | |||
==== Datenbereich ==== | |||
<syntaxhighlight lang="asm"> | |||
.data | |||
</syntaxhighlight> | |||
Dies markiert den Beginn des Datenbereichs, wo unsere Daten (der String) gespeichert werden. | |||
==== String definieren ==== | |||
<syntaxhighlight lang="asm"> | |||
helloworld: | |||
.ascii "Hello World!\n" | |||
</syntaxhighlight> | |||
Hier wird der String (Hello World!\n) definiert und die Adresse als helloworld markiert. \n steht für einen Zeilenumbruch. | |||
=== Kompilieren und Ausführen === | |||
Um das Programm zum Laufen zu bringen, sind nun folgende Schritte nötig: | |||
==== Kompilieren ==== | |||
<syntaxhighlight lang="shell"> | <syntaxhighlight lang="shell"> | ||
as -o HelloWorld.o HelloWorld.s | as -o HelloWorld.o HelloWorld.s | ||
</syntaxhighlight> | |||
Dies übersetzt den Assembler-Code (HelloWorld.s) in ein Objektfile (HelloWorld.o). | |||
==== Linken ==== | |||
<syntaxhighlight lang="shell"> | |||
ld -o HelloWorld HelloWorld.o | ld -o HelloWorld HelloWorld.o | ||
</syntaxhighlight> | |||
Dies verbindet das Objektfile und erstellt ein ausführbares Programm namens HelloWorld. | |||
==== Ausführen ==== | |||
<syntaxhighlight lang="shell"> | |||
./HelloWorld | ./HelloWorld | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Dies führt das Programm aus und sollte "Hello World!" auf dem Bildschirm ausgeben. | |||
=== Erklärung in einfachen Worten === | |||
Wir gehen später nochmal auf alles ein und versuchen es spezifischer zu erklären. | |||
* mov, ldr, und svc sind Befehle, die dem Computer sagen, was er tun soll, wie das Bewegen von Daten oder das Ausführen von Systembefehlen. | |||
* Register (x0, x1, x2, x8) sind wie kleine Speicherplätze im Prozessor, die Daten zwischenspeichern. | |||
* Labels (_start und helloworld) sind Markierungen, die bestimmte Stellen im Code benennen. | |||
* Systemaufrufe (wie svc 0) sind spezielle Befehle, die dem Betriebssystem sagen, dass es etwas für unser Programm tun soll - wie auf den Bildschirm schreiben oder das Programm beenden. | |||
Aktuelle Version vom 1. Dezember 2024, 16:15 Uhr
Das erste Programm
In der Programmierung ist es traditionell, mit einem einfachen Programm zu beginnen, das "Hello World" auf dem Bildschirm ausgibt. In Assembler für ARM64 können wir dies auch tun.
Hier ist der vollständige Code und eine Erklärung, was jeder Abschnitt macht.
.globl _start // Definition der Einsprungadresse als GLOBAL, also der Startpunkt des Programms
_start: // Label, das den Start des Programms markiert
mov x0, #1 // Setze das Register x0 auf 1, was StdOutput (Standardausgabe, wie der Bildschirm) bedeutet
ldr x1, =helloworld // Lade die Adresse des Strings "helloworld" in das Register x1
mov x2, #13 // Setze das Register x2 auf 13, die Länge des Strings "Hello World!\n"
mov x8, #64 // Systemcall für Output (Schreiben auf den Bildschirm)
svc 0 // Führe den Systemcall aus
mov x0, #0 // Setze das Register x0 auf 0, was "keine Fehler" bedeutet
mov x8, #93 // Systemcall für Exit (Programm beenden)
svc 0 // Führe den Systemcall aus
.data // Definition des Datenbereichs
helloworld: // Label für den String, der angezeigt werden soll
.ascii "Hello World!\n" // Der String selbst, der ausgegeben wird
Schritt-für-Schritt-Erklärung
Globaler Startpunkt
.global _start
Dies definiert _start als global, sodass es vom Betriebssystem als der Startpunkt des Programms erkannt wird.
Programmstart
_start:
Dieses Label (_start:) markiert den Beginn des Programms. Bei Programmausführung beginnt der Prozessor hier.
Ausgabe auf Standardausgabe vorbereiten
mov x0, #1
Der Inhalt des Registers x0 wird auf 1 gesetzt, was den Standardausgabegerät (meistens der Bildschirm) symbolisiert.
Adresse des Strings in ein Register laden
ldr x1, =helloworld
Der Speicherort (die Adresse) des “helloworld”-Strings wird in das Register x1 geladen.
Die Länge des Strings spezifizieren
mov x2, #13
Der Wert 13 wird in das Register x2 geladen, was die Länge des Strings "Hello World!\n" (12 Zeichen + neues Zeilenzeichen) darstellt.
Systemcall für Output (Schreiben) definieren
mov x8, #64
Der Wert 64 wird in das Register x8 geladen. Dies ist der Befehlscode für den Systemcall write (zum Schreiben auf den Bildschirm).
Systemcall ausführen
svc 0
Dies führt den Systemcall aus und schreibt den String auf den Bildschirm.
Erfolg melden und Programm beenden
mov x0, #0
Setzt x0 auf 0, was "keine Fehler" bedeutet.
Systemcall für Exit (Beenden) setzen
mov x8, #93
Der Wert 93 wird in x8 geladen, was der Befehlscode für exit (Programm beenden) ist.
Systemcall ausführen
svc 0
Führt den Systemcall aus, um das Programm zu beenden.
Datenbereich
.data
Dies markiert den Beginn des Datenbereichs, wo unsere Daten (der String) gespeichert werden.
String definieren
helloworld:
.ascii "Hello World!\n"
Hier wird der String (Hello World!\n) definiert und die Adresse als helloworld markiert. \n steht für einen Zeilenumbruch.
Kompilieren und Ausführen
Um das Programm zum Laufen zu bringen, sind nun folgende Schritte nötig:
Kompilieren
as -o HelloWorld.o HelloWorld.s
Dies übersetzt den Assembler-Code (HelloWorld.s) in ein Objektfile (HelloWorld.o).
Linken
ld -o HelloWorld HelloWorld.o
Dies verbindet das Objektfile und erstellt ein ausführbares Programm namens HelloWorld.
Ausführen
./HelloWorld
Dies führt das Programm aus und sollte "Hello World!" auf dem Bildschirm ausgeben.
Erklärung in einfachen Worten
Wir gehen später nochmal auf alles ein und versuchen es spezifischer zu erklären.
- mov, ldr, und svc sind Befehle, die dem Computer sagen, was er tun soll, wie das Bewegen von Daten oder das Ausführen von Systembefehlen.
- Register (x0, x1, x2, x8) sind wie kleine Speicherplätze im Prozessor, die Daten zwischenspeichern.
- Labels (_start und helloworld) sind Markierungen, die bestimmte Stellen im Code benennen.
- Systemaufrufe (wie svc 0) sind spezielle Befehle, die dem Betriebssystem sagen, dass es etwas für unser Programm tun soll - wie auf den Bildschirm schreiben oder das Programm beenden.