KSP Aufgabe 3
1. Implementieren Sie die neuen Instruktionen
zum Testen von Zahlen (eq, ne, lt, le, gt, ge), die die numerischen
Vergleiche (==, !=, <, <=, >, >=) repraesentieren. Die Auswirkungen
auf den Stack koennen Sie hier sehen. Das
Ergebnis eines Vergleichs, ein Boole'scher Wert, wird durch die
ganze Zahl 0 fuer "false" bzw. 1 fuer "true" dargestellt.
Natuerlich gibt's einen Assembler , der
auch die neuen Instruktionen assemblieren kann.
2. Nehmen Sie sich dann den unbedingten Sprung sowie die beiden
bedingten Spruenge ("branch on false" und "branch on true") vor.
Der Immediate-Wert in diesen Instruktionen gibt das Sprungziel an.
Die bedingten Spruenge pruefen das oberste Stack-Element, um zu
entscheiden, ob gesprungen wird. Wenn nicht gesprungen wird, kommt
die naechste Instruktion zur Ausfuehrung. Die Auswirkungen auf den
Stack koennen Sie wieder hier sehen. Der
Assembler hat eine neue Kommandozeilenoption "--map"; was kann
man eigentlich mit der anfangen?
3. Nun kommt die erste etwas groessere Aufgabe: ein interaktiver
Debugger fuer Ihre VM. Die Instruktionen werden komplizierter,
die auszufuehrenden Programme umfangreicher - man wuenscht sich,
mehr ueber den inneren Zustand der VM zu erfahren, speziell wenn
Fehler auftreten.
a) Im Gegensatz zu den frueheren Aufgaben soll ab jetzt das Programm
nach dem Laden nicht mehr automatisch gelistet werden, sondern einfach
nur ausgefuehrt werden. Wenn man aber die VM mit dem
Kommandozeilenschalter --debug startet, soll sich nach dem
Laden des Programms der interaktive Debugger melden und auf Kommandos
warten, die er dann ausfuehrt.
b) Schreiben Sie eine kurze, aber exakte Spezifikation, welche
Kommandos Ihr Debugger verstehen soll. Als kleiner Hinweis fuer
diejenigen, die sich wenig unter einem solchen Teil vorstellen
koennen: Was wuenscht man sich, um den Programmverlauf verfolgen
oder vielleicht sogar beeinflussen zu koennen? Lassen Sie doch
einfach mal dieses Beispielprogramm 1 laden
und stellen Sie sich vor, es wuerde nicht das gewuenschte Ergebnis
(den groessten gemeinsamen Teiler zweier positiver Zahlen) liefern.
Natuerlich koennen Sie das auch ganz praktisch ausprobieren, indem
Sie irgendeine Instruktion (z.B. das zweite "brf") in eine andere
Instruktion (z.B. "brt") umaendern, oder noch besser: von Ihrem
anderen Grupenmitglied umaendern lassen, ohne dass Sie wissen, was
da passiert ist. Was braucht man dann fuer Hilfsmittel, um den Fehler
zu lokalisieren?
Als Minimalmenge muessen die Kommandos "Anzeigen des Stacks",
"Anzeigen der statischen Daten", "Listen des Programms",
"Ausfuehren des naechsten Befehls", "Weiterlaufen ohne Anhalten"
und "Verlassen der VM" aufgenommen werden. Sehr zweckmaessig ist
auch das "Setzen eines Breakpoints" (wenn das Programm bei der
Ausfuehrung spaeter dort vorbeikommt, haelt es an und der Debugger
uebernimmt die Kontrolle). Anregungen koennen Sie sich natuerlich
wie immer auch von der Referenzimplementierung holen:
njvm
c) Implementieren Sie nun die von Ihnen vorgesehen Kommandos des
Debuggers. Pruefen Sie mit dem
Beispielprogramm 1 und
Beispielprogramm 2 sowie anderen, von
Ihnen geschriebenen Testprogrammen, ob der Debugger das leistet,
was Sie sich von ihm erwarten. Wahrscheinlich fallen Ihnen noch
Verbesserungen ein - dann gehen Sie zurueck zu b).