Debugger
Der Debugger dient dazu, die Programmausführung
an beliebiger Stelle anzuhalten,
einzelne Befehle im Schrittbetrieb abzuarbeiten
und so das Geschehen im Emulator zu überwachen.
Dabei ist es auch möglich,
die Speicher- und Registerinhalte anzusehen.
Die Registerihalte können auch geändert werden.
Zum Ändern des Speicherinhalts gibt es den
Speichereditor.
1. Debugger starten
Sie befinden sich im Hauptfenster und klicken im Menü
Extra, Untermenü Werkzeuge, den Punkt
Debugger... an.
Die weitere Beschreibung bezieht sich auf das Debugger-Fenster.
2. Programmausführung anhalten
Damit Sie die Speicher- und Registerinhalte ansehen können,
muss die Programmausführung angehalten werden.
Dafür gibt es zwei Möglichkeiten:
-
Sie legen einen oder mehrere Haltepunkte an.
Wenn während der Befehlsabarbeitung ein solcher Haltepunkt
zutrifft, der zudem auch aktiviert sein muss, wird angehalten.
-
Sie klicken im Menü Debuggen auf den Punkt
Programmausführung anhalten.
Jedesmal wenn die Programmausführung anhält,
wird der Inhalt des Debugger-Fensters aktualisiert, d.h.,
Sie sehen im linken Bereich des Fensters die Registerinhalte,
in der Mitte die ersten Bytes der Speicherbereiche,
auf denen die Doppelregister zeigen und
unten die nächsten auszuführenden Befehle.
Es gibt vier verschiedene Arten von Haltepunkten,
die bei unterschiedlichen Bedingungen zum Anhalten
der Programmausführung führen.
3.1. Haltepunkt auf Adresse
Das ist die klassische Form eines Haltepunktes.
Es wird angehalten, wenn die Programmausführung
auf die angegebene Adresse stößt.
3.2. Haltepunkt auf Speicher
Ein solcher Haltepunkt reagiert auf Zugriffe auf eine Speicherzelle
bzw. auf einen Speicherbereich.
Sie können angeben, ob nur bei Lese-, nur bei Schreib-
oder bei Lese- und Schreibzugriffe angehalten werden soll.
Zusätzlich können ein Wert und eine Maske angeben werden.
Dann wird nur angehalten, wenn der angegebene Wert mit dem gelesenen
bzw. zu schreibenden übereinstimmt.
Dabei werden nur die Bits verglichen, die in der Maske gesetzt sind.
3.3. Haltepunkt auf E/A-Tor
So ein Haltepunkt ist ähnlich wie einer auf den Speicher.
Anstelle einer Speicherzelle oder eines Speicherbereichs
wird eine Ein-/Ausgabeadresse oder eine Gruppe von zusammenliegenden
IO-Ports überwacht.
Die E/A-Haltepunktadresse können Sie als 8 Bit-
(2 hexadezimale Ziffern) oder 16 Bit-Wert
(4 hexadezimale Ziffern) angeben.
Der emulierte Mikroprozessor unterstützt offiziell nur
E/A-Adressen mit 8 Bit.
Allerdings sind aufrund seines undokumentierten Verhaltens
auch 16-Bit-E/A-Adressen möglich.
Ob Sie nun die E/A-Haltepunktadresse mit 8 oder 16 Bit angeben
(müssen), hängt davon ab, ob das emulierte System
mit 8 oder 16-Bit-IO-Ports arbeitet.
Auch bei Haltepunkte auf E/A-Tore können ein Wert und eine Maske
als zusätzliches Kriterium angegeben werden.
Allerdings zeigt das nur bei Ausgabebefehlen eine Wirkung.
Bei Eingabebefehlen wird ein Wert als zusätzliches Kriterium
deshalb nicht unterstützt, weil immer vor Ausführung
des betreffenden Befehls angehalten wird und der Emulator
nicht in jedem Fall wissen kann, welcher Wert dann bei der
eigentlichen Befehlsausführung gelesen werden würde.
3.4. Haltepunkt auf Interrupt-Quelle
Bei dieser Form eines Haltepunktes geben Sie eine im emulierten
System vorhandene Interrupt-Quelle (z.B. PIO oder CTC) an.
Es wird dann angehalten, sobald die Interrupt-Quelle
einen Interrupt auslöst und dieser vom Mikroprozessor
auch angenommen wird, d.h.,
es wird vor dem ersten Befehl der Interrupt-Service-Routine angehalten.
3.5. Verwaltung der Haltepunkte
Über das Menü Debuggen können Sie beliebig
viele Haltepunkte anlegen.
Mit dem Kontextmenü über der jeweiligen Haltepunktliste
ist das auch möglich.
Um einen Haltepunkt wieder zu entfernen,
müssen Sie diesen im rechten Bereich des Debugger-Fensters
durch Anklicken markieren.
Anschließend klicken Sie im Menü Debuggen
auf den Eintrag Haltepunkt entfernen.
Optional können Sie auch alle Haltepunkte auf einmal entfernen
(Menüeintrag Alle Haltepunkte entfernen).
Haltepunkte, die Sie temporär nicht benötigen,
müssen Sie nicht unbedingt entfernen.
Sie können diese Haltepunkte auch einfach deaktivieren
und später bei Bedarf wieder aktivieren.
Der Debugger ist nur solange aktiv, wie das Debugger-Fenster
sichtbar ist.
Wenn Sie Haltepunkte angelegt haben und Sie schließen
das Fenster, werden die Haltepunkte zwar nicht gelöscht,
jedoch wird dann dort auch nicht mehr angehalten.
3.6. Haltepunkte importieren
Der Debugger bietet die Möglichkeit,
Haltepunkte aus einer Datei oder aus der Zwischenablage zu
importieren.
Diese Haltepunkte können dabei auch einen Namen haben.
So ist z.B. der Import der Markentabelle eines Assemblers möglich,
um für jede Marke einen Haltepunkt anzulegen.
Die Markentabelle des JKCEMU-Assemblers können Sie sogar
automatisch in den Debugger importieren lassen.
Schalten Sie dazu die entsprechende
Assembler-Option ein.
4. Schrittbetrieb
Mit Schrittbetrieb ist gemeint, dass nach dem Anhalten der
Programmausführung einzelne Befehle oder Befehlsgruppen
abgearbeitet werden und danach automatisch wieder
die Programmausführung angehalten wird.
Die Funktionalitäten des Schrittbetriebs finden Sie im Menü
Debuggen unter den Punkten Über Aufruf springen,
In Aufruf springen und Aus Aufruf herausspringen.
Den Schrittbetrieb beenden Sie ganz einfach durch Fortsetzung
der Programmausführung.
Klicken Sie dazu im Menü Debuggen den Punkt
Bis Haltepunkt ausführen an.
Wenn Sie sich im Schrittbetrieb befinden und Sie schließen
des Debugger-Fenster, geht der Emulator in den Pause-Zustand über.
Sie können dann im Hauptfenster im Menü
Extra auf Fortsetzen klicken,
oder Sie öffnen wieder den Debugger.
4.1. Über Aufruf springen
Es wird ein einzelner Maschinenbefehl abgearbeitet.
Handelt es sich jedoch um den Aufruf eines Unterprogramms,
so wird das ganze Unterprogramm ausgeführt und
erst danach wieder angehalten.
Das Ende eines Unterprogramms wird dabei anhand des Stack Pointers erkannt.
Sobald dieser wieder den gleichen Wert wie vor dem Unterprogrammaufruf
hat, wird angehalten.
Blockbefehle und leere DJNZ-Schleifen werden ebenfalls übersprungen,
d.h. sie werden bis zum Ende abgearbeitet.
Bei der Funktion Über Aufruf springen wird nämlich
die Programmausführung niemals angehalten,
wenn der Befehlszeiger (Program Counter) nach Abarbeitung
eines Maschinenbefehls immer noch auf den gleichen Befehl zeigt.
4.2. In Aufruf springen
Es wird immer nur ein einzelner Maschinenbefehl abgearbeitet.
Handelt es sich um den Aufruf eines Unterprogramms,
so wird nur der CALL-Befehl abgearbeitet und somit vor dem
ersten Maschinenbefehl des Unterprogramms wieder angehalten.
Bei Blockbefehlen wird nur ein Zyklus des Blockbefehls abgearbeitet
und danach wieder angehalten.
4.3. Aus Aufruf herausspringen
Es werden die Maschinenbefehle bis zum nächsten Return-Befehl
ausgeführt.
Werden dabei Unterprogramme aufgerufen,
so werden diese vollständig ausgeführt.
4.4. Registerinhalte und Flags ändern
Im Schrittbetrieb, d.h. wenn die Programmausführung angehalten
wurde, können die Inhalte der Register geändert werden.
Geben Sie dazu den gewünschten neuen Wert in das jeweilige Feld
hexadezimal ein.
Die Werte der einzelnen Flags können Sie festlegen,
indem Sie auf die entsprechenden Boxen im oberen Bereich des Fensters
klicken und so ein Häkchen setzen oder entfernen.
5. Befehle aufzeichnen
Eine weitere Möglichkeit der Verfolgung des Geschehens
im Emulator ist die Befehlsaufzeichnung.
Dabei werden vor der Abarbeitung eines jeden Maschinenbefehls
die Adresse, die Inhalte der wichtigsten Register und der
anstehende Maschinenbefehl in Form einer Zeile in
eine Textdatei geschrieben.
Diese können Sie sich dann mit einem Editor ansehen,
z.B. mit dem in JKCEMU eingebauten
Texteditor.
Die Befehlsaufzeichnung schalten Sie über den Schalter
Befehle aufzeichnen im Menü Debuggen
ein und wieder aus.
Immer wenn Sie die Befehlsaufzeichnung einschalten,
werden Sie nach dem Namen der Datei gefragt,
in der die Befehle aufgezeichnet werden sollen.
Achtung! Die Befehlsaufzeichnung schreibt pro Maschinenbefehl
eine ganze Zeile in eine Textdatei.
Diese Textdatei wächst deshalb sehr schnell und sehr stark an.
Sie sollten deshalb die Befehlsaufzeichnung nicht zu lange
eingeschaltet lassen und sicherstellen, dass auf dem Speichermedium
ausreichend Platz ist.
Außerdem wird die Programmausführung in Abhängigkeit
von der Schreibgeschwindigkeit des Speichermediums deutlich gebremst.