Assemblersprache

Assemblersprache

Eine Assemblersprache (oft abgekürzt als ASM bzw. asm) ist eine spezielle Programmiersprache, welche die Maschinensprache einer spezifischen Prozessorarchitektur in einer für den Menschen lesbaren Form repräsentiert. Jede Computerarchitektur hat folglich ihre eigene Assemblersprache.

Inhaltsverzeichnis

Übersicht

Ein Programm in Assemblersprache wird auch als Assemblercode bezeichnet. Es wird durch einen speziellen Compiler, ebenfalls Assembler genannt, in direkt ausführbare Maschinensprache (auch Maschinencode) umgewandelt. Die umgekehrte Umsetzung von Maschinencode in menschenlesbaren Assemblercode wird Disassemblierung genannt. Allerdings lassen sich dabei beiläufige Informationen wie Bezeichner und Kommentare nicht wiederherstellen, da diese bereits bei der Compilierung unwiederbringlich verloren gingen, was ein Verstehen des Programms erschwert.

Programme in Assemblersprache zeichnen sich dadurch aus, dass man die komplette Bandbreite des Computers ausnutzen und Hardwarechips direkt programmieren kann. Weil Assemblerprogramme faktisch auf Maschinencode-Ebene arbeiten, sind sie oftmals erheblich kleiner und schneller als Programme, die einen ähnlichen Grad an Komplexität aufweisen, aber eine Hochsprache als Basis haben. Der Compiler einer höheren Programmiersprache erzeugt meistens mehr Code, weil er stark generalisiert geschrieben werden muss. Die zwingende Nutzung von Assemblersprache ist heutzutage selten erforderlich, außer wenn Programme bzw. Teile davon sehr zeitkritisch sind (beispielsweise bei der Programmierung von Gerätetreibern für Grafikkarten) oder nur einen sehr geringen Speicherplatzbedarf aufweisen dürfen (z. B. in eingebetteten Systemen) oder einfach noch keine Hochsprach-Bibliotheken existieren, z. B. bei völlig neuer Technik. Prinzipiell wird immer mehr an maschinennaher Programmierung – die Domäne von Assembler – heute durch höhere Programmiersprachen abgedeckt. Auch steht der Möglichkeit der Erstellung effizienter Programme die erschwerte Pflege von Assemblerprogrammen gegenüber. Weitere Nachteile von Assemblercode sind u. a. höhere Fehleranfälligkeit (durch erhöhte Komplexität), damit verbunden extrem großer Programmieraufwand bei umfangreichen Projekten und die (praktische) Unmöglichkeit des Portierens auf eine andere Hardware.

Unter dem Aspekt der Geschwindigkeitsoptimierung kann der Einsatz von Assemblercode auch bei verfügbaren hochoptimierten Compilern noch seine Berechtigung haben, muss aber differenziert betrachtet und für die spezifische Anwendung abgewogen werden. Bei komplexer Technik wie Intel Itanium und verschiedenen DSPs kann ein Compiler u. U. durchaus besseren Code erzeugen als ein durchschnittlicher Assemblerprogrammierer, da das Ablaufverhalten solcher Architekturen mit komplexen mehrstufigen intelligenten Optimierungen (z. B.: Out-of-Order Excecution, Pipeline-Stalls, …) hochgradig nichtlinear ist. Die Geschwindigkeitsoptimierung wird immer komplexer, da zahlreiche Nebenbedingungen eingehalten werden müssen, ein gleichermaßen wachsendes Problem für die durchaus immer besser werdenden Compiler der Hochsprachen als auch für Programmierer der Assemblersprache. Für einen optimalen Code wird immer mehr Kontextwissen benötigt (z. B.: Cachenutzung, räumliche und zeitliche Lokalität der Speicherzugriffe), welches der Assembler-Programmierer teilweise (im Gegensatz zum Compiler) durch Laufzeitprofiling des ausgeführten Codes in seinem angestrebten Anwendungsfeld gewinnen kann. Ein Beispiel hierfür ist der SSE-Befehl MOVNTQ, welcher wegen des fehlenden Kontextwissens von Compilern kaum optimal eingesetzt werden kann.

Beschreibung

