Einführung

Dieses Tutorial wird Ihnen die Grundlagen der Assemblersprache auf Intels x86-Prozessoren vermitteln. In einer Reihe praktischer Beispiele wird gelerntes Wissen angewandt und vertieft.

Um Zweideutigkeiten vorzubeugen, sei gleich zu Anfang bemerkt, daß der Begriff Assembler sowohl die Sprache als auch den Compiler bezeichnet. Ich versuche in den Fällen, in denen der Compiler gemeint ist, den Begriff Assemblierer zu verwenden. Im allgemeinen werden Sie aber keine Schwierigkeiten haben, die Bedeutung des Wortes aus dem jeweiligen Kontext zu ermitteln.

Das Tutorial ist in zwei große Bereiche aufgeteilt. Der erste Teil beschäftigt sich hauptsächlich mit der Erarbeitung der theoretischen Kenntnisse (Bedienung des Assemblers, Befehle, Datentypen, Codestrukturierung) an Beispielen, im zweiten Teil werden die gewonnenen theoretischen Kenntnisse angewandt und so zusammengefügt, daß lauffähige Programme entstehen.

In diesem Tutorial sind die Beispiele auf den Turbo Assembler (TASM) der Firma Borland/Inprise und dessen IDEAL-Mode abgestimmt. Ich habe mich für diese Kombination entschieden, weil sie meiner Meinung nach besser lesbaren Code erzeugt und bestimmte Konstrukte leichter durchschaubar werden. Nachteil: die Quelltextkompatibilität zum MASM geht verloren. In den meisten Fällen sind aber nur kleine Umstellungen nötig, um diese Kompatibilität wiederherzustellen. Der IDEAL-Mode ändert nichts an den eigentlichen Maschinenbefehlen, sondern beeinflusst in aller Regel die Direktiven an den Assembler selbst. Wenn eine neue Direktive eingeführt wird, dann wird sie sowohl im IDEAL- als auch im MASM-Mode dargestellt. Programmbeispiele werden jedoch den IDEAL-Mode verwenden.
Als zugrundeliegendes Betriebssystem habe ich mich für MS-DOS entschieden. Die mit TASM erstellten Programme sind grundsätzlich auch in einer DOS-Box beispielsweise unter Windows 95/98 lauffähig. Das hat u. U. auch den Vorteil, daß Sie bei einem Programmabsturz nicht den ganzen Rechner neu starten müssen, sondern einfach nur die DOS-Box schließen. Allerdings würde ich trotzdem empfehlen, auf der nackten DOS-Ebene zu arbeiten, da die Abstürze durchaus auch Windows in Mitleidenschaft ziehen können und DOS läßt sich eindeutig schneller booten als Windows. Zudem könnte Windows Probleme bereiten, wenn die hardwarenahe Programmierung in Angriff genommen wird.

Assembler bietet als Sprache der zweiten Generation, genau wie die sogenannten Hochsprachen, die Möglichkeit, den Programmcode zu modularisieren und bestimmte Teilaufgaben in Prozeduren unterzubringen.
Durch eingebaute Mechanismen lassen sich bestimmte, in Assembler geschriebene Bausteine auch in Hochsprachenprogramme einbauen, um zum Beispiel zeitkritische Routinen besser zu optimieren, als es die Hochsprache selbst zuläßt.
Wenn Sie einige Erfahrungen in Assembler gesammelt haben, werden Sie unter Umständen bei bestimmten Problemstellungen in anderen Programmiersprachen zu der Erkenntnis kommen, daß sich dieses Problem in Assembler in wenigen Befehlen lösen ließe, in der entsprechenden Sprache aber erheblich größeren Aufwand verursacht.

Um Assembler zu erlernen, müssen Sie über keine Vorkenntnisse in einer anderen Programmiersprache verfügen. Es ist trotzdem hilfreich, wenn Sie bereits Kenntnisse in einer strukturierten Programmiersprache wie zum Beispiel Pascal oder C vorweisen können, da dann bestimmte Begrifflichkeiten weniger Erklärungs- bzw. Verständnisaufwand bedürfen. Desweiteren können Sie mit geringen Englischkenntnissen die teilweise kryptisch erscheinenden Befehle besser entschlüsseln.

Wie Sie sicherlich wissen, gibt es in der x86-Familie mehrere Prozessorgenerationen, die von 8086/8088 bis zum 80486 und zum Pentium mit all seinen Nachfolgern reichen.
Zwar wird in diesem Tutorial viel vom 8086 gesprochen, aber in den Programmen werden an den Stellen, an denen Befehle des 80386 verwendet werden können, diese auch oft verwendet. Sie werden selbstverständlich mit dem Wissen ausgestattet, das nötig ist, damit Sie die 80386-Befehle durch äquivalente Befehle älterer Prozessoren austauschen können (für den Fall, daß dies notwendig werden sollte).

Die Ausführungen und Beispiele in diesem Tutorial gebe ich nach bestem Wissen und Gewissen und spiegeln das wider, was ich im Laufe meiner Arbeit mit TASM erfahren habe. Sollten Sie auf Fehler aufmerksam werden oder Fragen haben, so schreiben Sie bitte eine EMail an amasm at gmx .de.

