Zum Inhalt springen
L

Wikipedia · einfach zusammengefasst · Stand

Assemblersprache

Eine Assemblersprache, kurz auch Assembler genannt (von englisch to assemble ‚zusammenfügen'), ist eine Programmiersprache, die auf den Befehlsvorrat eines …

Inhalt5 Abschnitte
  1. 1. Grundidee und Übersetzung
  2. 2. Unterschiede und gemeinsame Grundlagen
  3. 3. Befehle, Syntax und Makros
  4. 4. Einsatz, Leistungsfähigkeit und Grenzen
  5. 5. Hallo-Welt-Beispiel und Entwicklung

Grundidee und Übersetzung

Eine Assemblersprache (kurz: Assembler) ist eine maschinenorientierte Programmiersprache, die auf den Befehlsvorrat einer bestimmten Prozessorarchitektur ausgerichtet ist. Sie gehört als Nachfolgerin der direkten Programmierung mit Zahlencodes zur zweiten Programmiersprachengeneration. Statt Binärcode verwendet sie besser lesbare mnemonische Symbole, also Kürzel für Befehle, etwa „MOVE“, sowie teilweise symbolische Adressen wie „PLZ“.

Ein Assemblerprogramm wird als Assemblercode oder Quelltext geschrieben. Ein Übersetzungsprogramm, ebenfalls Assembler oder Assemblierer genannt, wandelt ihn in Maschinencode um. Hochsprachen der dritten Generation werden dagegen durch einen Compiler übersetzt; ihre Befehle sind abstrakter und nicht auf den Befehlssatz eines Prozessors beschränkt. Umgangssprachlich werden „Maschinensprache“ und „Assembler(sprache)“ häufig gleich verwendet.

Der Assembler entfernt unter anderem Kommentare, übersetzt Mnemonics und Operanden in Opcodes, verwaltet Symbole, Konstanten, Speicher und Adressen, wertet Ausdrücke aus und richtet Code und Daten aus (Alignment). Je nach Assembler erzeugt er Objektdaten und Listings, verarbeitet Makros und bedingte Übersetzungen oder unterstützt Module und Bibliotheken.

Unterschiede und gemeinsame Grundlagen

Jede Computerarchitektur besitzt eine eigene Maschinensprache und damit eine eigene Assemblersprache. Für dieselbe Architektur kann es mehrere Dialekte geben, da keine Standardisierung besteht. Unterschiede betreffen die Schreibweise, die unterstützte Architektur und Mikroarchitektur sowie versteckte Bedeutungsunterschiede, etwa Delayed Branches oder Zugriffe auf falsch ausgerichtete Operanden.

So kann derselbe Befehl beim 8080 in Intel-Syntax „STAX B“, beim Z80 in Zilog-Syntax „LD (BC),A“ heißen. Bei aktuellen Prozessoren unterscheiden sich auch Intel- und AT&T-Syntax: „mov eax,[ebx+esi*8+1Fh]“ entspricht „movl 0x1F(%ebx,%esi,8),%eax“. Architekturen wie Intel 80386, Motorola 68000 und MIPS 4000 unterscheiden sich besonders stark durch Register, Adressierungsarten und verfügbare Operationen.

Grundlegende Operationen besitzen jedoch alle Architekturen: Daten zwischen Hauptspeicher und Prozessor beziehungsweise Registern lesen und schreiben, logische Operationen wie AND, OR, NOT und SHIFT, bedingte Sprünge zur Steuerung des Programmflusses sowie einfache Ganzzahl-Arithmetik und -Vergleiche. CISC-Architekturen können zusätzlich komplexe Befehle etwa für Ein- und Ausgabe, Vektor- und Speicherblockoperationen, Gleitkomma-Arithmetik, Parallelität, Synchronisation oder Unterbrechungssteuerung anbieten.

Befehle, Syntax und Makros

Ein Maschinenbefehl besteht aus einem Operationscode (Opcode) und weiteren je nach Befehl festgelegten Angaben, zum Beispiel Adressen, Literalen oder Längen. Da Zahlenwerte von Opcodes schwer zu merken sind, verwendet Assembler Mnemonics.

Beim x86-Prozessor entspricht der Maschinencode „10110000 01100001“, hexadezimal „B0 61“, beispielsweise den Befehlen „movb $0x61, %al“ in AT&T-Syntax und „mov al, 61h“ in Intel-Syntax. Beide laden den Wert „61“ hexadezimal beziehungsweise 97 dezimal in „al“, den niederwertigen Teil des Registers „ax“. Der hochwertige Teil heißt „ah“. Die Dialekte unterscheiden sich dabei: AT&T kennzeichnet die Byte-Größe in „movb“, vertauscht Quelle und Ziel gegenüber Intel und schreibt Register sowie direkte Werte anders.

Assembler können symbolische Adressen in passende Adressen umformen. Zusätzlich zum eigentlichen Code enthalten ihre Eingaben Steueranweisungen, etwa zur Definition eines Basisregisters. Makroassembler erleichtern die Arbeit durch Makros: Parameterisierte Aufrufe werden vor dem Assemblieren automatisch durch meist kurze Befehlsfolgen ersetzt. Beim Disassemblieren, also der Rückwandlung von Maschinencode in Assembler, erscheinen solche Makros nicht mehr. Ohne Debug-Informationen ist Disassemblierung stark verlustbehaftet, weil ursprüngliche Bezeichner und Kommentare im Maschinencode nicht enthalten sind.

Einsatz, Leistungsfähigkeit und Grenzen

Assembler wird eingesetzt, wenn sehr geringer Speicherbedarf, Echtzeitverhalten oder besonders hohe Leistung wichtig sind. Genannt werden Embedded-Prozessoren, Hardware-Treiber, High-Performance-Bibliotheken, SIMD-intensiver Code, Kryptoroutinen mit konstanter Laufzeit sowie Computergrafik, Video-Codecs und Signalverarbeitung. Bei SIMD sind gegenüber C++ Faktoren von 20 bis 30 nicht selten. Programme können alle Möglichkeiten eines Mikroprozessors nutzen; das ist heute aber nur selten nötig.

Auch bei hochoptimierenden Compilern kann Assembler zur Geschwindigkeitsoptimierung sinnvoll sein. Bei komplexen Architekturen wie Intel Itanium oder digitalen Signalprozessoren kann ein Compiler jedoch besseren Code erzeugen als ein durchschnittlicher Assemblerprogrammierer, weil Out-of-order execution und Pipeline-Stalls das Ablaufverhalten hochgradig nichtlinear machen. Optimierung benötigt außerdem Kontextwissen, etwa über Cache-Nutzung sowie räumliche und zeitliche Lokalität von Speicherzugriffen. Ein Programmierer kann dieses teilweise durch Laufzeitprofiling gewinnen; der SSE-Befehl MOVNTQ wird wegen fehlenden Kontextwissens von Compilern kaum optimal eingesetzt.

Assembler ist für bestimmte systemnahe Aufgaben notwendig, die übliche Hochsprachen nicht abbilden: frühe Startphasen eines Betriebssystems, Spezialregister der Systemverwaltung, Prozesswechsel und Interrupts, Koroutinenverwaltung sowie Übergänge zwischen User- und Systemmode. Auch Startup-Code bereitet in ausführbaren Programmen den Start von Hochsprachen-Code vor. Vorteile sind Mikro-Optimierungen, etwa bei BLAS oder architekturabhängigen Varianten von memcpy, und teils direkte Hardwarezugriffe wie Schreiben in den Bildschirmspeicher.

Nachteile sind die starke Bindung an eine Prozessorarchitektur und die schwierige Übertragbarkeit auf andere Systeme. Je nach Unterschied kann eine Anpassung bis zum vollständigen Neuschreiben nötig sein; bei Hochsprachen genügt oft ein Compiler für die Zielplattform. Assemblerquelltexte sind meist deutlich länger, weil einfache Instruktionen für komplexere Aufgaben kombiniert werden müssen. Das erhöht das Risiko von unübersichtlichem, schlecht wartbarem Code.

Hallo-Welt-Beispiel und Entwicklung

Ein MASM-Programm für MS-DOS definiert zunächst ein Datensegment mit der Zeichenkette „Hallo Welt“, den Bytes 13 und 10 für eine neue Zeile sowie „$“ als Ende der Zeichenkette für INT 21h, Unterfunktion 09h. Im Codesegment lädt es die Adresse des Datensegments in „AX“ und danach in „DS“, legt die relative Adresse der Meldung in „DX“ ab und ruft mit „mov ah, 09h“ sowie „int 21h“ die Textausgabe auf. Mit „mov ax, 4C00h“ und einem weiteren „int 21h“ wird das Programm beendet. „END Anfang“ teilt Assembler und Linkprogramm den Einsprung-Label mit. In Pascal genügt dafür dagegen: „program Hallo(output); begin writeln('Hallo Welt') end.“

Die erste Assemblersprache entwickelte Kathleen Booth 1947; zwischen 1948 und 1950 schrieb Nathaniel Rochester einen frühen symbolischen Assembler für eine IBM 701. In den 1980er und frühen 1990er Jahren wurden Betriebssysteme für größere Rechner meist von Assembler auf C, teils C++ oder Objective C umgestellt. Gründe waren die steigende Komplexität und Speicher oberhalb von einem Megabyte. Assembler blieb etwa für Registerzwischenspeicherung beim Prozesswechsel und für den auf 512 Byte begrenzten Master Boot Record.

Bis etwa 1990 entstanden die meisten Computerspiele in Assembler, weil Heimcomputer und Spielkonsolen nur so ausreichend schnell und klein programmiert werden konnten. Bei Mikrocontrollern war Assembler früher wegen knapper Ressourcen oft erforderlich; Cross-Assembler übersetzen dabei auf dem Entwicklungsrechner. Heute haben leistungsfähigere und günstigere Mikrocontroller sowie moderne C-Compiler Assembler dort weitgehend verdrängt. Assembler wird weiterhin auch gelehrt, um Rechnerarchitektur und die Arbeitsweise eines Systems zu verstehen.

Lernvideos zu Assemblersprache

Weiterlesen

Programmiersprache Bei deklarativen Programmiersprachen ist der Ausführungsalgorithmus schon vorab festgelegt und wird nicht im Quelltext ausformuliert/beschrieben, sondern es … Befehlssatz Der Befehlssatz, auch Instruktionssatz (englisch instruction set), eines Prozessors ist in der Rechnerarchitektur die Menge der Maschinenbefehle, die ein … Prozessor Aufbau und Funktionale Einheiten · Hauptprozessor (CPU) und Mehrprozessorkerne · Steuer- bzw. Leitwerk · Rechenwerk und Register · Datenleitungen · Caches und MMU. Binärcode Ein Binärcode ist ein Code, in dem Informationen durch Sequenzen von zwei verschiedenen Symbolen (zum Beispiel 1/0 oder wahr/falsch) dargestellt werden. Maschinensprache Mit einem Assembler: Assemblersprachen formulieren die Prozessorbefehle des Maschinencodes als Mnemonics in einer einfachen Syntax. Dieser Quelltext wird … Anweisung (Programmierung) Anweisungen sind üblicherweise Zuweisungen, Kontrollanweisungen (wie Sprünge, Schleifen und bedingte Anweisungen) und Prozeduraufrufe. Abhängig von der … Quelltext Quelltext, auch Quellcode (englisch source code) oder unscharf Programmcode genannt, ist in der Informatik der für Menschen lesbare, in einer … Assembler (Informatik) Ein Assembler (auch Assemblierer) ist ein Computerprogramm, das Quelltext in Maschinensprache übersetzt. Der Quelltext eines Assemblerprogramms ist in … Höhere Programmiersprache Eine höhere Programmiersprache ist eine Programmiersprache zur Abfassung eines Computerprogramms, die in Abstraktion und Komplexität von der Ebene der … Compiler Ein Übersetzer zur Übertragung von Assembler-Quellprogrammen in Maschinensprache wird als Assembler oder Assemblierer bezeichnet. Geschichte. Bearbeiten. Mikroprozessor Ein Mikroprozessor (µP oder uP) ist ein als integrierter Schaltkreis (IC) ausgeführter Computerprozessor. Typische Beispiele von Mikroprozessoren sind die … Pipeline-Hazard Pipeline-Hazards sind Konflikte in der Pipeline von Prozessoren, die während der Programmlaufzeit auftreten können. Alle modernen Prozessoren sind in …