Programmbefehle in Maschinensprache – Instruktionen – sind einfache Bitmuster, die sich aus den Opcodes und den zugehörigen Daten bilden. Da die Zahlenwerte der Opcodes schwieriger zu merken sind, verwendet eine Assemblersprache besser merkbare Kürzel, so genannte mnemonische Symbole (kurz Mnemonics).

Beispiel:

Der folgende Befehl in der Maschinensprache von x86-Prozessoren

 10110000 01100001

entspricht dem Assemblerbefehl

 movb $0x61, %al    ; AT&T-Syntax (Zeichen nach einem „;“ gelten als Kommentare)

bzw.

 mov al, 61h        ; Intel-Syntax

und bedeutet, dass der hexadezimale Wert 61 (97 dezimal) ins Register ‚al‘ geladen werden soll (al: dabei steht das ‚a‘ für das Register, und das ‚l‘ für low, was praktisch dem ersten Teil des Registers entspricht). Der zweite Teil des Registers wird mit einem ‚h‘ ausgezeichnet, das ‚h‘ steht für High (Also: ‚ah‘). Soll das ganze Register (je nach Speicherbedarfs des Typs, der gespeichert werden soll) angesprochen werden, wird ‚l‘ bzw. ‚h‘ durch ein ‚x‘ ersetzt: ‚ax‘. Mit Computerhilfe kann man das eine in das andere weitgehend eins zu eins übersetzen. Jedoch werden Adressumformungen vorgenommen, so dass man symbolische Adressen benutzen kann. Im Allgemeinen haben die Assembler neben den eigentlichen Codes auch Steueranweisungen, die die Programmierung bequemer machen, zum Beispiel zur Definition eines Basisregisters.

Häufig werden komplexere Assemblersprachen (Makroassembler) verwendet, um die Programmierarbeit zu erleichtern. Makros sind dabei Bruchstücke von Assemblercode, der vor dem eigentlichen Assemblieren automatisch an Stelle der Makroaufrufe eingefügt wird. Dabei können einfache Parameterersetzungen vorgenommen werden. Die Disassemblierung von derart generiertem Code ergibt allerdings den reinen Assemblercode ohne die beim Übersetzen expandierten Makros.

Beispielprogramme

Hello World in Assemblersprache (MASM für MS-DOS)

DATA SEGMENT ;- Beginn des Datensegments
Meldung db "Hello World" ;- Die Zeichenkette "Hello World"
        db "$"             ;- Endzeichen der Zeichenkette
DATA ENDS ;- Ende des Datensegments
CODE SEGMENT ;- Beginn des Codesegements
ASSUME CS:CODE,DS:DATA ;- dem Assembler die Segmente mitteilen
Anfang: ;- Label für den Anfang des Programms
mov ax, DATA ;- das Daten...
mov ds, ax ; ...segment festlegen
mov dx, offset Meldung ;- den Text in das auf DS bezogene Datenregister laden
mov ah, 09h ;- die Unterfunktion 9 des Betriebssysteminterrupts 21h auswählen
int 21h ;- den Betriebssysteminterrupt 21h (hier erfolgt Ausgabe des Texts) aufrufen
mov ax, 4C00h ;- die Unterfunktion 4Ch (Programmbeendigung) des Betriebssysteminterrupts 21h festlegen
int 21h ;- diesen Befehl wiederum ausführen 
CODE ENDS ;- Ende des Codesegments
END Anfang ;- dem Assembler das Ende des Labels Anfang mitteilen

Hello World in Assemblersprache (NASM für MS-DOS)

ORG 100h ; Startoffset auf 100h setzen (Startpunkt für COM-Programme)
 
mov ax, cs ; Wert des Codesegmentregisters in Register ax übertragen
mov ds, ax ; Datensegment auf Wert von ax setzen
 
mov ah, 09h ; DOS-Funktion zum Schreiben von Text
mov dx, Meldung ; Adresse des Textes
int 21h ; DOS-Funktion ausführen
 
mov ax, 4C00h ; DOS-Funktion um das Programm zu beenden
int 21h
 
Meldung: db "Hello World" ; unser Text
         db "$"             ; markiert das Ende der Zeichenkette

Hello World in Assemblersprache (MIPS-Architektur)

.data
out:  .asciiz "Hallo Welt"        # die Zeichenkette zum Ausgeben (als Label)
 