Ihre Programmierumgebung

Um Assemblerprogramme zu schreiben, benötigen Sie natürlich einen Editor. Im Grunde tut es hier schon der DOS-eigene Editor edit, günstiger ist aber ein vernünftiger Programmiereditor, wie er zum Beispiel den Programmierumgebungen Turbo Pascal und Turbo C++ von Borland/Inprise beiliegt. Wichtig ist das Merkmal der sogenannten Autoindentation (automatische Einrückung) und, je nach persönlichem Geschmack, verstellbare Tabulatorweiten.

Für die folgenden Bemerkungen gehen wir davon aus, daß unser korrekter Quelltext in der Datei quelle.asm auf Diskette oder Platte vorliegt. Der Compiler für Ihre Programme liegt in der Datei tasm.exe. Dieser erwartet standardmäßig eine Datei mit der Endung .asm. Ist dies der Fall, so muß die Endung nicht angegeben werden.
tasm quelle
Der Compiler erzeugt aus der ihm übergebenen Quelldatei eine sogenannte Objektdatei mit der Endung .obj, in unserem Falle also quelle.obj.
Diese Datei ist noch nicht ausführbar, weil zum Beispiel externer Code aus anderen Bibliotheken noch nicht enthalten ist und bestimmte Adressen noch nicht die richtigen Werte enthalten.
Um eine ausführbare Datei zu erhalten, muß noch der sogenannte Linker aufgerufen werden. Dieser erwartet standardmäßig eine .obj-Datei.
tlink quelle
Als Ergebnis erhalten wir die Datei quelle.exe, die auch sofort gestartet werden kann.

Dieser glatte Ablauf ist nur bei syntaktisch korrekten Quelldateien gewährleistet. Wenn der Compiler auf ein Problem trifft, dann mahnt er die entsprechende Fehlerzeile an und bricht die Übersetzung ab.
Viel schlimmer als die Syntaxfehler sind aber die logischen Fehler, weil diese in Assemblerprogrammen zumeist einen kompletten Systemabsturz verursachen. Als zusätzliches Hilfsmittel ist also auch ein Debugger angeraten.

Das erste Programm

Für den kleinen Einstieg in Assembler folgt hier das erste Programm.
Standardmäßig wird keine Unterscheidung nach Groß- und Kleinschreibung durchgeführt. Schreibt man allerdings Module für case-sensitive Sprachen wie C, dann kann eine Unterscheidung die Programmierung vereinfachen (die Programmierung des Assemblermoduls wird vielleicht erst etwas nervenaufreibender, weil plötzlich Variablennamen aufgrund unterschiedlicher Schreibweise als unbekannt ausgewiesen werden). Eingeschaltet wird sie durch einen Parameter beim Aufruf von TASM.
In jeder Zeile kann immer nur genau ein Befehl oder eine Anweisung stehen, höchtens ergänzt um einen Zeilenkommentar.
Kommentare werden in Assembler mit einem Semikolon (;) eingeleitet und gelten bis zum Zeilenende. Für mehrzeilige Kommentare bietet der MASM-Modus noch eine zweite Möglichkeit. Hier wird der Kommentar durch das Wort COMMENT und ein dahinterstehendes Zeichen eingeleitet. Der danachfolgende Text wird solange als Kommentar betrachtet, bis das Zeichen hinter COMMENT auftaucht. Beispiel:

COMMENT ~
Das
ist
ein
mehrzeiliger Kommentar ~
Vieles von dem, was im folgenden Quelltext großgeschrieben wird, sind Anweisungen an den Assemblierer selbst.
TITLE Das erste Programm			;Diese Zeile ist optional
IDEAL						;IDEAL-Modus einschalten
MODEL SMALL					;Speichermodell
STACK 100					;100 Bytes für den Stack
DATASEG						;Beginn des Datensegments
	derText db 'Das erste Programm$'	;1.
CODESEG						;Beginn des Codesegmentes
start:						;2.
	STARTUPCODE
	  mov ah, 009h				;3.
	  mov dx, OFFSET derText		;4.
	  int 21h				;5.
	EXITCODE
END start					;6.

kurze Erläuterungen:
  1. Hier wird die Zeichenkette definiert, die ausgegeben werden soll
  2. Dies ist die Anfangsmarke für Code (s. auch weiter unten)
  3. In das Prozessorregister AH den Wert 9 schreiben
  4. Das Prozessorregister DX mit der Adresse des Ausgabestrings beschreiben
  5. Aufruf eines Interrupts; die Zusammenhänge werden später erläutert
  6. Die Endmarkierung für die Assemblierung; alles, was jetzt noch kommt, wird vom Assemblierer ignoriert
Was Ihnen jetzt vielleicht noch komplett unverständlich erscheint, wird selbstverständlich im Laufe dieses Tutorials aufgeklärt. Dabei wird immer wieder auf dieses Programm zurückgegriffen.

Nach speichern dieses Textes in der Datei first.asm assemblieren Sie das Programm mit
tasm first
in die Objektdatei first.obj, die Sie mit
tlink first
zur fertigen Datei first.exe linken können.
Nach Eingabe von first auf der Kommandozeile sollte der Text 'Das erste Programm' ausgegeben werden.