Wie alle Testhilfsprogramme erfordert die Anwendung eine gewisse Übung. Eine andere Möglichkeit, Assemblerprogramme ohne solche Testhilfsprogramme zu „debuggen”, ist die Verwendung spezieller Testmakros oder -unterprogramme. Auf der Seite Routinensammlung für COM-Programme sind mit den Makros RDUMP und MDUMP zwei Anzeigeroutinen enthalten, die speziell zum Testen der Programme gedacht sind. Auf der Seite Statt DEBUG: Demonstration von RDUMP und MDUMP wird die Anwendung dieser beiden Makros an einem Beispiel gezeigt.
Aufruf:
DEBUG
DEBUG /?
DEBUG [Datei][.Erw][Argliste]
Aufruf ohne Parameter: DEBUG antwortet mit dem Bereitschaftszeichen - und erwartet die Eingabe von Befehlen. Man kann mit dem aktuellen Speicher, mit Disk-Sektoren oder Disk-Dateien arbeiten.
DEBUG /? zeigt eine Hilfsanzeige.
Vermeiden Sie einen Neustart des Programmes nach der Meldung
Program terminated normally.
Statt dessen müssen Sie das Programm mit den Befehlen Name oder Load neu laden, um es erneut starten zu können.
Aufruf mit Parametern: Hierbei wird die Datei in den Speicher geladen. Es wird ein Programmkopf ab Adresse 0 eingerichtet. Wird eine .COM- oder .EXE- Datei angegeben, so darf der Programmkopf unterhalb der Adresse 5CH nicht verändert werden (andernfalls wird DEBUG beendet). Die Argliste versorgt das bei Datei angegebene Programm.
Kommandostruktur: Jedes DEBUG-Kommandos besteht aus einem Buchstaben, der von einem oder mehreren Parametern gefolgt sein kann. Bei formal falschen Kommandos erscheint als Fehlerindikator das Zeichen ^ gefolgt von dem Wort Error.
Fehlermeldungen: Fehlermeldungen bei Debug
Befehl | Syntax | Funktion |
---|---|---|
Assemble | a [Adresse] | Befehle assemblieren |
Compare | c Bereich Adresse | Befehle vergleichen |
Dump | d [Bereich] | Speicher hexa zeigen |
Enter | e Adresse [Liste] | Daten eingeben |
Fill | f Adresse Liste | Bereich füllen |
Go | g[=Adresse[Adresse...]] | Programm starten, ggf. mit Breakpoints |
Hex | h Wert Wert] | Hexadezimalzahlen berechnen |
Input | i Portadresse] | von Portadresse lesen |
Load | l [Adresse [Laufwerk Sektor Sektor]] | Datei oder Sektor laden |
Move | m [Bereich Adresse] | Bereich kopieren |
Name | n [Laufwerk:][Pfad]Datei[.Erw][…] | Dateinamen und/oder Parameter festlegen |
Output | o Portadresse Wert] | auf Portadresse schreiben |
Procstep | p[=Adresse[Anzahl]] | Programmschrittausführen |
Quit | q | DEBUG beenden |
Register | r [Registername] | Registerbelegung zeigen/ ändern |
Search | s Bereich Liste] | Bytes suchen |
Trace | t[=Adresse][Wert] | Verfolge Programmablauf |
Unassemble | u [Bereich] | Befehle disassemblieren |
Write | w [Adresse[Laufwerk:Satz Satz]] | Datei oder Sektor schreiben |
? | Hilfsanzeige | Zeigt die möglichen DEBUG-Kommandos an |
Bereich: Ist ein Parameter, der aus zwei Adressen besteht. Sein Aufbau ist entweder
Adresse-von Adresse-bis
Adresse-von L Wert
Wert ist die Zeichenanzahl auf die der Befehl wirken soll.
Beispiele: CS:100 110
CS:100 L 10
Laufwerk: Bei der Laufwerksangabe sind die Werte 0 bis 3 zugelassen. 0=A, 1=B, 2=C, 3=D
A Assembliert Anweisungen sofort nach der letzten Eingabe in den Speicher an der aktuellen Adresse. Die Eingabe von ENTER beendet die Eingabe.
Aadresse Assembliert Anweisungen mit der Adresse beginnend in den Speicher.
A100 Die Eingabe von ENTER beendet die Eingabe.
Cbereich adresse vergleicht zwei Speicherblöcke.
C100 L20 200 vergleicht 32 Bytes ab Adresse 100 mit 32 Bytes ab Adresse 200
D Zeigt den Inhalt des Speichers beginnend ab der zuletzt gezeigten Position.
Dadresse Zeigt den Inhalt des Speichers beginnend ab der angegebenen Position.
D650
Dbereich Zeigt den Inhalt des Speichers beginnend ab der angegebenen
D650 L50 Position in der angegebenen Länge
D650 6A0 bzw. von Adresse bis Adresse.
Eadresse Beginn der Eingabe von HEX-Werten ab Adresse.
EDS:50 Eingabebeginn bei Datensegment:50h
Die Eingabe erfolgt bis ENTER gedrückt wird. Space überspringt ein Byte.
Eadresse liste Gibt die Byte liste in den Speicher beginnend an der angegebenen Adresse.
E100 20 20 Gibt zwei Leerzeichen ab Adresse 100h im aktuellen Segment ein.
Fadresse Liste Füllt Speicherbereich ab der angegebenen Adresse mit Bytewerten aus der Liste.
FDS:00 L0F "TEH" Ab Adresse 00 im Datensegment wird 5-mal, d.h. 0fh Bytes lang, die Bytefolge TEH eingefüllt.
G Beginnt die Ausführung bei der aktuellen Adresse CS:IP
G=adresse Beginnt die Ausführung bei der angegebenen Adresse
G=100 Beginnt auf Adresse 100H im aktuellen CS
G=adresse adressleiste Beginnt Ausführung ab Adresse mit in der Adressleiste angegeben Breakpoints.
G=100 10A 213 Beginnt auf Adresse 100H im aktuellen CS mit Breaks wenn Adresse 10AH oder 213H erreicht ist.
H wert wert Hexadezimalzahlen berechnen
H 8 0F Addiert und subtrahiert 8H und FH, zeigt die Ergebnisse an.
I portadresse von Portadresse lesen
I 2E6 liest von Port 2E6H ein, zeigt gelesenen Wert an.
L Lädt Datei (deren Spezifikation bei CS:80H steht) nach CS:100H
L adresse Lädt Datei (deren Spezifikation bei CS:80H steht) nach Adresse.
COM- und EXE-Dateien werden jedoch immer nach CS:100H geladen.
L 506 Lädt Datei (deren Spezifikation bei CS:80H steht) nach CS:506H
L Adresse Laufwerk Sektor1 Sektor2 Lädt Sektoren aus dem Laufwerk in die Adresse beginnend ab Sektor1 in der Anzahl Sektor2. Die Sektoranzahl ist maximal 80H. Nach dem L-Befehl sind die Register BX:CX auf die Anzahl gelesener Bytes
gesetzt.
L DS:10 2 0 3 Lädt die ersten 3 Sektoren von Laufwerk C: nach DS:10H
M bereich adresse Kopiert den angegebenen Bereich an die neue Adresse. Die Übertragung wird ohne Speicherverlust durchgeführt.
M 100 L10 500 Kopiert 16 Bytes ab Adresse 100H nach 500H.
N dateiname Der Dateiname wird auf Adresse CS:80H eingetragen. Auch die Übergabe von Parametern ist hier möglich.
N c:irgend.was c:irgend.was wird für den Debugger vorbereitet.
O portadresse wert Schreibt den Wert zur Portadresse.
O 2E6 FF Schickt FFH zum Port 2E6H
P Hält die Ausführung einer Instruktion bei der nächsten Instruktion an. Die Ausführung beginnt bei CS:IP Die P- Anweisung hat dieselbe Syntax wie T(race)
P=Adresse Ausführung von Adresse bis zum Ende der betreffenden Anweisung.
P=1044 Ausführung beginnt bei Adresse CS:1044
P=Adresse Anzahl Anweisung von Adresse bis soviel Bytes abgearbeitet sind, wie bei Anzahl angegeben.
P=1044 10 Ab CS:1044 werden 16 Bytes abgearbeitet.
Q Debug wird sofort beendet, ohne dass irgendetwas gesichert wird.
R zeigt alle Register an.
R register zeigt den Inhalt des Registers an und ermöglicht seine Änderung.
Registernamen: AX BX CX DX SP BP SI DI DS ES SS CS IP PC F
Wird F als Registername angegeben, so werden alle CPU-Flags mit einem 2 Zeichen langen Namen, der den Zustand der betreffenden Flag wiedergibt, gezeigt. Um eine Flag zu ändern, muss einer der Setz- oder Löschcodes bei der Bereitschaftsanzeige
eingegeben werden:
Flag | setzen | löschen |
---|---|---|
Überlauf | OV ja | NV nein |
Richtung | DN dekrement | UP increment |
Interrupt | EI enable | DI disable |
Vorzeichen | NG negativ | PL positiv |
Null | ZR ja | NZ nein |
Zus. Carry | AC ja | NA nein |
Parität | PE even | PO odd |
Carry | CY ja | CY nein |
R AX zeigt Inhalt von AX und wartet auf neue Werte. Die Eingabe von ENTER lässt den Inhalt unverändert.
S bereich liste Durchsucht den Speicherbereich nach Listinhalten.
S 100 L100 "TEH"Sucht nach dem Muster TEH in den 100H Bytes ab Adresse CS:100H
S CS:100 200 41 Sucht nach dem Byte 41H in den 200H Bytes ab Adresse CS:100H
T Führt eine Anweisung im Einzelschritt durch. Die Ausführung beginnt bei CS:IP.
T=adresse Führt eine Anweisung im Einzelschritt ab der angegebenen Adresse aus.
T=1044 Ausführung beginnt bei Adresse CS:1044
T=adresse anzahl Anweisung ausführen ab Adresse bis soviel Bytes abgearbeitet sind, wie bei Anzahl angegeben.
0bei Anzahl bedeutet alles.
T=100 10 Ab CS:100 werden 16 Bytes abgearbeitet.
Unassemble
u [Bereich] Befehle disassemblieren
Write
w [adresse[laufwerk:satz satz]] Datei oder Sektor schreiben.
debug -a 151A:0100 db 1,2,3,"Dies ist ein Beispiel" 151A:0118 db 'ein Anführungszeichen:"'," und ein Apostroph:'" 151A:0143 dw 1000,2000,"ABC" 151A:014A -d100 149 151A:0100 01 02 03 44 69 65 73 20-69 73 74 20 65 69 6E 20 ...Dies ist ein 151A:0110 42 65 69 73 70 69 65 6C-65 69 6E 20 41 6E 66 81 Beispielein Anf. 151A:0120 68 72 75 6E 67 73 7A 65-69 63 68 65 6E 3A 22 20 hrungszeichen:" 151A:0130 75 6E 64 20 65 69 6E 20-41 70 6F 73 74 72 6F 70 und ein Apostrop 151A:0140 68 3A 27 00 10 00 20 41-42 43 h:'... ABC -
MASM: | DEBUG: | bei MASM: |
---|---|---|
MOV AL,HALLO | MOV AL,41 | HALLO EQU 41H |
MOV AL,HALLO | MOV AL,[41] | HALLO LABEL NEAR |
Das mit dem Debugger assemblierte Programm steht als Datei abc.com auf der Platte. Allerdings ist die Datei mit 256 Bytes Länge etwas zu lang. Vor dem Schreiben des Programmes muss man unbedingt das Doppelregisterpaar BX und CX auf die Anzahl der gewünschten Programmlänge setzten. Bei praktikablen Programmlängen ist BX immer 0000. Besonders wichtig ist, dass das Programm einen Namen bekommen hat, und dass man beim W-Befehl nicht mit den Parametern herumspielt. Tut man Letzteres, kann man sich den Inhalt der Platte zerstören, da der W-Befehl in der Lage ist, jeden beliebigen Sektor auf der Platte ohne den Schutz durch das Betriebssystem zu verändern.
Man kann anschließend das kleine Programm von der DOS-Ebene aus ausführen lassen:
0:10:46:29 C:\>abc
ABCDEFGHIJKLMNOP
0:11:10:41 C:\>