Informatik

Assembler verstehen: Befehle, Register, Schleifen

Assembler verstehen: Befehle, Register, Schleifen
Assembler verstehen: Befehle, Register, Schleifen
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Assemblersprache stellt Maschinenbefehle mit lesbaren Kürzeln wie MOV und ADD dar. Ein Assembler übersetzt diese Befehle in den Maschinencode einer bestimmten Prozessorarchitektur.

Auf dieser Seite lernst du, eine kurze Befehlsfolge zu verfolgen und eine einfache Schleife zu erklären.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Vom lesbaren Befehl zum Maschinencode

Eine CPU führt Maschinenbefehle aus, die als Bitmuster gespeichert sind. Assemblersprache ersetzt solche schwer lesbaren Bitmuster durch kurze symbolische Namen, sogenannte Mnemoniken. ADD steht beispielsweise für eine Addition.

Definition

Assemblersprache

Assemblersprache ist eine maschinennahe, symbolische Darstellung von CPU-Befehlen. Ihre Befehle und ihre genaue Schreibweise hängen von der Prozessorarchitektur und vom verwendeten Werkzeug ab.

Definition

Assembler

Ein Assembler ist ein Übersetzungsprogramm. Er wandelt Assemblersprache in Maschinencode oder in eine Objektdatei um.

Das Wort „Assembler“ wird im Alltag manchmal auch für die Sprache verwendet. Genau genommen unterscheidest du jedoch zwischen Assemblersprache und dem Assembler als Programm.

Ein Assembler erledigt mehr als das bloße Ersetzen von Befehlsnamen. Er kann unter anderem:

  • Mnemoniken in passende Opcodes übersetzen,
  • symbolische Namen durch Adressen ersetzen,
  • zur Übersetzungszeit bekannte Ausdrücke berechnen,
  • Kommentare ignorieren,
  • unzulässige Befehle zurückweisen,
  • Makros verarbeiten und
  • Maschinencode oder Objektdateien erzeugen.
Merke

Assemblersprache ist der symbolische Quelltext. Der Assembler ist das Programm, das diesen Quelltext übersetzt.

Teste dich
Frage 1 von 1LeichtWas ist die Aufgabe eines Assemblers?
Lösung: Er übersetzt Assemblersprache in Maschinencode oder eine Objektdatei. — Der erzeugte Maschinencode ist für eine bestimmte Zielarchitektur bestimmt.
Register und einfache Befehle

Ein Register ist ein kleiner Speicherplatz direkt in der CPU. Befehle können Werte in Register schreiben, Werte verändern oder Ergebnisse zwischen Registern übertragen.

Die folgenden Beispiele verwenden eine vereinfachte Lehrsyntax. Sie zeigt die Grundidee, ist aber kein vollständiger x86-Dialekt.

BefehlWirkung
MOV A 5Schreibe den Wert 5 in Register A.
ADD C AAddiere den Wert aus A zu C und speichere das Ergebnis in C.
DEC BVermindere den Wert in B um 1.
JNZ LoopSpringe zum Label Loop, wenn das Zero-Flag nicht gesetzt ist.
RETKehre im vereinfachten Aufgabenmodell aus der Befehlsfolge zurück.

Ein Label ist ein Name für eine Stelle im Programm. Ein Sprungbefehl kann die Ausführung an diesem Namen fortsetzen.

Beispiel

Betrachte diese drei Befehle:

text MOV A 5 MOV C 0 ADD C A

Nach dem ersten Befehl gilt A = 5. Danach wird C auf 0 gesetzt. ADD C A berechnet schließlich C = 0 + 5. Am Ende steht daher 5 in C.

Teste dich
Frage 1 von 1MittelIn A steht 4, in C steht 3. Was bewirkt ADD C A in der verwendeten Lehrsyntax?
Lösung: In C steht danach 7; A bleibt 4. — Der Befehl addiert den Wert aus A zum bisherigen Wert in C und schreibt nur das Ergebnis nach C.
Wie eine Schleife entsteht

Hochsprachen besitzen fertige Konstruktionen wie for oder while. Auf Maschinenebene entsteht eine Schleife aus einfachen Befehlen:

  1. Ein Zähler erhält einen Anfangswert.
  2. Der Schleifenrumpf verarbeitet Daten.
  3. Der Zähler wird verändert.
  4. Ein bedingter Sprung entscheidet, ob die Schleife wiederholt wird.

Viele Rechenbefehle verändern Flags. Flags sind einzelne Zustandsmerkmale der CPU. Das Zero-Flag zeigt an, ob das Ergebnis einer passenden Operation null war. JNZ bedeutet „springe, wenn nicht null“ und prüft dieses Flag.

Gut zu wissen

Ein bedingter Sprung prüft nicht allgemein „den Wert der letzten Zeile“. Er wertet bestimmte Flags aus, die ein vorheriger Befehl gesetzt hat. Welche Flags verändert werden, hängt vom jeweiligen Befehl ab.

Nun verfolgen wir eine vollständige Schleife:

```text MOV A 5 MOV B 7 MOV C 0

Loop: ADD C A DEC B JNZ Loop RET ```