.text
main:  li $v0, 4             # Befehl 4 ('print_string') in Register schreiben
        la $a0, out           # Argument für den Systemaufruf in das Argumentregister schreiben
        syscall                        # Ausführung der Systemfunktion (Ausgabe)
        li $v0, 10            # Befehl 10 ('exit') in Register schreiben
        syscall                        # Ausführung der Systemfunktion (Programmende)

Hello World in Assemblersprache (Jasmin)

; HelloWorld.j
.bytecode 50.0
.source HelloWorld.java
.class public HelloWorld
.super java/lang/Object
 
.method public <init>()V
  .limit stack 1
  .limit locals 1
  aload_0
  invokespecial java/lang/Object/<init>()V
  return
.end method
 
.method public static main([Ljava/lang/String;)V
  .limit stack 2
  .limit locals 1
  getstatic java/lang/System/out Ljava/io/PrintStream;
  ldc "Hello World!"
  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  return
.end method

Der zum Assembler-Quelltext HelloWorld.j zugehörige Java-Quelltext HelloWorld.java lautet:

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello World!");    
  }
}

Verschiedene Assemblersprachen

Jede Computerarchitektur hat ihre eigene Maschinensprache und damit Assemblersprache. Vereinzelt existieren sogar mehrere verschiedene Assemblersprachen (und zugehörige Assembler) für die gleiche Prozessorarchitektur. Die Beispiele (mit Ausnahme des Jasmin-Beispiels) oben sind für x86-Prozessoren. Die Sprachen unterscheiden sich in Anzahl und Typ der Operationen.

Jedoch haben alle Architekturen die folgenden grundlegenden Operationen:

  • Daten lesen und schreiben innerhalb des Zentralspeichers sowie Datenaustausch mit Registern,
  • einfache arithmetische Operationen (mit Gleitkommaprozessoren auch schwierige),
  • einfache logische Operationen,
  • einfache Kontrolle des Programmflusses.

Bestimmte Rechnerarchitekturen haben oft auch komplexere Befehle wie z. B.:

  • einen großen Speicherblock im Hauptspeicher verschieben;
  • höhere Arithmetik wie Sinus-, Kosinus- und Wurzelberechnung (entweder über spezielle Zusatzprozessoren realisiert oder über Softwareroutinen);
  • eine einfache Operation (z. B. Addition) auf einen Vektor von Werten anwenden;
  • massive, direkte Parallelprogrammierbarkeit des Prozessors, etwa bei digitalen Signalprozessoren;
  • Unterbrechungssteuerungen, die besonders für Prozessrechner benötigt werden;
  • Aufrufe von Ein- bzw. Ausgabegeräten;
  • Synchronisation mit anderen Prozessoren für SMP-Systeme.

Geschichte

Früher wurden Betriebssysteme in einer Assemblersprache geschrieben. Heute werden jedoch Hochsprachen bevorzugt, in den meisten Fällen C. Allerdings müssen häufig kleine Assemblerroutinen hardwarenahe Aufgaben in Betriebssystemen übernehmen. Dazu gehört zum Beispiel das Speichern von Registern in Schedulern, oder bei der x86-Architektur der Teil des Boot-Loaders, der innerhalb des 512 Byte großen Master Boot Records untergebracht sein muss. Auch Teile von Gerätetreibern werden in Assemblersprache geschrieben, falls aus den Hochsprachen kein effizienter Hardware-Zugriff möglich ist. Manche Hochsprachencompiler erlauben es, direkt im eigentlichen Quellcode Assemblercode, sogenannte Inline-Assembler-Routinen, einzubetten.

Bis ca. 1990 wurden die meisten Computerspiele in Assemblersprachen programmiert, da nur so auf Heimcomputern und den damaligen Spielkonsolen eine akzeptable Spielgeschwindigkeit und eine den kleinen Speicher dieser Systeme nicht sprengende Programmgröße zu erzielen war. Noch heute gehören Computerspiele zu den Programmen, bei denen am ehesten kleinere assemblersprachliche Programmteile zum Einsatz kommen, um so Prozessorerweiterungen wie SSE zu nutzen.

