Das erste Programm "Hello World": Unterschied zwischen den Versionen
KKeine Bearbeitungszusammenfassung |
KKeine Bearbeitungszusammenfassung |
||
| (6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
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. | == 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"> | <syntaxhighlight lang="asm"> | ||
. | .globl _start // Definition der Einsprungadresse als GLOBAL, also der Startpunkt des Programms | ||
_start: // Label, das den Start des Programms markiert | _start: // Label, das den Start des Programms markiert | ||
| Zeile 19: | Zeile 22: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Schritt-für-Schritt-Erklärung == | === Schritt-für-Schritt-Erklärung === | ||
=== Globaler Startpunkt === | ==== Globaler Startpunkt ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
.global _start | .global _start | ||
| Zeile 26: | Zeile 29: | ||
Dies definiert _start als global, sodass es vom Betriebssystem als der Startpunkt des Programms erkannt wird. | Dies definiert _start als global, sodass es vom Betriebssystem als der Startpunkt des Programms erkannt wird. | ||
=== Programmstart === | ==== Programmstart ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
_start: | _start: | ||
| Zeile 32: | Zeile 35: | ||
Dieses Label (_start:) markiert den Beginn des Programms. Bei Programmausführung beginnt der Prozessor hier. | Dieses Label (_start:) markiert den Beginn des Programms. Bei Programmausführung beginnt der Prozessor hier. | ||
=== Ausgabe auf Standardausgabe vorbereiten === | ==== Ausgabe auf Standardausgabe vorbereiten ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x0, #1 | mov x0, #1 | ||
| Zeile 38: | Zeile 41: | ||
Der Inhalt des Registers x0 wird auf 1 gesetzt, was den Standardausgabegerät (meistens der Bildschirm) symbolisiert. | Der Inhalt des Registers x0 wird auf 1 gesetzt, was den Standardausgabegerät (meistens der Bildschirm) symbolisiert. | ||
=== Adresse des Strings in ein Register laden === | ==== Adresse des Strings in ein Register laden ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
ldr x1, =helloworld | ldr x1, =helloworld | ||
| Zeile 44: | Zeile 47: | ||
Der Speicherort (die Adresse) des “helloworld”-Strings wird in das Register x1 geladen. | Der Speicherort (die Adresse) des “helloworld”-Strings wird in das Register x1 geladen. | ||
=== Die Länge des Strings spezifizieren === | ==== Die Länge des Strings spezifizieren ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x2, #13 | mov x2, #13 | ||
| Zeile 50: | Zeile 53: | ||
Der Wert 13 wird in das Register x2 geladen, was die Länge des Strings "Hello World!\n" (12 Zeichen + neues Zeilenzeichen) darstellt. | 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 === | ==== Systemcall für Output (Schreiben) definieren ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x8, #64 | mov x8, #64 | ||
| Zeile 56: | Zeile 59: | ||
Der Wert 64 wird in das Register x8 geladen. Dies ist der Befehlscode für den Systemcall write (zum Schreiben auf den Bildschirm). | 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 === | ==== Systemcall ausführen ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
svc 0 | svc 0 | ||
| Zeile 62: | Zeile 65: | ||
Dies führt den Systemcall aus und schreibt den String auf den Bildschirm. | Dies führt den Systemcall aus und schreibt den String auf den Bildschirm. | ||
=== Erfolg melden und Programm beenden === | ==== Erfolg melden und Programm beenden ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x0, #0 | mov x0, #0 | ||
| Zeile 68: | Zeile 71: | ||
Setzt x0 auf 0, was "keine Fehler" bedeutet. | Setzt x0 auf 0, was "keine Fehler" bedeutet. | ||
=== Systemcall für Exit (Beenden) setzen === | ==== Systemcall für Exit (Beenden) setzen ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
mov x8, #93 | mov x8, #93 | ||
| Zeile 74: | Zeile 77: | ||
Der Wert 93 wird in x8 geladen, was der Befehlscode für exit (Programm beenden) ist. | Der Wert 93 wird in x8 geladen, was der Befehlscode für exit (Programm beenden) ist. | ||
=== Systemcall ausführen === | ==== Systemcall ausführen ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
svc 0 | svc 0 | ||
| Zeile 80: | Zeile 83: | ||
Führt den Systemcall aus, um das Programm zu beenden. | Führt den Systemcall aus, um das Programm zu beenden. | ||
=== Datenbereich === | ==== Datenbereich ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
.data | .data | ||
| Zeile 86: | Zeile 89: | ||
Dies markiert den Beginn des Datenbereichs, wo unsere Daten (der String) gespeichert werden. | Dies markiert den Beginn des Datenbereichs, wo unsere Daten (der String) gespeichert werden. | ||
=== String definieren === | ==== String definieren ==== | ||
<syntaxhighlight lang="asm"> | <syntaxhighlight lang="asm"> | ||
helloworld: | helloworld: | ||
| Zeile 93: | Zeile 96: | ||
Hier wird der String (Hello World!\n) definiert und die Adresse als helloworld markiert. \n steht für einen Zeilenumbruch. | Hier wird der String (Hello World!\n) definiert und die Adresse als helloworld markiert. \n steht für einen Zeilenumbruch. | ||
== Kompilieren und Ausführen == | === Kompilieren und Ausführen === | ||
Um das Programm zum Laufen zu bringen, sind nun folgende Schritte nötig: | Um das Programm zum Laufen zu bringen, sind nun folgende Schritte nötig: | ||
=== Kompilieren === | ==== Kompilieren ==== | ||
<syntaxhighlight lang="shell"> | <syntaxhighlight lang="shell"> | ||
as -o HelloWorld.o HelloWorld.s | as -o HelloWorld.o HelloWorld.s | ||
| Zeile 102: | Zeile 105: | ||
Dies übersetzt den Assembler-Code (HelloWorld.s) in ein Objektfile (HelloWorld.o). | Dies übersetzt den Assembler-Code (HelloWorld.s) in ein Objektfile (HelloWorld.o). | ||
=== Linken === | ==== Linken ==== | ||
<syntaxhighlight lang="shell"> | <syntaxhighlight lang="shell"> | ||
ld -o HelloWorld HelloWorld.o | ld -o HelloWorld HelloWorld.o | ||
| Zeile 108: | Zeile 111: | ||
Dies verbindet das Objektfile und erstellt ein ausführbares Programm namens HelloWorld. | Dies verbindet das Objektfile und erstellt ein ausführbares Programm namens HelloWorld. | ||
=== Ausführen === | ==== Ausführen ==== | ||
<syntaxhighlight lang="shell"> | <syntaxhighlight lang="shell"> | ||
./HelloWorld | ./HelloWorld | ||
| Zeile 114: | Zeile 117: | ||
Dies führt das Programm aus und sollte "Hello World!" auf dem Bildschirm ausgeben. | Dies führt das Programm aus und sollte "Hello World!" auf dem Bildschirm ausgeben. | ||
== Erklärung in einfachen Worten == | === Erklärung in einfachen Worten === | ||
Wir gehen später nochmal auf alles ein und versuchen es spezifischer zu erklären. | Wir gehen später nochmal auf alles ein und versuchen es spezifischer zu erklären. | ||
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.