A enthält den Wert 5. B zählt die Schleifenrunden. C sammelt die Summe.

RundeC nach ADD C AB nach DEC BNoch einmal?
156ja
2105ja
3154ja
4203ja
5252ja
6301ja
7350nein

Die Addition wird siebenmal ausgeführt. Deshalb gilt:

$$C = 7 \cdot 5 = 35$$

Die Schleife berechnet also eine Multiplikation durch wiederholte Addition.

Merke

Beim Verfolgen einer Schleife notierst du nach jeder Runde alle Register, die verändert wurden. So erkennst du sowohl das Zwischenergebnis als auch die Abbruchbedingung.

Teste dich
Frage 1 von 2MittelWas steht nach der dritten Runde der Beispielschleife in B und C?
Lösung: B = 4 und C = 15 — Pro Runde steigt C um 5, während B um 1 sinkt.
Frage 2 von 2SchwerWas berechnet dieselbe Schleifenstruktur bei A = 6 und B = 4, wenn C wieder bei 0 beginnt?
Lösung: Sie addiert viermal 6 und liefert C = 24. — Der Zähler B legt die Rundenzahl fest. Daher gilt C = 4 · 6 = 24.
Warum Assembler hardwarenah und wenig portabel ist

Prozessorarchitekturen legen fest, welche Maschinenbefehle, Register und Kodierungen verfügbar sind. Ein Assembler muss daher zur Zielarchitektur passen. Auch Werkzeuge für dieselbe Prozessorfamilie können unterschiedliche Schreibweisen und Makros verwenden.

Ein Cross-Assembler läuft auf einer Hostplattform, erzeugt aber Code für eine andere Zielplattform. Das ist beispielsweise bei der Entwicklung für Mikrocontroller nützlich.

Ein Disassembler geht in die Gegenrichtung: Er stellt Maschinencode wieder als Assemblersprache dar. Verlorene Kommentare und ursprüngliche symbolische Namen kann er jedoch nicht zuverlässig zurückholen.

Assembler bietet direkten Zugriff auf maschinennahe Möglichkeiten. Dafür entstehen klare Grenzen:

  • Der Code ist stark an Architektur und Syntaxumgebung gebunden.
  • Wartung und Fehlersuche verlangen genaues Prozessorwissen.
  • Ein Wechsel der Zielarchitektur erfordert häufig Anpassungen.
  • Die einfache Zuordnung „eine Anweisung gleich ein Maschinenbefehl“ gilt bei Makros nicht uneingeschränkt.

Hochsprachen verbergen viele Hardwaredetails und lassen sich deshalb meist leichter übertragen. Assembler wird heute vor allem dort eingesetzt, wo direkter Hardwarezugriff oder besondere Kontrolle notwendig oder nützlich ist. Inline-Assembler kann solche Abschnitte in ein Hochsprachenprogramm einbetten.

Teste dich
Frage 1 von 1MittelWarum läuft ein Assemblerprogramm nicht automatisch auf jeder CPU?
Lösung: Weil Befehle, Register und Kodierungen von der Zielarchitektur abhängen. — Maschinenbefehle werden vom Prozessorhersteller festgelegt. Andere Architekturen können andere Befehle und Bitkodierungen besitzen.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Assembler
    • übersetzt Assemblersprache in Maschinencode
    • erzeugt Code für eine Zielarchitektur
  • Assemblersprache
    • verwendet Mnemoniken und Operanden
    • arbeitet mit Registern und Speicher
  • Kontrollfluss
    • Labels markieren Sprungziele
    • Flags steuern bedingte Sprünge
  • Schleife
    • verarbeitet Daten
    • verändert einen Zähler
    • endet bei erfüllter Abbruchbedingung
  • Grenzen
    • architekturabhängig
    • wartungsintensiv
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWelche Aussage unterscheidet Sprache und Werkzeug richtig?
Lösung: Assemblersprache enthält symbolische Befehle; der Assembler übersetzt sie. — Die ähnliche Benennung darf nicht darüber hinwegtäuschen: Quelltext und Übersetzungsprogramm haben verschiedene Rollen.
Frage 2 von 3MittelEine Schleife startet mit A = 3, B = 4 und C = 0. Pro Runde werden ADD C A und danach DEC B ausgeführt. Welcher Zustand beendet die Schleife nach vier Runden?
Lösung: C = 12 und B = 0C wächst viermal um 3; zugleich sinkt B viermal um 1.
Frage 3 von 3SchwerDu möchtest dieselbe Assemblersource unverändert für eine andere Prozessorarchitektur verwenden. Welches Problem ist zuerst zu prüfen?
Lösung: Ob Zielarchitektur, Befehle, Register und Syntax zusammenpassen. — Assemblercode bildet hardwarenahe Eigenschaften ab. Beim Architekturwechsel können Befehle, Register, Kodierungen und Werkzeugsyntax abweichen.

Du hast den Kern verstanden, wenn du eine Befehlsfolge registerweise verfolgen, die Sprungentscheidung erklären und die Architekturabhängigkeit begründen kannst.

Passend dazu