Bei vielen Anwendungen für Geräte, die von Mikrocontrollern gesteuert sind, war früher oft eine Programmierung in Assembler notwendig, um die knappen Ressourcen dieser Mikrocontroller optimal auszunutzen. Dies gilt heute praktisch nur noch, wenn wegen Massenproduktion möglichst günstige und damit minimale Mikrocontroller verwendet werden sollen und das Programm nicht zu komplex ist. Moderne C-Compiler haben aber auch in diesem Bereich die Assembler abgelöst. Um Code für solche Mikrocontroller zu erzeugen, werden Cross-Assembler bei der Entwicklung eingesetzt. Nicht zuletzt aufgrund größerer Programmspeicher bei gleichen Kosten für die Chips fallen die Vorteile von Hochsprachen gegenüber den teils verschwindend geringen Vorteilen der Assemblersprache immer mehr ins Gewicht.

Vorteile

Von erfahrenen Programmierern geschriebene Assemblerprogramme sind fast immer deutlich schneller als die Produkte der Hochsprachencompiler.[1][2] Beispielsweise sind im Bereich des wissenschaftlichen Rechnens die schnellsten Varianten mathematischer Bibliotheken wie BLAS weiterhin die mit Assembler-Code optimierten.[3][4] Auch lassen sich gewisse sehr systemnahe Operationen bzw. Operationen unter Umgehung des Betriebssystems (z. B. direktes Schreiben in den Bildschirmspeicher) immer noch nicht in allen Hochsprachen ausführen. Der Nutzen von Assembler liegt auch in dem Verstehen, wie ein System arbeitet und funktioniert, um damit in Hochsprachen umständliche Konstrukte zu vermeiden. Auch heute noch wird an vielen Hochschulen Assembler gelehrt. Es geht darum, ein Gefühl für den Rechner und seine Arbeitsweise zu bekommen.

Es gibt Fälle, in denen diskrete Berechnungen einfacher und effizienter direkt in Assembler geschrieben werden. Die meisten Hochsprachencompiler übersetzen zuerst in Assemblercode oder können diesen optional ausgeben, so dass man Details genauer betrachten und gewisse Stellen von Hand optimieren kann.

Nachteile

Da Assemblerprogramme sehr hardwarenah geschrieben werden, weil die unterschiedlichen Spezifikationen der einzelnen Prozessorentypen individuell verschiedene Maschinencode-Befehlssätze erfordern, kann ein Assemblerprogramm nicht auf ein anderes Computersystem übertragen werden ohne die Programmstruktur anzupassen. Das erfordert häufig ein komplettes Neuschreiben des Programmtextes. Im Gegensatz dazu muss bei Hochsprachen nur der Compiler individuell auf ein anderes Betriebssystem angepasst (neu geschrieben) werden, da dieser im Regelfall den Programmcode in eine für das Betriebssystem verwertbare Form umwandelt. Das Betriebssystem seinerseits übernimmt die Vermittlung zur Hardwareebene.

Das Programmieren in Assembler ist oft mit einer großen Anzahl an Einzelbefehlen verbunden, da häufig kleinste Informationseinheiten in einzelnen Speicherzellen manipuliert werden müssen. Das führt häufig zu unübersichtlichen, oft schlecht strukturierten und schlecht wartbaren Assembler-Programmen.

Literatur

  • Gerhard Niemeyer: Einführung in das Programmieren in ASSEMBLER. Systeme IBM, Siemens, Univac, Comparex, IBM-PC/370. 6. bearbeitete und erweiterte Auflage. de Gruyter, Berlin u. a. 1989, ISBN 3-11-012174-3, (De-Gruyter-Lehrbuch).
  • Joachim Rohde: Assembler ge-packt. (Schnelles und effektives Nachschlagen aller relevanten Befehlssätze für AMD und Intel. MMX und 3DNow! SSE und seine Erweiterungen). 2. aktualisierte Auflage. Mitp-Verlag, Heidelberg 2007, ISBN 978-3-8266-1756-0, (Die ge-packte Referenz).
  • Joachim Rohde, Marcus Roming: Assembler. Grundlagen der Programmierung. (Theorie und Praxis unter DOS und Windows. MMX und 3DNOW! Programme optimieren und Reverse Engineering). 2. aktualisierte und erweiterte Auflage. Mitp-Verlag, Bonn 2006, ISBN 3-8266-1469-0, (3-8266-1469-0).
  • Jeff Duntemann: Assembly Language Step-by-Step. Programming with DOS and Linux. 2. Auflage. Wiley, New York NY u. a. 2000, ISBN 0-471-37523-3, (Mit 1 CD-ROM).
  • Paul Carter: PC Assembly Language, kostenloses E-Book, 2001, auf der Website erhältlich.
  • Robert Britton: MIPS Assembly Language Programming. Prentice Hall, Upper Saddle River NJ 2003, ISBN 0-13-142044-5.
  • Randall Hyde: The Art of Assembly Language. No Starch Press, San Francisco CA 2003, ISBN 1-886411-97-2, als PDF oder HTML.
  • Steve McConnell: Code Complete. A practical Handbook of Software Construction. Microsoft Press, Redmond WA 1993, ISBN 1-55615-484-4.

