Allgemeines
Sowohl für Windows als auch für Linux gibt es den Assembler nasm.
Dieser ist recht nahe an der Intel-Syntax.
Ausnahme hier: Zugriffe auf Speicheraddresssen werden immer
in eckige Klammern geschrieben. Die Original Intel Syntax
unterscheidet Speicherzugriffe und Konstantennamen anhand ihrer
Deklaration anderswo im Code. Daher kann MOV AX,adrA nur dann
einen Lesezugriff auslösen, wenn adrA als Speicherzelle definiert
wurde. Wenn adrA als Konstante definiert wurde, bekommt AX einfach
deren Wert zugewiesen.
Dies ist etwas verwirrend (Aktion abhängig vom Kontext),
daher muß bei nasm (und anderen neueren Assemblern) der Speicherzugriff
explizit mit den Klammern [] angeschrieben werden, also MOV AX,[adrA]
Ebenso ist die Syntax für indirekte Speicherzugriffe mit Index und/oder
Displacement leicht verschieden. Die Intelsyntax 4[BX][SI] würde in nasm
[BX+SI+4] entsprechen.
Assembler unter DOS/Windows
Ablauf am Beispiel des Assemblerprogramms BSP.ASM
Benötigte Dateien:
- nasm.exe (Assembler)
- val.exe (Linker)
- asm.bat (Batch-Datei zum einfachen Assemblieren und Linken)
- bsp.asm (Beispiel-Programm mit 16Bit-Hexausgabe zur Wiederverwendung)
- DEBUG.COM Ein simpler, aber gut zu
bedienender Debugger (aus der Demo-Version von PTS-DOS).
- insight.com Noch schönerer (und bunter) Debugger
(für das Menu F10 drücken!)
Weitere Möglichkeiten zum Debuggen:
- debug.exe (ist in jedem DOS/Windows dabei, wenn nicht: debug.exe)
- Ein (nach der Einarbeitung) wesentlich komfortabler Debugger ist z.B.
mmd (mmd100.zip)
Benutzung der Programme:
- Assemblerprogramm (mit Endung .asm, BSP.ASM) schreiben
- Die Batchdatei ASM mit der Assemblerdatei ohne Endung starten (asm bsp)
- Evtl. Fehler korrigieren, neu assemblieren
- Es wird bei korrektem Assemblerprogramm eine BSP.EXE-Datei erzeugt
- BSP.EXE-Programm starten und die Ausgabe anschauen (und sich freuen), oder
- Debuggen mit debug bsp.exe, mit jedem F7 geht das
Programm einen Schritt weiter und zeigt die gerade aktuellen Registerwerte an.
Mehr Hilfe gibt es mit F1.
Das Beispiel-Programm holt sich analog der ersten Assembler-Übungsaufgabe
zwei 16-Bit-Werte aus den Speicherzellen mit Namen addrA und addrB und addiert diese.
Um das Programm auch ohne Debugger zu betreiben, habe ich noch eine Routine eingebaut,
die eine 16-Bit-Hexzahl (in AX) so auf die Konsole ausgibt.
Unter DOS, Windows 3.1, Windows 95 und Windows 98 kann man
wegen der Beschränktheit dieser "Betriebssysteme" mit einem falschen
Programm bzw. einer falschen Eingabe in debug den Rechner problemlos abstürzen lassen.
Daher: Beim Assembler-Basteln nie andere Anwendungen nebenher benutzen!
Windows 2000/XP sind dagegen geschützt.
Assembler unter Linux
Unter Linux kann man z.B. den GNU-Assembler benutzen (gas bzw. as),
allerdings hat dieser eine etwas andere Syntax als die in der Vorlesung
besprochene Intel-Syntax. Alle Register haben ein % vorangestellt,
die Länge der Operation wird mit einem angefügten B,W oder L (8/16/32Bit)
bezeichnet.
Zusätzlich ist bei Zwei-Operanden-Befehlen immer die Reihenfolge
vertauscht (Intel: ADD AX,BX, GNU: ADDW %BX,%AX).
Wegen dieser Unterschiede empfiehlt es sich, auf nasm
auszuweichen (bei jeder Linux-Installation dabei,
evtl. nachinstallieren!).
Zum Ausgeben evtl. berechneter Werte kann man ein C-Programm benutzen,
das das eigene Assemblerprogramm aufruft. Zum Starten müssen dann
C- und Assemblerprogramm zusammengebunden (gelinkt) werden.
Beispiel: Addition ähnlich Übung 1, Aufgabe 1.1 (ohne Überlauftest).
Assembler (test.asm),
C-Programm (test_c.c)
Assemblieren mit nasm -f elf test.asm , ergibt (bei fehlerfreiem
Programm) eine Datei test.o
Compilieren und Linken mit gcc -g test_c.c test.o, ergibt
ein startfertiges Programm a.out
Starten von a.out und das Ergebnis anschauen.
Das Debuggen geht nur mit gdb (bzw. xxgdb oder ddd), diese haben
allerdings normalerweise die GNU-Assembler-Schreibweise (sog.
ATT-Syntax, Parameter haben das Format Quelle, Ziel etc).
Dies lässt sich aber mit "set disassembly-flavor intel" oder
"set disassembly-language intel" umstellen.
Alternativ kann man auch ald (von
http://dunx1.irt.drexel.edu/~psa22/ald.html
) benutzen. Dieser ist wesentlich
einfacher und übersichtlicher als gdb und benutzt auch die Intel-Syntax.
Linux arbeitet im 32-Bit-Modus, das heisst, daß alle Adressen
32Bit sein müssen, d.h. für Adresszugriffe muß man EAX, EBX, ECX,
EDX, EBP, ESP benutzen!
Unter Linux kann auch mit dem falschesten Programm nichts passieren,
solange man nicht als 'root' arbeitet.