Referenzen

  1. Bit-field-badness (englisch). hardwarebug.org (30. Januar 2010). Abgerufen am 4. März 2010.
  2. GCC makes a mess (englisch). hardwarebug.org (13. Mai 2009). Abgerufen am 4. März 2010.
  3. Writing the Fastest Code, by Hand, for Fun: A Human Computer Keeps Speeding Up Chips (englisch). New York Times, John Markoff (28. November 2005). Abgerufen am 4. März 2010.
  4. BLAS Benchmark-August2008. eigen.tuxfamily.org (1. August 2008). Abgerufen am 4. März 2010.

Weblinks

Wikibooks Wikibooks: Assembler-Programmierung – Lern- und Lehrmaterialien

Wikimedia Foundation.

Игры ⚽ Поможем решить контрольную работу
Synonyme:

Schlagen Sie auch in anderen Wörterbüchern nach:

  • Assemblersprache — asemblerio kalba statusas T sritis automatika atitikmenys: angl. assembly language vok. Assemblersprache, f rus. tiesioginio ryšio kanalas, m pranc. langage d assemblage, m …   Automatikos terminų žodynas

  • Assemblersprache — Assembler …   Universal-Lexikon

  • Assemblersprache — ⇡ Assembler, ⇡ Programmiersprache …   Lexikon der Economics

  • Programmierung in Assemblersprache — programavimas asemblerio kalba statusas T sritis automatika atitikmenys: angl. assembly language coding vok. Programmierung in Assemblersprache, f rus. программирование на языке ассемблера, n pranc. programmation en assembleur, f …   Automatikos terminų žodynas

  • Assembler — Assemblersprache * * * As|sem|bler auch: As|semb|ler 〈[ əsɛ̣mblə(r)] m. 3; unz.; EDV〉 1. maschinenorientierte, d. h. in ihrer Struktur einfache, sich stark an die Bauteile des EDV Geräts anlehnende Programmiersprache 2. Programm, das den in… …   Universal-Lexikon

  • Assembler-Code — Eine Assemblersprache ist eine spezielle Programmiersprache, welche die Maschinensprache einer spezifischen Prozessorarchitektur in einer für den Menschen lesbaren Form repräsentiert. Jede Computerarchitektur hat folglich ihre eigene… …   Deutsch Wikipedia

  • Assemblersprachen — Eine Assemblersprache ist eine spezielle Programmiersprache, welche die Maschinensprache einer spezifischen Prozessorarchitektur in einer für den Menschen lesbaren Form repräsentiert. Jede Computerarchitektur hat folglich ihre eigene… …   Deutsch Wikipedia

  • Assembley — Eine Assemblersprache ist eine spezielle Programmiersprache, welche die Maschinensprache einer spezifischen Prozessorarchitektur in einer für den Menschen lesbaren Form repräsentiert. Jede Computerarchitektur hat folglich ihre eigene… …   Deutsch Wikipedia

  • Assembley Language — Eine Assemblersprache ist eine spezielle Programmiersprache, welche die Maschinensprache einer spezifischen Prozessorarchitektur in einer für den Menschen lesbaren Form repräsentiert. Jede Computerarchitektur hat folglich ihre eigene… …   Deutsch Wikipedia

  • Cross-Assembler — Ein Assembler (nach DIN 44300: Assemblierer) ist ein Hilfsprogramm der Programmierung (Programmierwerkzeug), das ein in einer einfachen, maschinennahen Assemblersprache geschriebenes Programm in Maschinensprache (auch Maschinencode oder Nativer… …   Deutsch Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”