88
Bachelorarbeit Entwurf eines Assembler-Compilers/-Debuggers und Memory-Viewers Bachelorand: Dennis Reuling Fakultät: Naturwissenschaftlich-Technische Fakultät Department: Elektrotechnik und Informatik Institut: Fachgruppe für Mikrosystementwurf Betreuer: Prof. Rainer Brück Zweitkorrektur: Dipl.-Ing. André Schäfer Abgabedatum: 6. Mai 2011

Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

  • Upload
    dangnhu

  • View
    215

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Bachelorarbeit

Entwurf einesAssembler-Compilers/-Debuggers

undMemory-Viewers

Bachelorand: Dennis ReulingFakultät: Naturwissenschaftlich-Technische FakultätDepartment: Elektrotechnik und InformatikInstitut: Fachgruppe für MikrosystementwurfBetreuer: Prof. Rainer BrückZweitkorrektur: Dipl.-Ing. André SchäferAbgabedatum: 6. Mai 2011

Page 2: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Zusammenfassung

Diese Bachelorarbeit beschreibt die Vorgehensweise bei der Entwicklung des ProgrammsAssembler-Compiler/-Debugger und Memory-Viewer sowie dessen einzelner Module. Umdies zu erreichen wird inKapitel 1 eine grobe Entwurfsübersicht gegeben, um eine Grund-lage für die restlichen Kapitel zu schaffen. Dort wird genauer auf Ausgangslage und diedamit entstandenen Anforderungen an das Programm eingegangen. In Kapitel 2 wirddas Augenmerk auf die grundlegenden Definitionen des Programms gelegt. Im Detailwerden hier die einzelen Komponenten und deren Zusammenspiel erläutert. Das nächsteKapitel beschäftigt sich mit dem Assembler-Compiler und -Debugger. Dazu werden erstCompiler-Technische Grundlagen erläutert, darauf aufbauend wird die Implementationund das Zusammenspiel dessen Module anhand eines Beispiels beschrieben. Kapitel 4widmet sich der Benutzeroberfläche, welche auch letzendlich für den Benutzer sichtbarund benutzbar ist. Hier wird auf die Funktionen des Programms und dessen Imple-mentation eingegangen. Weiter wird hier das Design und entsprechende Entscheidun-gen erläutert. Das letzte Kapitel besteht aus einer Zusammenfassung der Bachelorarbeitund einee Aussicht auf mögliche Erweiterungen und Verbesserungen des ProgrammsAssembler-Compiler/-Debugger und Memory-Viewer.

ii

Page 3: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Vorwort

Im Rahmen des Bachelor Studiums Informatik bietet die Fachgruppe für Mikrosys-tementwurf an der Universität Siegen ein Hardwarepraktikum an, um den Studentenpraktische Anwendungen und Beispiele im Bereich der technischen Informatik näherzu bringen. Um dies zu erreichen, entwickeln die Studenten im Zuge des Praktikumsmithilfe von FPGA Advantage der Firma Mentor Graphics [1] einen Prozessor. Daraufaufbauend wird dieser Entwurf auf einem Xilinx Field Programmable Array (FPGA)Experimentier-Board von der Firma Digilent [2] getestet und verfeinert. Genauere In-formationen zu dem Prozessor selbst und dessen Entwurf findet man im Begleitbuchzum Praktikum Entwurf digitaler Systeme [3] oder auf der Homepage der Fachgruppefür Mikrosystementwurf [4].

Im Rahmen dieser Bachelorarbeit entstand das ProgrammAssembler-Compiler/-Debuggerund Memory-Viewer. Dieses wird im Hardwarepraktikum von den Studenten benutzt,um die selbst entwickelten Assemblerprogramme zu kompilieren, auf den FPGA zu über-tragen und, falls nötig, eine Fehlersuche durchzuführen. Weiterhin bietet das Programmdie Möglichkeiten den Speicher des FPGAs auszulesen und zu modifizieren sowie Ein-und Ausgabeoperationen durchzuführen.

Diese Bachelorarbeit beschreibt die Vorgehensweise bei der Entwicklung des Programmssowie dessen einzelner Module. Es wird auf Details in der Implementierung eingegangenund Design-Entscheidungen werden anhand von Beispielen erläutert. Anschließend wirdnoch ein Ausblick auf Erweiterungen oder Verbesserungsmöglichkeiten gegeben. Im An-hang findet sich zusätzlich eine Einführung für Anwender und die komplette Grammatikder hier verwendeten Assemblersprache. Auf der beiliegenden CD befindet sich die An-wendung, der Quellcode, ein Bitfile sowie Beispielprogramme und die Anhänge in HyperText Markup Language (HTML).

iii

Page 4: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Parallel zu dieser enstand auch die Bachelorarbeit Entwurf eines Speicher- und IO-Interfaces auf einem FPGA von Simon Hardt[5]. Diese beschäftigt sich mit der Hardware-Seite des genannten Prozessors, im Detail mit dessen Speicher- und Input/Output (IO)-Interface. Die beiden Bachelorarbeiten ergänzen sich in der Hinsicht, dass die Daten-übertragung vom Programm zum FPGA die entsprechende Schnittstelle zwischen beidendarstellt, dazu gehört auch die Kommunikation. Daher wird diese Seite des Hardware-praktikums hier nicht näher behandelt und es wird an passender Stelle auf [5] verwie-sen.

iv

Page 5: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Erklärung

1. Ich erkläre hiermit, dass ich diese Bachelorarbeit selbständig verfasst, noch nichtanderweitig für andere Prüfungszwecke vorgelegt, keine anderen als die angege-benen Quellen und Hilfsmittel benutzt sowie wörtliche und sinngemäße Zitate alssolche gekennzeichnet habe.

Siegen, den 6. Mai 2011

Page 6: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Inhaltsverzeichnis

1. Entwurfsüberblick 11.1. Ausgangslage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2. Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2. Grundlegende Definitionen 32.1. Programmiersprache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2. Schichtenmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3. Umgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3. Assembler-Compiler/-Debugger 63.1. Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2. Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.3. Sprache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.4. Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.4.1. Muster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.4.2. Grammatik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.4.3. Aktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.4.3.1. Schritt 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.4.3.2. Schritt 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.4.3.3. Schritt 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.4.3.4. Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.5. Design-Entscheidungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4. Benutzeroberfläche 324.1. Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324.2. Konsolenversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4.2.1. Kompilieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.2.2. Komplettes Debugging . . . . . . . . . . . . . . . . . . . . . . . . 344.2.3. Schrittweises Debugging . . . . . . . . . . . . . . . . . . . . . . . 36

4.3. Grafische Oberfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.3.1. Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.3.2. Menü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.3.2.1. Datei . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.3.2.2. Bearbeiten . . . . . . . . . . . . . . . . . . . . . . . . . 424.3.2.3. Sprache . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

vi

Page 7: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Inhaltsverzeichnis

4.3.2.4. Hilfe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.3.3. Assembler Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . 454.3.4. Assembler Debugger . . . . . . . . . . . . . . . . . . . . . . . . . 474.3.5. Memory-Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.3.6. Ein- und Ausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . 534.3.7. Design-Entscheidungen . . . . . . . . . . . . . . . . . . . . . . . . 53

5. Zusammenfassung und Ausblick 55

A. Anhang: Anwendungsszenario 57

B. Anhang: Assembler Grammatik 63

Literaturverzeichnis 79

vii

Page 8: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Abbildungsverzeichnis

2.1. Verwendetes Schichtenmodell . . . . . . . . . . . . . . . . . . . . . . . . 4

3.1. Befehlssatz des Prozessors . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2. Muster des Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.3. Hierarchie der store Regel . . . . . . . . . . . . . . . . . . . . . . . . . . 123.4. Definition der store Regel . . . . . . . . . . . . . . . . . . . . . . . . . . 133.5. Beispielcode der Multiplikation 3 x 4 . . . . . . . . . . . . . . . . . . . . 153.6. Schritte des Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.7. Label Aktionen Schritt 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.8. load Ausschnitt Schritt 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.9. Befehlstabelle nach Schritt 2 . . . . . . . . . . . . . . . . . . . . . . . . . 203.10. load Ausschnitt Schritt 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.11. Speicherdatei des Beispielcodes nach Schritt 3 . . . . . . . . . . . . . . . 223.12. load Ausschnitt Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . 243.13. jump Ausschnitt Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . 253.14. line Ausschnitt Schritt 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.15. load Ausschnitt mit einer Konstanten(Teil 1) . . . . . . . . . . . . . . . . 283.16. load Ausschnitt mit einer Konstanten(Teil 2) . . . . . . . . . . . . . . . . 293.17. .org Aktionen Ausschnitt . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.1. Startbildschirm der Konsolenversion . . . . . . . . . . . . . . . . . . . . . 334.2. Ausschnitt des Debuggers . . . . . . . . . . . . . . . . . . . . . . . . . . 354.3. Breakpoint im Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . 364.4. Flow-Chart des Anwendungsszenarios . . . . . . . . . . . . . . . . . . . . 384.5. Die Anwendung im Überblick . . . . . . . . . . . . . . . . . . . . . . . . 394.6. Das Menü im Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . 404.7. Das Datei Menü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.8. Das Bearbeiten Menü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424.9. Das Sprachen Menü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434.10. Das Hilfe Menü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.11. Der Reiter Assembler Editor . . . . . . . . . . . . . . . . . . . . . . . . . 454.12. Der Reiter Assembler Debugger . . . . . . . . . . . . . . . . . . . . . . . 474.13. Der Reiter Memory-Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . 50

viii

Page 9: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Abkürzungsverzeichnis

ANTLR ANother Tool for Language RecognitionEBNF Extended Backus-Naur FormEOF End of FileFPGA Field Programmable ArrayHTML Hyper Text Markup LanguageIO Input/OutputLALR Look-ahead, read from left to right, rightmost derivationLED Light-emitting diodeLL Read from left to right, leftmost derivationMIPS Microprocessor without Interlocked Pipeline StagesOPCode Operation CodeRS232 Recommended Standard 232 (Serial Port)USB Universal Serial Bus

ix

Page 10: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

1. Entwurfsüberblick

In diesem ersten Kapitel wird die Motivation für das in dieser Bachelorarbeit entstandeneProgramm näher gebracht. Die Ausgangslage sowie die daraus entstandenen Anforderun-gen werden dargelegt. Aufgrund dieser sind die in den folgenden Kapiteln behandeltenEntscheidungen maßgeblich beeinflusst.

1.1. Ausgangslage

Um erfolgreich zu planen und dementsprechend auch zu entwickeln, muss zuerst dieaktuelle Situation betrachtet und festgestellt werden, in welchem Umfeld die Softwarenachher benutzt werden soll. Das Hardwarepraktikum selbst wurde vorher bereits nä-her erklärt, jedoch wurde bisher nicht näher auf die verwendete Software eingegangen.Die für das Praktikum verwendete Software wurde unter dem namen Assembler- undMemoryviewer von Carsten Giersbach entwickelt. Als Programmiersprache diente C++, welche durch das grafische Toolkit QT mit einer Benutzeroberfläche versehen wurde.Das Kompilieren von Assemblerprogrammen wurde durch einen Aufruf des ProgrammsAssemblercompiler von Andre Hertwig [3] realisiert.Folgende Funktionen bot der Assembler- und Memoryviewer :

• Entwerfen, Laden und Speichern von Assemblerprogrammen

• Kompilieren von Assemblerprogrammen

• Kommunikation mit einem angeschlossenen FPGA

• Lesen, Schreiben sowie Visualisieren des Speichers vom FPGA

1

Page 11: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

1.2 Anforderungen

Diese Programme wurde längere Zeit in der Praxis eingesetzt, wodurch vermehrt Fehlererkannt wurden oder der Wunsch nach mehr Funktionalität größer wurde. Aufgrunddiesen Sachlverhalts entstand diese Bachelorarbeit und dementsprechend das ProgrammAssembler-Compiler/-Debugger und Memory-Viewer.

1.2. Anforderungen

Die Anforderungen an das hier entworfene Programm entstanden durch praktische Erfah-rungen sowie dem Wunsch nach Erweiterungen. Zusätzlich zu den vorhandenen Funk-tionlitäten des Vorgängerprogramms Assembler- und Memoryviewer sollten folgendenMöglichkeiten geboten werden:

• Kompilieren und Debuggen von Assemblerprogrammen neu und unabhängig vondem Programm Assemblercompiler [3] entwickeln

• Debuggen von Assemblerprogrammen direkt im Programm

• Unterstützung mehrerer Betriebssysteme

• Unnötige Abhängigkeiten vermeiden

• Möglichkeiten zur Erweiterung bieten

Welche Schritte und Entscheidungen für die Erfüllung der genannten Kriterien notwendigwaren, wird in den folgenden Abschnitten näher erläutert.

2

Page 12: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

2. Grundlegende Definitionen

In diesem Kapitel werden die grundlegenden Definition des Programms dargelegt. DieProgrammiersprache, das Schichtenmodell und die verwendete Umgebung werden be-schrieben. Dieses Kapitel bildet die Grundlage für die folgenden.

2.1. Programmiersprache

In den Anforderungen wurde unter anderem die Neuentwicklung des Compilers sowieeine Unterstützung für mehrere Betriebssysteme gefordert. Durch die Neuentwicklungwar die Wahl der Sprache nicht auf die des Vorgängers, C++, festgelegt. Die Wahl fielauf die Programmiersprache Java[6] .Diese bietet zum einen den Vorteil der Mobilität, das heißt dass Java unter Linux, Win-dows und MacOSx lauffähig ist, ohne weitere Abhängigkeiten von Bibliotheken. Dieswar ein Manko des Vorgängers, da es von mehrere Bibliotheken abhängig war und eskeine lauffähige Version für verschiedene Betriebssysteme gab.Weiter bietet Java eine sehr gute Umgebung für die Compiler Entwicklung an, ANotherTool for Language Recognition (ANTLR)[7], welche einen Großteil der Entwicklung vonAssembler-Compiler/-Debugger und Memory-Viewer betrifft.Java bietet als grafische Oberfläche in den Standard Biobliotheken Java Swing an. Sieverfügt über ein betriebssystemabhängiges Aussehen und lässt sich damit sehr gut inte-grieren. Weiter bietet Swing alle Funktionialitäten, die das Programm benötigt. Durchdie Wahl auf Swing werden auch weitere mögliche Abhängigkeiten vermieden.

3

Page 13: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

2.2 Schichtenmodell

2.2. Schichtenmodell

Das hier entwickelte Programm implementiert in Verbindung mit dem von Simon Hardtentwickelten Recommended Standard 232 (Serial Port) (RS232) - Modul für die Übertra-gung und dem IO-/Memoryinterface des FPGAs für die Kommunikation [5] das folgendeSchichtenmodell:

Abbildung 2.1.: Verwendetes Schichtenmodell

4

Page 14: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

2.3 Umgebung

Die Wahl dieser Schichtenaufteilung beruht auf der Idee der Kapselung aller Module.Durch diesen Aufbau bietet die Zugriffssschicht alle nötigen Aufrufe und Methoden fürden jeweiligen Aufrufer an. Die Wahl der Benutzeroberfläche (zum Beispiel grafisch odertextuell) spielt für die Zugriffsschicht keine Rolle, wodurch die Oberfläche austauschbarist, ohne dass die unteren Schichten geändert werden müssen. Dieses pflanzt sich bis indie unterste Schicht fort, wodurch ein modulares System entsteht.Die Zugriffsschicht bietet auch die Schnittstelle zum RS232 - Modul, welches von SimonHardt im Rahmen einer anderen Bachelorarbeit entwickelt wurde, an. Dies zeigt dieKapselung deutlich, da auch das RS232 - Modul austauschbar oder änderbar ist, ohnedass die anderen Schichten angepasst werden oder gar vorher bekannt sein müssen.

Die Anwendungsschicht benutzt die Methoden und Funktionen, die der Compiler undder Debugger anbietet. Diese kommuniziert mit der Zugriffsschicht, welche die Schnitt-stellen für alle Aufrufer bildet.

In den folgenden Kapitel werden die oberste und die untereste Schicht im Detail er-läutert, die rechte Seite wird in der Bachelorarbeit von Simon Hardt behandelt [5].

2.3. Umgebung

Um den Assembler-Compiler in Java zu implementieren musste eine Umgebung für dieEntwicklung festgelegt werden. Oft werden diese Umgebungen auch Compiler-Compilergenannt, da sie einen Compiler für einen Compiler darstellen. Die Wahl der Umgebungfiel auf ANTLR [7]. Der Grund dafür ist die gute Dokumentation sowie die verständli-che Syntax der Grammatiken, in denen man mithilfe von ANTLR die zu kompilierendeSprache beschreibt. Weiter lässt sich ANTLR sehr gut in Entwicklungsumgebungen ein-binden, in diesem Fall wurde es in Verbindung mit Eclipse[9] verwendet.Es sollte noch erwähnt werden, dass ANTLR nicht auf Java beschränkt ist und auch fürandere Sprachen wie zum Beispiel C++ verwendet werden kann.

5

Page 15: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3. Assembler-Compiler/-Debugger

In diesem Kapitel wird die unterste Schicht der Anwendung behandelt. Der Assembler-Compiler/-Debugger soll hier näher erläutert werden. Zuerst werden die Grundlageneines Compilers und die zugrundeliegende Assemblersprache beschrieben. Die Imple-mentation wird daraufhin mit Hilfe einiger Code-Beispiele näher gebracht. Im Detailwerden die definierten Muster, Grammatiken und jeweiligen Aktionen behandelt. ZumAbschluss werden wichtige Design-Entscheidungen und deren Lösungen detailliert dar-gelegt und sollen den Gedankengang bei der Entwicklung aufzeigen.

3.1. Einleitung

Der Assembler-Compiler/-Debugger bietet die Funktionalität, einen Assembler-Quellcodein Maschinencode zu übersetzen und den Quellcode auf Fehler zu untersuchen. Somitbietet dieser die Grundlage für die Entwicklung von Assembler Programmen und derenÜbertragung an den FPGA. Erst nach der Übersetzung kann der FPGA den Code lesenund ausführen. Weiter zeigt der Compiler dem Anwender syntaktische Fehler im Quell-code an, und ebenfalls in welcher Zeile und Spalte diese auftraten.Der Debugger hilft dem Anwender, semantische Fehler in dem Assembler-Quellcode zufinden, indem er den auf dem FPGA verwendeten Prozessor simuliert und die entspre-chenden Befehle ausführt. Der Anwender kann über diesen Weg Fehler in dem Assembler-Quellcode ausschließen oder aber verifizieren. Die Grundidee basiert auf dem VorgängerProgramm Assemblercompiler von Andre Hertwig [3], wurde jedoch von Grund auf neuentwickelt und um einige Funktionen erweitert.In den folgenden Abschnitten wird ausführlich dargestellt, welche Funktionen der Com-piler und der Debugger bieten und auf welche Weise diese implementiert wurden.

6

Page 16: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.2 Grundlagen

3.2. Grundlagen

Ein Compiler ist ein Übersetzer von einer Quellsprache in eine Zielsprache. Meist ist dieQuellsprache eine höhere Programmiersprache und die Zielsprache eine Maschinenspra-che. Sprachen werden durch reguläre Ausdrücke und deren Grammatiken beschrieben,mit deren Hilfe sich die gesamten Möglichkeiten der Sprache darstellen lassen.Der Compiler muss die kleinsten syntaktischen Einheiten, sogenannte Lexeme, erkennenund in eine Tokenfolge umwandeln. Diese Lexeme werden mit Hilfe von regulären Aus-drücken beschrieben. Nach der Lexikalischen Analyse folgt die Syntaktische Analyse.Diese erhält als Eingabe die zuvor entstandene Tokenfolge und überprüft die syntak-tische Richtigkeit des Programms. Die syntaktisch korrekten Programme werden ducheine kontextfreie Grammatik definiert.Oft verwendete Parser, welche die syntaktische Analyse durchführen, sind der Readfrom left to right, leftmost derivation (LL) und der Look-ahead, read from left to right,rightmost derivation (LALR) Parser. Ein LL Parser verarbeitet die Eingabe Top-Downwohingegen ein LALR Parser die Eingabe Bottom-Up verarbeitet. Durch diesen Sach-verhalt sind Grammatiken für einen LL Parser für einen Menschen lesbar, haben jedochNachteile wie zum Beispiel Linksrekursionen, die zu einer Endlosschleife bei der Erken-nung führen. Diese Probleme werden durch LALR Parser eliminiert, auf Kosten derÜbersicht.Der mit ANTLR verwendete Parser fällt in die LL Kategorie, was ihn, wie zuvor be-merkt, lesbarer macht.Falls das Programm keine unbekannten Lexeme oder syntaktische Fehler enthält werdendanach mithilfe von Regeln der Grammatik Aktionen ausgeführt. Diese Aktionen sindfrei definierbar und dienen in diesem Compiler dem Übersetzen von Quellsprache in dieZielsprache, oder dem Debugger zum Simulieren des Prozessors.Für mehr Informationen zum Thema Compilerbau lässt sich das Buch Compilers [8]empfehlen, welches dieses Thema sehr ausführlich behandelt.

3.3. Sprache

In dem hier entwickelten Programm wird eine Assemblersprache in eine Maschinenspra-che übersetzt. Die Assemblersprache ist relativ maschinennah anzusehen im Verhältnis

7

Page 17: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.3 Sprache

zu höheren Programmiersprachen wie zum Beispiel C++ oder Java.

Befehl OPCode(Binär) BedeutungST 10000 00 dest src0 src1 dest← src1

10000 01 dest src0 src1 M [src1]← src0

10000 10 dest src0 src1 const dest← const

LD 10001 00 dest src0 src1 dest← src1

10001 01 dest src0 src1 dest←M [src1]10001 10 dest src0 src1 const dest← const

OUT 10010 00 dest src0 src1 dest← src1

10010 01 dest src0 src1 IO[src1]← src0

10010 10 dest src0 src1 const dest← const

IN 10011 00 dest src0 src1 dest← src1

10011 01 dest src0 src1 dest← IO[src1]10011 10 dest src0 src1 const dest← const

JMP 00010 00 dest src0 src1 pc← src0

00010 10 dest src0 src1 pc← const

JNZ 00000 00 dest src0 src1 pc← src0, ifsrc1 6= 000000 10 dest src0 src1 pc← const, ifconst 6= 0

JZ 00001 00 dest src0 src1 pc← src0, ifsrc1 = 000001 10 dest src0 src1 pc← const, ifconst = 0

HALT 00111 − dest src0 src1 Prozessor hält

ADD 01000 − dest src0 src1 dest← src0 + src1

SUB 01001 − dest src0 src1 dest← src0 − src1

AND 01010 − dest src0 src1 dest← src0&src1

OR 01011 − dest src0 src1 dest← src0|src1

NOP 01100 − dest src0 src1 Keine Aktion

NOT 01101 − dest src0 src1 dest←!src1

SAL 01110 − dest src0 src1 dest← src1 << 1SAR 01000 − dest src0 src1 dest← src1 >> 1

Abbildung 3.1.: Befehlssatz des Prozessors

8

Page 18: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.3 Sprache

In Abbildung 3.1 ist der komplette Befehlssatz des von den Studenten zu entwerfen-den Prozessors zu sehen. Die Assemblersprache bietet alle nötigen Grundkonstruktewie Addition oder Sprünge, jedoch ist die Syntax nicht so komfortabel wie eine höhereProgrammiersprache. Dies ist mit Bedacht so gewählt, damit die Teilnehmer des Hard-warepraktikums Erfahrungen mit einer maschinennahen Sprache machen können.Als ein Beispiel für einen Befehl in Assemblersprache sei

add r1, r2, r3

angegeben. Dieser addiert die beiden Register 2 und 3 und schreibt das Ergebnis inRegister 1.Der entworfene Prozessor bietet eine Load-/Store Architektur an und orientiert sichan dem Microprocessor without Interlocked Pipeline Stages (MIPS) Befehlssatz. MehrInformationen zu dem Prozessor und dessen Aufbau findet man unter [3].Zusätzlich zu den in Abbildung 3.1 definierten Befehlen bietet die Assemblersprachenoch weitere Konstrukte:

• Kommentare (ein- oder mehrzeilig)

• Prozessordirektiven

• Breakpoints

Kommentare im Assemblercode sind wie üblich definiert durch die Befehle

//comment

für einzeilige und/ ∗ ...comment... ∗ /

für mehrzeilige Kommentare. Die mehrzeiligen Kommentare wurden im Zuge der Bache-lorarbeit für mehr Komfort bei der Assemblerprogrammierung neu eingeführt.

9

Page 19: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Es gibt in der definierten Sprache drei Prozessordirektiven, die wie folgt definiert sind:

1. .org adress - Speichert den folgenden Code ab der Stelle adress

2. .dw label value - Speichert an die aktuelle Speicherstelle den Wert value und ver-knüpft diesen mit dem Label label

3. .equ label value - Verknüpft den Wert value mit dem Label label.

Im Hinblick auf das Debuggen wurde die Funktion Breakpoint neu eingebaut, welcherwie folgt definiert ist:

• !BREAK! - Pausiert die Ausführung des Assemblerprogramms an der aktuellenStelle

Mithilfe der zuvor genannten Zusätze und des Befehlssatzes des Prozessors ist die gesam-te Assemblersprache, die im Hardwarepraktikum benutzt wird und somit implementiertwurde, definiert.Als Zielsprache wurde ein Maschinencode festgelegt, welche als Befehle 16 Bit breiteDaten, optional gefolgt von einer 16 Bit breiten Konstanten, annimmt. Dieser ist in Ab-bildung 3.1 unter der Spalte Operation Code (OPCode) zu sehen.Dieser OPCode kann entweder Hexadezimal (4 Stellen) oder Binär (16 Stellen) codiertund entsprechend weiterverarbeitet werden.

3.4. Implementation

Nachdem alle Grundlagen für die Entwicklung eines Compilers dargelegt wurden, solldie Implementation anhand eines Beispiels näher erläutert werden. Dazu wird auch aufProbleme und Entscheidungen, die bei der Entwicklung entstanden, eingegangen undderen Lösungen dargelegt.Die gesamte Definition der Grammatik inklusive aller Regeln und Muster sowie Lexemefindet in einer *.g Datei statt. Aus dieser werden die Parser und Lexer Dateien vonANTLR generiert, welche dann beim Kompilieren verwendet werden. Es sollen die Teileeiner solchen Grammatik-Datei näher erläutert werden.

10

Page 20: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

3.4.1. Muster

In dem entwickelten Compiler gibt es folgende Muster:

1 MINUS: ’− ’ ;2 DIGIT : ( ’ 0 ’ . . ’ 9 ’ ) ;3 HEXDIGIT: ( ( ’A ’ . . ’F ’ | ’ a ’ . . ’ f ’ ) | DIGIT) ;4 LETTER: ( ’ a ’ . . ’ z ’ | ’A ’ . . ’Z ’ ) ;5 REGISTER: ( ’ r ’ | ’R ’ ) ( ’ 0 ’ . . ’ 7 ’ ) ;6 CHAR: ( (LETTER) | (DIGIT) | ’_ ’ | ’ $ ’ | ’#’ ) ;7 IDENT: ( (LETTER) (CHAR) ∗) ;8 NUMBER: (DIGIT)+;9 HEXNUMBER: ( ’ 0x ’ (HEXDIGIT)+) ;

10 LABEL: IDENT ’ : ’ ;11 WHITESPACE: ( ’ ␣ ’ | ’ \ t ’ | ’ \ f ’ )+ {$channel=HIDDEN; } ;12 NEWLINE: ( ’ \n ’ | ’ \ r ’ )+ ;13 SLCOMMENT: ’ // ’ .∗ NEWLINE ;14 MLCOMMENT: ’ /∗ ’ .∗ ’ ∗/ ’ NEWLINE ;15 BREAKPOINT: ’ !BREAK! ’ ;

Abbildung 3.2.: Muster des Compilers

Wie man sieht werden Muster in der Extended Backus-Naur Form (EBNF) definiert.Wenn man zum Beispiel das Muster HEXNUMBER näher betrachtet, fällt auf, dass esaus einer führenden 0x und einem folgenden HEXDIGIT besteht. Ein HEXDIGIT be-steht widerrum aus einem Buchstaben zwischen a und f oder einem DIGIT. Ein solchesDIGIT besteht aus einer Zahl zwischen 0 und 9.Dazu sollte auch die Anzahl der einzelnen Elemente beachtet werden:Ein DIGIT besteht genau aus einer Zahl, ein HEXDIGIT besteht aus genau einemBuschstaben oder einer Zahl, wohingegen eine HEXNUMBER aus genau einem 0x be-steht und mindestens einem HEXDIGIT, aber unbestimmt vielen.Ein interessantes Muster ist das des WHITESPACE, da es im Gegensatz zu den an-deren eine Option definiert. Es besteht aus mindestens einem Leerzeichen oder einemTabulator. Die Option

$channel = HIDDEN

sagt dem Lexer, dass er beim Erkennen dieses Musters die Eingabe nicht in den nor-malen Kanal einfügt, sondern in einen versteckten. Dies bewirkt, dass der Parser , dernachher den normalen Kanal abarbeitet, nichts von diesen sieht. Somit werden solche

11

Page 21: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

WHITESPACES für den Parser entfernt und es macht für diesen keinen Unterschied obein solches vorhanden war oder nicht.Hier werden zusätzlich zur vorigen Assemblersprache von Andre Hertwig[3] die Befeh-le des mehrzeiligen Kommentars und des Breakpoints definiert. Diese bieten weiterenKomfort für den Assemblerprogrammierer.Beim Kompilieren ist der erste Schritt das Erkennen von den oben definierten Mustern.Falls er ein Lexem findet, was nicht in einem der oberen Muster entspricht, zeigt derLexer eine Fehlermeldung.Nach der Erkennung der Muster wird im nächsten Schritt die Syntax des Befehls über-prüft, dies geschieht mithilfe der Grammatik, die im Folgenden erläutert wird.

3.4.2. Grammatik

Die Grammatik der Assemblersprache definiert die Syntax dieser. Sie dient zur Erken-nung der syntaktischen Richtigkeit der Eingabe und lehnt diese entsprechend ab bzwakzeptiert diese. Hier soll ein Beispiel1 herausgegriffen und erläutert werden.Es wird die Regel store betrachtet, welche dazu dient, Werte in Registern oder im Spei-cher abzulegen. Ein solcher Befehl wird vom Compiler durch folgende Hierarchie derGrammatik erkannt:

Abbildung 3.3.: Hierarchie der store Regel

1Die gesamte Grammatik findet sich im Anhang unter B

12

Page 22: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Abbildung 3.3 zeigt, wie der Compiler den Befehl

st r1, r2

verarbeitet. Er erkennt anhand des Befehls, dass es sich um ein Programm handelt, wel-ches wiederrum aus einer Zeile und dem End of File (EOF) besteht. Die Zeile setzt sichaus einem Befehl und ein einem Zeilenumbruch zusammen. Aus den Befehlen erkenntder Compiler die store Regel. Die unterste Ebene zeigt den Befehl selber.Auf diese Art erkennt der Compiler durch die definierte Grammatik die jeweiligen Re-geln und spaltet diese auf beziehungsweise durchläuft deren Hierarchie.

Es gibt drei Möglichkeiten, den store Befehl zu verwenden2:

1. Einen Registerinhalt in ein anderes Register schreiben(direkte Adressierung)

2. Einen Registerinhalt an eine Stelle im Speicher schreiben(indirekte Adressierung)

3. Eine Konstante in ein Register schreiben

Um diese drei Möglichkeiten abzudecken, sieht die Definition der store Regel folgender-maßen aus:

Abbildung 3.4.: Definition der store Regel

Die store Regel besteht aus einem führenden st oder ST, was den Befehl unverwechsel-bar macht. An dieser Stelle muss eins der beiden Keywords stehen, gefolgt von den dreigenannten Möglichkeiten. Wie man sieht, gabelt sich der Weg in diese drei auf, wobei

2Siehe dazu auch Abbildung 3.1

13

Page 23: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

das oberste der ersten enstpricht, das mittlere der zweiten und das untere inklusive derspäteren Verzweigungen der dritten Möglichkeit.Letztere spaltet sich erneut in folgende Wege auf:

• Die Konstante ist eine (negative) Dezimalzahl

• Die Konstante ist eine Hexadezimalzahl

• Die Konstante ist ein im restlichen Assemblercode festgelegtes Keyword(Label)

Diese drei Möglichkeiten müssen später bei den Aktionen gesondert betrachten werden,da jeder Fall andere Konsequenzen mit sich bringt.Die übrigen Regeln sind vom Aufbau her ähnlich definiert und werden daher hier nichtnäher erläutert.Da durch die gegebenen Definitionen die Syntax eines Befehls überprüft werden kann,soll der nächste Abschnitt die genannten Aktionen näher betrachten.

3.4.3. Aktionen

Die Grammatik des Compilers muss zusätzlich zum Erkennen der Syntax der Eingabebestimmte Aktionen ausführen, um ein Ergebnis zu liefern. Aktionen sind im optionaleRümpfe einer Regel der Grammatik, in welcher der entsprechende Java-Code ausgeführtwird, falls diese Regel erkannt wurde. Das vorige Beispiel des store Befehls würde dieenstprechenden Aktionen des Rumpfes der store Regel ausführen, da er diese erkannthat.Der Compiler besteht aus drei Schritten, die er nacheinander durchführen muss, umdas richtige Ergebnis und somit das fertige Maschinenprogramm als Ausgabe zu liefern.Trotz gleicher Grammatik in jedem dieser Schritte werden unterschiedliche Aktionendurchgeführt die zu unterschiedlichen Ergebnissen führen.Anhand dem folgendem Beispielcode3 in Abbildung 3.5 sollen alle Schritte des Compilersund Debuggers im Folgenden erläutert werden.

3Dieser ist auf der beiliegenden CD zu finden unter dem Namen beispielcode.asm

14

Page 24: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

1 ld r1 ,#02 ld r2 ,#33 ld r5 ,#14 ld r6 ,#45

6 loop :7 !BREAK!8 add r1 , r2 , r19 sub r6 , r6 , r5

10 jnz #loop , r611 jmp #ende12 ende :13 ha l t

Abbildung 3.5.: Beispielcode der Multiplikation 3 x 4

Der Beispielcode führt eine 3 × 4 Multiplikation durch. In den Zeilen 1 bis 4 werdenKonstanten in die jeweiligen Register geladen. Register 1 ist das Ergebnisregister undRegister 5 speichert eine Zählvariable. Die Schleife ab Zeile 6 bis 11 führt dann die Mul-tiplikation durch, indem auf den Inhalt von Register 1 die Konstante 3 addiert wird.Danach wird Register 6 um eins erniedrigt und daraufhin überprüft, ob dieses 0 ist. Istdies der Fall ist die Multiplikation abgeschlossen und es wird zum Label ende gesprun-gen, welches den Prozessor mithilfe des HALT Befehls anhält. Ist dies nicht der Fall wirdzum Label loop gesprungen, und die genannten Aktionen der Schleife erneut durchge-führt. Besonders zu betrachten ist Zeile 7, in welcher ein neu definiertes Element derAssemblersprache auftaucht: !BREAKPOINT! . Dieses Muster wird vom Compiler zwarerkannt und bearbeitet, spielt aber nur im Debugger eine Rolle, um Fehler zu findenmithilfe eines Punktes, wo die Ausführung anhält.Wie man sieht bietet die Assemblersprache eine Operation wie die Multiplitkation nurüber Umwege an, hier mithilfe der Operationen Addition, Subtraktion und Sprüngen.Wie bereits erwähnt ist dies gewollt so entwickelt worden, um den Studenten des Hard-wareprakikums eine hardwarenahe Erfahrung zu bieten.

15

Page 25: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

In der folgenden Abbildung ist eine Übersicht der Schritte des Compilers zu sehen. Siezeigt wie die einzelnen Schritte, Tabellen sowie Arrays miteinander zusammenhängen.Die Inhalte genannter Tabellen und Arrays entsprechen denen des Beispielcodes, enthal-ten aber nur einen aktuellen Schnappschuss, nicht den kompletten Beispielcode.In den folgenden Abschnitten sollen anhand des zuvor angegebenen Beispielcodes je-der einzelne Schritt durchleuchtet werden und auch das Zusammenspiel näher erläutertwerden.

Abbildung 3.6.: Schritte des Compilers

16

Page 26: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

3.4.3.1. Schritt 1

Dieser erste Schritt des Kompiliervorgangs dient als Grundlage für die weiteren Schrit-te. Die Hauptaufgabe dieses Schritts ist das Aufbauen einer Tabelle für vorkommendeLabels. Ein Label ist eine Benennung für eine Variable oder eine Stelle im Code. BeideEinsatzgebiete erhöhen die Lesbarkeit der Assemblerprogramme und werden aus diesemGrund von der hier benutzten Assemblersprache unterstützt.Im Beispielcode aus Abbildung 3.5 tauchen die zwei Labels loop und ende auf. Um Labelszu unterstützen muss der erste Schritt folgende Aktionen durchführen:

• Die aktuelle Zeile bestimmen

• Vorkommende Labels in eine Tabelle eintragen

Warum ist dieser Schritt nötig und kann nicht in einen späteren integriert werden ?

Dazu soll aus dem Beispielcode in Abbildung 3.5 die Zeile 11 betrachtet werden. Hierwird ein Sprung durchgeführt an das Label ende. An dieser Stelle kennt der Compilerjedoch dieses Label noch nicht, da dies erst in der Zeile 12 definiert wird mit ende . Wennman somit diesen ersten Schritt nicht vor den nächsten ausführt, kann es passieren, dassder Compiler nicht weiß, an welche Stelle er springen soll, oder welche Konstante erladen soll, da er das Label noch nicht kennt.Da ein Label in einer Tabelle zusammen mit der Zeilennummer, in der das Label vor-kommt, gespeichert wird, muss die aktuelle Zeilennummer bestimmt werden. Wenn derCompiler dann später auf das Label trifft, zum Beispiel in Zeile 10, schaut er in derTabelle nach und erhält als Antwort die Zeilennummer, an welcher er den benötigtenWert findet.

17

Page 27: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

1 label :2

3 LABEL {4 i f ( P r e f e r enc e s . hexa == true )5 I n s t r u c t i onS e t . addLabel ($LABEL. getText ( ) . s ub s t r i ng (0 ,

$LABEL. getText ( ) . l a s t IndexOf ( ’ : ’ ) ) ,6 I n s t r u c t i onS e t . opCodeToHex( I n s t r u c t i onS e t .

stringToOpCode ( " "+(lineNumber ) , fa l se ) ) ) ;7 else8 I n s t r u c t i onS e t . addLabel ($LABEL. getText ( ) . s ub s t r i ng (0 ,

$LABEL. getText ( ) . l a s t IndexOf ( ’ : ’ ) ) ,9 I n s t r u c t i onS e t . stringToOpCode ( " "+(lineNumber ) , fa l se ) ) ;

10 } ;

Abbildung 3.7.: Label Aktionen Schritt 1

Abbildung 3.7 zeigt die Aktionen der Regel LABEL:Wenn der Compiler das Muster label erkennt, wird je nach Option entweder der hexa-dezimale oder der binäre Wert der Zeilennummer in Verbindung mit dem Label ohnefolgenden Doppelpunkt eingetragen.Wenn dieser Schritt auf den Beispielcode in Abbildung 3.5 angewandt wird, erhält manfolgende Label-Tabelle:

loop = 0008, ende = 000e

Wie man sieht wurde loop die Zeile 8 zugewiesen. Dieses hängt damit zusammen, dasszuvor Konstanten in Register geladen wurden und diese jeweils eine eigene Befehlszeileverwenden. Im nächsten Schritt sollte dieser Zusammenhang deutlicher werden, da dortdas Befehls-Array erläutert wird.

3.4.3.2. Schritt 2

Der zweite Schritt im Compiler dient der Vorbereitung für späteres Debuggen. In diesemwird ein Befehls-Array aufgebaut, welches später vom Debugger als Input genutzt wird.

18

Page 28: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Der Compiler durchläuft das Assemblerprogramm und fügt jeden erkannten Befehl 4 indas erwähnte Array ein.In der folgenden Abbildung ist ein Beispiel5 für eine Aktion zu sehen:

1 ld :2 ( ’ ld ’ | ’LD ’ ) ( rde s t=REGISTER ’ , ’ r s r c 1=REGISTER3 { In s t r u c t i onS e t . commands [ commandPC] = $ld . t ex t ; }4 |5 .6 .7 .

Abbildung 3.8.: load Ausschnitt Schritt 2

Das Befehlsarray wird an der aktuellen Stelle, definiert durch eine Zählvariable com-mandPC, mit dem erkannten Befehl beschrieben.Auch dieser Schritt wird daraufhin auf den Beispielcode in Abbildung 3.5 angewendet,wodurch man die in Abbildung 3.9 aufgeführte Befehlstabelle erhält.Im Schritt zuvor war noch unklar, warum für das Label loop die Zeile 8 (anstatt 5) ein-getragen wurde. Laut Befehlstabelle sieht man, dass an der Stelle 8 im Array der Befehlsteht, der nach dem Label loop im Quellcode auftaucht:

add r1, r2, r3

So verhält es sich auch mit dem folgenden Label ende, welches den halt Befehl an derStelle 14 als nächstes ausführt. Diese Tabelle wird später vom Debugger benutzt, umBefehle und insbesondere Sprünge auszuführen.Zu beachten ist hierbei, dass bei Operationen mit Konstanten, hier der LOAD Befehl,eine weitere Befehlszeile für diese benutzt wird. Das liegt daran, dass Befehle wie Kon-stanten 16 Bit breit sind und dementsprechend eine eigene Stelle im Array und späterim Speicher benötigen.

4Siehe Abbildung 3.15Der Übersicht wegen wurde die direkte Adressierung mit zwei Registern gewählt

19

Page 29: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Stelle im Array Befehl Stelle im Array Befehl0 ld r1 ,#0 8 add r1,r2,r11 0000 9 sub r6,r6,r52 ld r2 ,#3 10 jnz #loop,r63 0003 11 00084 ld r5, #1 12 jmp #ende5 0001 13 000e6 ld r6,#4 14 halt7 0004

Abbildung 3.9.: Befehlstabelle nach Schritt 2

Dieser Vorgang muss vor dem Debugger ausgeführt werden, da dieser zur Ausführungdas hier enstandene Befehls-Array benötigt. Der Debugger benutzt das Befehls-Arrayals Eingabe6.Nachdem diese beiden Schritte durchgeführt wurden, sind alle nötigen Vorbereitungenfür das Kompilieren getroffen worden. Der nächste Schritt kann danach ausgeführt wer-den, welcher dann das gewünschte Endergebnis liefert.

3.4.3.3. Schritt 3

Dieses ist der letzte Schritt in einem Kompiliervorgang. Nach den Vorbereitungen dervorherigen Schritte können in diesem Aktionen ausgeführt werden, die nachher zu derder gewollten Ausgabe führen: Maschinencode. Um dies zu erreichen, wird bei jeder er-kannten Regel ein String, welcher dem jeweiligen Maschinencode entspricht, in ein Arraygeschrieben. Nach dem kompletten Einlesen des Eingabeprogramms steht in diesem Ar-ray der gesamte Maschinencode des Assemblerprograms, welcher nachher in eine *.memDatei geschrieben werden kann. Diese Datei kann nachher in den Speicher des FPGAsübertragen und ausgeführt werden.

6Siehe Abbildung 3.6

20

Page 30: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Es soll als Beispiel ein Ausschnitt des load Befehls betrachtet werden :

1 ld :2 ( ’ ld ’ | ’LD ’ ) ( rde s t=REGISTER ’ , ’ r s r c 1=REGISTER3 { In s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

getOpCode ( "LD" )4 + In s t r u c t i onS e t . getOpCode ( "REG_IMM" )5 + In s t r u c t i onS e t . getOpCode ( $ rde s t . t ex t )6 + In s t r u c t i onS e t . getOpCode ( "REG_OFFSET" )7 + In s t r u c t i onS e t . getOpCode ( $ r s r c 1 . t ex t ) ;8 i f ( P r e f e r enc e s . hexa == true )9 I n s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

opCodeToHex( I n s t r u c t i onS e t .memory [ adre s s ] ) ; }10 |11 .12 .13 .

Abbildung 3.10.: load Ausschnitt Schritt 3

Wie üblich wird erst die Syntax definiert, wie in Zeile 2 zu sehen. Die darauffolgendenZeilen definieren die Aktionen, die in diesem Schritt ausgeführt werden. Es wird einkonkatenierter String an die aktuelle Stelle adress in das Speicher-Array geschrieben, undfalls der Benutzer die hexadezimale Speicherung wünscht, wird die binäre Darstellungin eine hexadezimale umgewandelt, hier in Zeile 8 bis 9 zu sehen.Der konkatenierte String setzt sich aus mehreren Teilen zusammen:

• OPCode des Befehls LOAD

• OPCode der direkten Addressierung

• Das Zielregister, binär codiert

• Ein Platzhalter, da in diesem Befehl nur zwei Register vorhanden sind

• Das Quellregister, binär codiert

21

Page 31: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Alle diese Teile werden aus der OPCode Tabelle gelesen und sind binär codiert.Nach der Konkatenation erhält man ein 16 Bit breites binäres Datum, welches an dieaktuelle Speicherstelle geschrieben wird. Standardmäßig wird dieses Datum vor demSchreiben in einen hexadezimalen Wert umgewandelt. Dies wird für alle Befehle desAssemblerprogramms durchgeführt, wodurch man nachher im Speicher-Array somit alleBefehle in der richtigen Reihenfolge, beziehungsweise an den richtigen Speicherstellen,findet. Dieses Array kann nach dem dritten Schritt in eine Speicherdatei mit dem Namen*.mem geschrieben und an den FPGA übertragen werden.

1 8c402 00003 8c804 00035 8d406 00017 8d808 00049 4051

10 49b511 040612 000813 140014 000 e15 3800

Abbildung 3.11.: Speicherdatei des Beispielcodes nach Schritt 3

In Abbildung 3.11 findet man das Ergebnis des kompletten Kompiliervorgangs des Bei-spielcodes in Form der entstandenen Speicherdatei7. Diese kann jetzt mit Hilfe desAssembler-Compilers/-Debuggers und Memory-Viewers über die RS232-Schnittstelle inden Speicher des FPGAs geschrieben und dann ausgeführt werden.

7Diese Datei ist unter dem Namen beispielcode.mem auf der beiliegenden CD zu finden

22

Page 32: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Im folgenden Abschnitt soll eine andere Komponente des Programms beleuchtet werden:Der Debugger. Dort sind nach diesen drei Schritten weitere Aktionen in der Grammatiknötig, um das Programm auf Fehler testen zu können und somit das gewünschte Ergebniszu erhalten.

3.4.3.4. Debugger

Nach dem Entwerfen eines Assemblerprogramms übertragen die Studenten den in denvorherigen Schritten entstandenen Maschinencode auf den FPGA. Dort wird dieser aus-geführt und liefert ein Ergebnis. Oft stimmt dieses Ergebnis jedoch nicht mit dem erwar-teten überein, so dass danach geprüft werden muss, wo der Fehler liegt. Genauer gibt eszwei unterschiedliche Quellen:

• Entwurfsfehler beim Prozessor

• Fehler im Assemblerprogramm

Im Hardwarepraktikum konnten die Studenten den Assemblercode vorher nur umständ-lich in einem anderen Programm überprüfen, welcher der beiden Fälle vorlag. Zusätzlichbot der Debugger des Vorgängers kaum Informationen über den aktuellen Prozessor-zustand und konnte nur in einer Konsole ausgeführt werden. Um diesen Mißstand zubeheben, bietet das Programm Assembler-Compiler/-Debugger und Memory-Viewerauch eine neu entwickelte Debug-Möglichkeit an.Diese simuliert den zu entwerfenden Prozessor, der später auf dem FPGA die Assembler-programme ausführt. Der Debugger führt die Operationen und Befehle entsprechend ausund liefert deren Ergebnisse, so dass nach einigen Tests genau bestimmt werden kann,ob ein Fehler im Assemblerprogramm oder im zuvor entworfenen Prozessor vorliegt. Essollen die in der Debugger-Grammatik definierten Aktionen und deren Beweggründedargestellt werden.

23

Page 33: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Im Debugger werden folgende Datentypen benutzt, um den Prozessor auf dem FPGAnachzubilden:

• 8 Stellen großes Register-Array

• 65536 Stellen großes Speicher-Array

• 65536 Stellen großes Befehls-Array

• Befehlszähler, als Integer realisiert

Die Register, der Speicher und der Befehlszähler entsprechen den jeweiligen Gegen-stücken, welche durch den FPGA vorgegeben sind. Aus diesem Grund wurden auch dieentsprechende Größen gewählt. Zu den genauen Hardware Spezifikationen sei auf [2]verwiesen.Das Befehls-Array gibt es nur im Debugger und wird dort benutzt, um die entsprechen-den Befehle auszulesen und dann auszuführen. Der Aufbau und der Inhalt des Arrayswird in Abschnitt 3.4.3.2. näher erläutert.Zu Beginn soll ein Ausschnitt aus dem load Befehl gezeigt werden:

1 ld :2 ( ’ ld ’ | ’LD ’ ) ( rde s t=REGISTER ’ , ’ r s r c 1=REGISTER3 { In s t r u c t i onS e t . r e g i s t e r s [ I n t e g e r . pa r s e In t (

I n s t r u c t i onS e t . getOpCode ( $ rde s t . t ex t ) , 2 ) ] =4 I n s t r u c t i onS e t . r e g i s t e r s [ I n t e g e r . pa r s e In t (

I n s t r u c t i onS e t . getOpCode ( $ r s r c 1 . t ex t ) , 2 ) ] ; }5 |6 .7 .8 .

Abbildung 3.12.: load Ausschnitt Debugger

24

Page 34: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.4 Implementation

Wie in den Abschnitten davor beginnt der Code mit der Syntax-Definition des Befehls,worauf die auszuführenden Aktionen folgen. Wie zu sehen, wird bei einem LOAD Befehl8

das Register-Array beschrieben. Es wird der Wert, der in Register rsrc1 steht, in dasRegister rdest geschrieben. Bei einem Assemblerbefehl der Form

ld r1, r2

wird in das Register-Array an der Stelle 1 der Inhalt des Register-Arrays der Stelle 2geschrieben. Diese Aktion entspricht der Definition des LOAD Befehls, die auch der Pro-zessor nachher ausführt.

Als weiteres Beispiel dient der folgende JUMP9 Befehl:

1 jmp :2 ( ’ jmp ’ | ’JMP’ ) ( r s r c 0=REGISTER3 { In s t r u c t i onS e t . pc = In s t r u c t i onS e t . r e g i s t e r s [ I n t eg e r .

pa r s e In t ( I n s t r u c t i onS e t . getOpCode ( $ r s r c 0 . t ex t ) , 2 ) ]; }

4 |5 .6 .7 .

Abbildung 3.13.: jump Ausschnitt Debugger

Ein solcher Befehl ändert den aktuellen Befehlszähler im Debugger, so wie der von denStudenten entworfen Prozessor. Somit wäre der nächste Befehl des Debuggers derjenige,der in dem Befehls-Array an der Stelle des neuen Befehlszählers steht. Ein Sprung wirdalso dadurch simuliert, dass die Zählvariable, hier der Befehlszähler, der den aktuellenauszuführenden Befehl bestimmt, auf den neuen Wert geändert wird.Diese zwei Beispiele sollten verdeutlichen, welche Aktionen der Debugger ausführt, umden Prozessor des Hardwarepraktikums zu simulieren, um die Fehlerfreiheit des Assem-blerprogramms zu verifizieren. Die übrigen Befehle (siehe Abbildung 3.1) sind ähnlich,verwenden jedoch je nach Befehl zusätzlich das definierte Speicher-Array.

8Bei direkter Register Adressierung9Erneut nur eine direkte Register Addressierung

25

Page 35: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

In den vorigen Abschnitten wurden alle Schritte und die Implementation des Compilersund des Debuggers anhand einfacher Fälle erläutert, um die Übersicht über deren Funk-tionsweise zu wahren. Im nächsten Abschnitt werden dagegen Problemfälle und derenLösungen beim Entwurf erörtert.

3.5. Design-Entscheidungen

Im Laufe der Entwicklung des Compilers und Debuggers sind einige Probleme aufge-taucht, die es zu lösen galt. Neben den zuvor gezeigten Entscheidungen, die die Art derAusführung und die Softwaretechnik generell betrifft, gab es weitere solcher wichtigenWahlmöglichkeiten.Zu Beginn musste eine Repräsentation für die spätere Ausgabe der Befehle festgelegtwerden. Es wurde als Datentyp ein String gewählt, an welchen nach jedem erkanntenBefehl der Maschinencode und ein Zeilenumbruch angehängt wurden. Nach der Abarbei-tung eines Assemblerprogramms enthielt der genannte String dann den Maschinencode.Dieser wurde danach in die Speicherdatei geschrieben und anschliessend an den FPGAübertragen.Bei dieser Art der Repräsentation gab es jedoch einige Unzulänglichkeiten:

1. Durch die Konkatenation war keine Adressierung einzelner Zeilen(Speicherstellen)möglich, daher nur Hinzufügen weiterer Befehle möglich

2. Bei jeder Konkatenation wird ein neuer String erstellt mit der alten Länge plusden neuen Befehl (Rechenaufwand)

3. Wegen Punkt 1 kein direkter Zugriff auf Befehle im Debugger

Durch die oben genannten Gründe ist sogar eine Implementierung der Prozessordirek-tive .org10 unmöglich, falls man auch kleinere Adressen als die aktuelle als Argumentzulassen will, da man Zeilen nicht direkt adressieren kann.Aus diesen Gründen wurde anstatt einem String ein Array von Strings gewählt, wobeidie Stelle des Arrays die entsprechende Stelle im Speicher repräsentiert. Mithilfe die-ser Änderung sind alle obigen Nachteile eliminiert worden. Aus diesen Gründen wurden

10Siehe Abschnitt 3.3

26

Page 36: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

auch für die Befehle, die Breakpoints und die Register Arrays gewählt.

Es sollen die Entscheidungen, die die auszuführenden Aktionen betreffen, näher erläutertwerden.Wie in den Abschnitten zuvor erwähnt, werden oft Zählvariablen benutzt, um die ak-tuelle Zeilennummer oder aber die aktuelle Adresse im Speicher herauszufinden. ImAssembler-Compiler/-Debugger und Memory-Viewer wurde das über die in Abschnitt3.4.2 erläuterte Hierarchie realisiert. Da jeder Befehl auch eine Zeile ist, wird die jewei-lige Zählvariable in der Aktion einer Zeile angepasst:

1 l i n e :2 ( label ? com=command ( SLCOMMENT | MLCOMMENT | NEWLINE )3 | (SLCOMMENT | MLCOMMENT) | label ( SLCOMMENT | MLCOMMENT |

NEWLINE )4 | NEWLINE )5 i f ($com . tex t != null ) { lineNumber++ ; } } ;

Abbildung 3.14.: line Ausschnitt Schritt 1

Über diesen Weg muss man die Zählvariablen nicht in jedem Befehl selbst erhöhen, die-ses wird durch die Hierarchie passend erledigt.

Als weitere wichtige Entscheidung, die es zu treffen galt, kann man das Verhalten bei derVerwendung von Konstanten nennen. Dazu soll als Beispiel der load Befehl aus Schritt3 genauer betrachtet werden. Die folgende Abbildung zeigt den ersten Teil des Befehls,der eine Konstante in ein Register lädt.

27

Page 37: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

1 ld :2 rd e s t=REGISTER ’ , ’ ’#’ (minus=MINUS? constnum=( DIGIT

| NUMBER) |3 consthex=HEXNUMBER | c on s t l a b e l = IDENT )4 { In s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

getOpCode ( "LD" )5 + In s t r u c t i onS e t . getOpCode ( "REG_ADR" )6 + In s t r u c t i onS e t . getOpCode ( $ rde s t . t ex t )7 + In s t r u c t i onS e t . getOpCode ( "REG_OFFSET" )8 + In s t r u c t i onS e t . getOpCode ( "REG_OFFSET" ) ;9 i f ( P r e f e r enc e s . hexa == true )

10 I n s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .opCodeToHex( I n s t r u c t i onS e t .memory [ adre s s ] ) ;

11 adre s s++;

Abbildung 3.15.: load Ausschnitt mit einer Konstanten(Teil 1)

Es wird, wie üblich, die Syntax definiert und darauf folgend die Aktionen. In diesemAusschnitt ist die erste wichtige Aktion zu sehen:Das Aufbauen des Maschinencodes und das darauffolgende Beschreiben des Speicher-Arrays. Danach wird die aktuelle Adresse um eins erhöht. Dabei gilt zu beachten, dassin dem Fall einer Konstanten, die Zählvariable, hier die Adresse, bereits in dem aktuellenBefehl erhöht wird. Zusätzlich dazu wird die Adresse nach dem Befehl durch die zuvorbesprochende Aktion in line erneut erhöht.Somit wurde die aktuelle Adresse nach einem solchen Befehl um zwei erhöht, was derzusätzlichen Zeile im Speicher für die Konstante geschuldet ist. In der ersten benutztenStelle des Speichers steht dann der Maschinencode für den load Befehl, wohingegen inder zweiten Stelle die Konstante steht.Nach dem gezeigten ersten Ausschnitt steht bereits der Maschinencode im Speicherund die Zählvariable wurde erhöht. Daraufhin folgt im zweiten Teil das Eintragen derKonstanten in den Speicher.

28

Page 38: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

1 i f ( $constnum . text != null && $minus . t ex t != null ) {2 i f ( P r e f e r enc e s . hexa == true )3 I n s t r u c t i onS e t .memory [ adre s s ] =4 I n s t r u c t i onS e t . opCodeToHex( I n s t r u c t i onS e t . stringToOpCode (

$constnum . text , true ) ) ;5 else6 I n s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

stringToOpCode ( $constnum . text , true ) ;7 }8 else i f ( $constnum . text != null ) { . . . }9 else i f ( $ c on s t l ab e l != null ) { . . . }

10 else i f ( $consthex != null ) { . . . }11 ;

Abbildung 3.16.: load Ausschnitt mit einer Konstanten(Teil 2)

Wie bereits in Abschnitt 3.4.2. beschrieben, gibts es vier Möglichkeiten für eine Kon-stante. In dem gezeigten Ausschnitt ist nur die Aktion des ersten Falls, einer negativenDezimalzahl, zu sehen.Der in den Speicher einzutragende Code ergibt sich daraus, die Methode

stringToOpCode(String input, boolean negative)

mit dem Wert der Konstanten und true aufzurufen. Diese Methode ist dafür zuständig,den Wert von $constum in einen binären Wert umzuwandeln und im Falle eines positivenbooleans das 2er-Komplement dieser zu bilden. Dieses dient dazu die negative Zahldarzustellen.Danach wird wahlweise der Code in die hexedazimale Darstellung gewandelt und in denSpeicher eingetragen.Die anderen Fälle führen spezifische Aktionen durch, um den jeweiligen richtigen Codezu erhalten. Falls zum Beispiel eine Konstante mit Hilfe eines Labels geladen werden soll,wird das Label in der Tabelle nachgesehen und der zutreffende Wert zurückgeliefert.

29

Page 39: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

Ein weiterer wichtiger Bereich sind die Prozessordirektiven. Hier soll nur die Direktive.org und deren Aktionen näher betrachtet werden.

1 org :2 ( ’ . org ’ | ’ .ORG’ ) ( constnum=(DIGIT | NUMBER) |3 consthex=HEXNUMBER )4 { i f ( $constnum . text != null ) {5 for ( int i = adre s s ; i < In t eg e r . pa r s e In t ( $constnum . text

) ; i++){6 i f ( P r e f e r enc e s . hexa == true )7 I n s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

opCodeToHex( I n s t r u c t i onS e t . getOpCode ( "ALL_OFFSET" ) ) ;

8 else9 I n s t r u c t i onS e t .memory [ adre s s ] = In s t r u c t i onS e t .

getOpCode ( "ALL_OFFSET" ) ;10 adre s s++;11 }12 adre s s = In t eg e r . pa r s e In t ( $constnum . text ) ;

Abbildung 3.17.: .org Aktionen Ausschnitt

Wie bereits in Abschnitt 3.3 erwähnt, definiert die .org Direktive die neue Speicherstelle,an der die zukünftigen Befehle abgelegt werden sollen. Um dieses zu erreichen, gab eszwei denkbare Möglichkeiten:

1. Einen OPCode festlegen und zusammen mit einer Konstanten in den Speicherschreiben

2. Den Speicher mit Nullen auffüllen

Der Vorteil der ersten Variante ist der geringe Speicherbedarf bei einem .org Befehl. Eswerden unabhängig zur Größe der Konstanten nur zwei Speicherstellen benötigt.

30

Page 40: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

3.5 Design-Entscheidungen

Der große und entscheidende Nachteil ist jedoch, dass sich mit dieser Variante einigeneue Probleme ergeben:

• Konstanten nach der Direktive liegen an falschen Adressen

• Labels werden falschen Adressen zugeordnet

• Der neue OPCode muss im Prozessor realisiert und verarbeitet werden

• Probleme beim Aufbau der Befehlstabelle und dadurch im Debugger

Aufgrund dieser Nachteile wurde die zweite Variante gewählt. Diese wurde auch zuvorvon Andre Hertwig [3] benutzt und bietet den Vorteil, dass diese einfach zu implemen-tieren ist und die oben genannten Nachteile eliminiert. Als Nachteil sei der Platzbedarfzu erwähnen:

.org 200

beschreibt den Speicher 200 Stellen lang mit Nullen, was bei einer größeren Zahl einensehr hohen Speicherbedarf bedeuten kann.Die in Abbildung 3.17 zu sehende for-Schleife in Zeile 5 dient dem Auffüllen des Spei-chers mit dem OPCode für ALL_OFFSET, welcher als 0 definiert ist. Danach wird inZeile 12 die aktuelle Adresse angepasst, womit die .org Aktionen abgeschlossen sind unddie Interpretation der Direktive sinngemäß ausgeführt wurde.

Nachdem in diesem Kapitel der Assembler-Compiler/-Debugger in seiner Funktionsweiseund dessen Implementation beschrieben wurde, soll das folgende Kapitel die Anwendungselbst erklären. Es wird auf den Aufbau, Aussehen und Verwendung der Anwendungeingegangen, welche der Benutzer letzendlich im Hardwarepraktikum für Versuche ver-wendet.

31

Page 41: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4. Benutzeroberfläche

In diesem Kapitel soll auf die oberste Schicht des Programms, der textuellen oder gra-fischen Benutzeroberfläche, eingegangen werden. Den Aufbau oder die Funktionen be-treffend, sollen auch die Motivationen für bestimmte Entscheidungen dargelegt werden.Um dieses zu erreichen wird erst eine kurze Einleitung zu dem Programm gegeben undanschließend wird kurz auf die Konsolenvariante des Programms eingegangen. Darauf-hin wird die grafische Oberfläche detailliert beleuchtet und erklärt. Abschließend solleneinige Implementations Details diskutiert werden.

4.1. Einleitung

Um die zuvor erläuterten Funktionen für den Anwender benutzbar zu machen, benötigtdas Programm eine Oberfläche. Diese sollte intuitiv, übersichtlich und stimmig sein, zu-dem soll sie alle Funktionen der unteren Schichten benutzbar machen. Dieses wurde imAssembler-Compiler/-Debugger und Memory-Viewer mit Hilfe von Java Swing realisiertund soll in den folgenden Abschnitten näher erläutert werden.Zusätzlich zu der grafischen Oberfläche wurde eine Konsolenversion des Programms ein-gebaut, falls der Anwender keine Oberfläche starten kann. Diese wird zuerst näher be-handelt.

4.2. Konsolenversion

Das Programm bietet die Möglichkeit, auch ohne eine vorhandene grafische Oberfläche,die Grundfunktionen auszuführen. Diese Funktionen umfassen:

32

Page 42: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.2 Konsolenversion

Abbildung 4.1.: Startbildschirm der Konsolenversion

Die Wahl der angebotenen Grundfunktionen wurde dadurch bedingt, dass das Programmmöglichst wenig Abhängigkeiten benötigen sollte. Dieses wird zum einen durch die feh-lende grafische Oberfläche und zum anderen durch die fehlende Möglichkeit der Über-tragung erreicht.Der Gedanke hinter dieser Konsolenversion war, dass der jeweilige Anwender an mög-lichst vielen Computern mit Hilfe eines externen Editors geschriebene Assemblerpro-gramme kompilieren und testen kann. Da dieses Programm hauptsächlich für Studentendes Hardwarepraktikums konzipiert wurde, kann man sich folgendes Szenario vorstellen:Der Student entwickelt in Heimarbeit ein Assemblerprogramm und möchte dessen syn-taktische und semantische Richtigkeit auf seinem Heimrechner überprüfen, bevor er die-ses mit in die Labore des Instituts[?] zum Übertragen auf den FPGA nimmt. Er kanndieses auch tun, falls er keine grafische Oberfläche zur Verfügung hat. Nachdem er nachmehreren Iterationen das Programm syntaktisch kontrolliert hat, kann er das Debuggingstarten und auch die semantische Richtigkeit überprüfen. Nach dieser Aktion kann erdas Programm direkt in den Laboren auf dem FPGA testen, um endgültige Ergebnissezu erhalten.

Die Konsolenversion wird gestartet, indem man an die auszuführende *.jar ein -c oder ein–console anhängt. Nach dem Ausführen wird der Anwender von einer Auswahl der mög-lichen Aktionen begrüßt.1 Der Benutzer muss dann die enstprechende Nummer eingebenund mit der Enter Taste bestätigen. Daraufhin benötigt das Programm den Dateinamender Quelldatei, also eines Assemblerprogramms (*.asm).Nach der Wahl jeder Aktion kann sich der Benutzer zwischen der hexadezimalen oderder dezimalen Darstellung für die Debugger entscheiden.

1Siehe Abbildung 4.1

33

Page 43: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.2 Konsolenversion

4.2.1. Kompilieren

Hat der Benutzer das Kompilieren gewählt, wird die Datei kompiliert und eine Spei-cherdatei (*.mem) erstellt. Falls syntaktische Fehler im Assemblerprogramm vorhandensind, werden diese in der Konsole angezeigt.

4.2.2. Komplettes Debugging

Wurde vom Benutzer das komplette Debugging gewählt, wird die *.asm Datei kompiliertund anschliessend komplett vom Debugger ausgeführt. Der Debugger simuliert, wie inKapitel 2 erläutert, den Prozessor und führt die entsprechenden Aktionen des Assemb-lerprogramms aus. Das Ergebnis dieser Ausführung wird in eine Debugging-Datei (*.dbg)geschrieben. Diese Lösung wurde gewählt, so dass der Anwender nach der Ausführungmit einem Texteditor seiner Wahl diese Debugging-Datei öffnen und die enstprechendenErgebnisse begutachten kann.Ein Assemblerbefehl im Debugger besteht immer aus drei Teilen:

1. Ausgeführter Befehl

2. Register- und Befehlszählerinhalte2

3. Veränderte Speicherstellen

2Nach dem ausgeführten Befehl

34

Page 44: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.2 Konsolenversion

Die folgende Abbildung zeigt einen Ausschnitt einer solchen *.dbg Datei:

Abbildung 4.2.: Ausschnitt des Debuggers

In diesem Ausschnitt sind zwei ausgeführte Assemblerbefehle zu sehen. Es soll der zweiteBefehl näher betrachtet werden:Dies ist der Subtraktions-Befehl, welcher zwei Register voneinander subtrahiert, hiersind dies r2 und r5. Das Ergebnis wird in Register 4 geschrieben. Der Debugger zeigtden Status der Register und des Befehlszählers nach dem Befehl an.Wie man sehen kann wurde die Subtraktion

209− 200 = 9

durchgeführt und das Ergebnis in r4 geschrieben. Der Befehlszähler wurde nach der Sub-traktion um eins erhöht.Zusätzlich wird der veränderte Speicher angezeigt. Dieser besteht aus der Stelle und demWert an der entsprechenden Stelle. Veränderter Speicher bedeutet, dass ein Befehl aus-geführt wurde, um eine Konstante an eine Stelle im Speicher zu schreiben. Dieses wirdmit Hilfe des registerindirekten store Befehls und der Prozessordirektive .org erreicht.Es werden nur diese Stellen angezeigt, da der Speicher laut Definition 65536 Stellenbesitzt und eine Anzeige des kompletten Speichers in jedem Befehl das gesamte Debug-ging unübersichtlich macht. Nur die genannten Befehle speichern durch den Anwender

35

Page 45: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.2 Konsolenversion

programmiert gezielt Konstanten an bestimmte Speicherstellen und sind damit die in-teressanten Stellen.Um jedoch auch für Debugging Zwecke den gesamten Speicher anschauen zu können,wird eine *.dbg Datei um eine Ausgabe des gesamten Speichers nach der Ausführungerweitert.Dabei sollte auch beachtet werden, dass je nach Assemblerprogramm auch keine Spei-cherstellen verändert und dementsprechend keine Speicherstellen angezeigt werden.In diesem Beispiel wird der Speicher nicht durch den Befehl verändert, sondern wurdebereits zuvor mit den angezeigten Werten beschrieben.Falls in dem Assemblerprogramm ein Breakpoint enthalten ist, hält der Debugger andieser Stelle und wartet auf eine Enter Eingabe des Benutzers:

Abbildung 4.3.: Breakpoint im Debugger

Es werden die aktuellen Inhalte zum Zeitpunkt des Breakpoints angezeigt. Nach derEingabe wird das Ausführen fortgesetzt.

4.2.3. Schrittweises Debugging

Entgegen der zuvor gewählten Variante schreibt das schrittweise Debugging seine Ergeb-nisse nicht in eine Ausgabedatei, sondern gibt diese in der Konsole aus. Der Debuggerführt einen Schritt des Assemblerprogramms aus und zeigt das Ergebnis wie in Abbil-dung 4.2 an. Der Benutzer kann sich daraufhin das Ergebnis ansehen und mit Hilfe derEnter Taste den nächsten Schritt des Assemblercodes ausführen. Der Debugger fügt das

36

Page 46: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

Ergebnis an die Ausgabe an und wartet erneut auf die Eingabe des Benutzers.Mit Hilfe dieser Form des Debuggens können einzelne Schritte und deren Auswirkungengenauer betrachtet werden, wohingegen das gesamte Debugging eher für die Bertrach-tung des Endergebnisses geeignet ist.Beide Varianten bieten die Möglichkeit Ein- und Ausgaben im Assemblerprogramm zuverarbeiten und warten auf entsprechende Eingaben oder liefern entsprechende Ausga-ben.

Wie bereits erwähnt, werden durch diese Konsolenversion nur ein kleiner Teil der Funk-tionen des Assembler-Compilers/-Debuggers und Memory-Viewers abgedeckt. Um demBenutzer eine komfortablere und umfangreichere Oberfläche zu bieten, soll in den folgen-den Abschnitten die grafische Oberfläche der Anwendung, deren Aufbau sowie Funktionerläutert werden.

4.3. Grafische Oberfläche

4.3.1. Aufbau

Die grafische Oberfläche der Anwendung bietet alle Funktionen der unteren Schichtenan:

• Assemblerprogramme erstellen oder editieren und kompilieren

• Assemblerprogramme debuggen (schrittweise oder komplett)

• Speicherdateien an den FPGA übertragen

• Den Speicher des FPGAs beschreiben und auslesen (adress- oder bereichsweise,oder komplett)

• Ein- und Ausgaben des FPGAs verarbeiten und anzeigen

37

Page 47: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

Die Wahl des Layouts und der Reihenfolge der Registerkarten, um diese Funktiona-litäten zu implementieren, ist durch das Anwendungsszenario3 im Hardwarepraktikumbestimmt, was wie folgt definiert werden kann:

Abbildung 4.4.: Flow-Chart des Anwendungsszenarios

3Ein ausführliches Beispiel dazu findet sich im Anhang unter A

38

Page 48: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

Um alle diese Funktionen übersichtlich und intuitiv einzubinden, wurde die Anwendunganhand einer oft vorkommenden Layout-Struktur entworfen:

Abbildung 4.5.: Die Anwendung im Überblick

Der Assembler-Compiler/-Debugger und Memory-Viewer besteht aus einem Hauptfens-ter, welches durch ein Menü und drei Registerkarten ergänzt wird. Dieses wurde sogewählt, da die drei Registerkarten jeweils bestimmte Arbeitsabläufe des Anwenderscharakterisieren, welche im Hauptfenster ausgeführt werden:

Assemblerprogramme editieren und übertragenDer Anwender möchte ein Assemblerprogramm entwerfen und anschließend ohne weite-res Testen auf den FPGA übertragen. Dieses Szenario wird von Registerkarte 1 bedient,in welchem eben diese Aktionen ausgeführt werden können. Zusätzlich werden syntakti-sche Fehler angezeigt, damit der Benutzer diese vor dem Übertragen korrigieren kann.

Assemblerprogramme testenDer Anwender möchte ein entworfenes Assemblerprogramm auf die semantische Rich-tigkeit überprüfen, da er entweder vor der Übertragung an den FPGA solche Fehler

39

Page 49: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

ausschließen möchte, oder aber mit dem Ergebnis nicht zufrieden ist. In Registerkarte 2finden sich die gewünschten Aktionen.

Speicher auslesen oder beschreibenDer Anwender möchte seine Ergebnisse der Berechnungen des Assemblerprogramms imDebugger oder FPGA überprüfen oder Veränderungen im Speicher vornehmen, um be-stimmte andere Fälle testen zu können. Für diese Art der Aktionen ist Registerkarte 3verantwortlich.

In den folgenden Abschnitten soll auf die einzelnen Module und Bereiche der Oberflä-che im Detail eingegangen werden. Dazu werden die ausführbaren Aktionen und derenKonsequenzen beschrieben. Weiter werden die Intentionen für das jeweilige Layout undDesign zusätzlich dargelegt.

4.3.2. Menü

In diesem Abschnitt soll das Menü in der Anwendung genauer betrachtet werden:

Abbildung 4.6.: Das Menü im Überblick

Wie in vielen Anwendungen werden mehrere Menüpunkte angeboten, die unterschiedli-che Optionen anbieten und jeweilige Aktionen ausführen. In den folgenden Abschnittensollen die einzelnen vier Menüpunkte und ihre Eigenschaften hervorgehoben werden.

40

Page 50: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

4.3.2.1. Datei

Abbildung 4.7.: Das Datei Menü

Dieses Menü bietet Dateioperationen und die Möglichkeit, Einstellungen vorzunehmen,an. Es besteht aus folgenden Komponenten:

1 Neue DateiEs wird ein neues Assemblerprogramm erstellt und mittels Dialog wird nach einem freiwählbaren Namen für die Datei gefragt. Anschließend kann die neue Datei im Editorbearbeitet werden.

2 Datei öffnenEs wird ein Assemblerprogramm geöffnet und mittels Dialog wird nach der Quelldateigefragt. Anschließend ist der Inhalt der Datei im Editor sichtbar und kann bearbeitetwerden.

3 Datei speichernDas geöffnete Assemblerprogramm wird gespeichert.

4 Datei speichern unterDer Inhalt des Editors wird auf die Festplatte gespeichert. Der Speicherort und der Na-me der zu erstellenden Datei wird mittels Dialog erfragt.

5 HTML exportierenEs werden ausgewertete HTML-Dateien (Tabellen) auf der Festplatte gespeichert. DerSpeicherort der HTML-Dateien wird mit einem Dialog erfragt. Gespeichert wird dabeizum einen eine Übersicht des veränderten Speichers in tabellarischer Form, und zum

41

Page 51: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

anderen die Ergebnisse des durchgeführten Debuggers in tabellarischer Form4. Diesesentspricht dem grafisch aufgearbeiteten Gegenstück zu der Debug Datei aus Abschnitt4.2.2.

6 EinstellungenDie Einstellungen des Programms können hier verändert werden, welche aus folgendenOptionen bestehen:

• Die Übertragungsgeschwindigkeit zum FPGA

• Die Schnittstelle für die Übertragung

• Die Befehlsrepräsentation in der Speicherdatei

Mit einem Klick auf OK werden die Änderungen gespeichert oder mit Abbrechen ver-worfen.

7 Programm beendenÜber diesen Menüpunkt wird das Programm nach einem erneuten Dialog beendet. AlleÄnderungen gehen dadurch verloren, falls diese nicht gespeichert wurden.

4.3.2.2. Bearbeiten

Abbildung 4.8.: Das Bearbeiten Menü

Diese Menü bietet Editieroperationen an, welche im Assembler Editor verwendet werdenkönnen. Außerhalb des Editors ist dieses Menü deaktiviert.

4Siehe dazu auch Abschnitt 4.3.4

42

Page 52: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

1 RückgängigMacht die letzte Aktion im Editor rückgängig.

2 WiederholenWiederholt die letzte rückgängig gemachte Aktion im Editor.

3 AusschneidenSchneidet den gewählten Text im Editor aus.

4 KopierenKopiert den gewählten Text im Editor in die Zwischenablage.

5 EinfügenFügt den kopierten oder ausgeschnittenen Text in der Zwischenablage in den Editor ein.

6 LöschenLöscht den gewählten Text im Editor.

7 Alles markierenMarkiert den gesamten Inhalt des Editors.

4.3.2.3. Sprache

Abbildung 4.9.: Das Sprachen Menü

Diese Menü bietet die Auswahl der Sprache an, wodurch die folgenden beiden Menü-punkte resultieren:

1 DeutschÄndert die Anwendungssprache auf Deutsch.

43

Page 53: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

2 EnglischÄndert die Anwendungssprache auf Englisch.

4.3.2.4. Hilfe

Abbildung 4.10.: Das Hilfe Menü

Diese Menü bietet dem Anwender Hilfe und Informationen mit folgenden Menüpunktenan:

1 HandbuchÖffnet das Handbuch und bietet dem Anwender Informationen zur Verwendung der An-wendung.

2 EinführungMit einem Klick auf diesen Menüpunkt wird dem Benutzer mit Hilfe eines Anwendungs-szenarios die Benutzung des Assembler-Compilers/-Debuggers und Memory-Viewers nä-her gebracht5.

3 Über dieses ProgrammZeigt Informationen zum Programm an.

5Diese findet sich auch im Anhang unter A

44

Page 54: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

4.3.3. Assembler Editor

Abbildung 4.11.: Der Reiter Assembler Editor

Der Assembler Editor ist die erste Registerkarte und auch die gewählte beim Anwen-dungsstart. Der Grund dafür liegt in der bereits in Abbildung 4.4 erläuterten Arbeits-reihenfolge eines Anwenders.Um alle Möglichkeiten dieses Reiters zu erläutern, sollen seine Komponenten einzelndbetrachtet werden:

1 EditorDer Editor dient zur Eingabe und zur Darstellung eines Assemblerprogramms. Wennein Assemblerprogramm geladen wird, erscheint es im Editor. In diesem kann der Codebearbeitet werden. Zusätzlich wird die aktuelle Zeilennummer am linken Rand ange-zeigt. Falls ein syntaktischer Fehler beim Kompilieren erkannt wird, kann die Stelleanhand dieser Nummer identifiziert werden. Im Editor sind auch die zuvor genanntenEditieroperationen6 verfügbar, um dem Anwender eine leichtere Bedienbarkeit zu bieten.

6Siehe Abschnitt 4.3.2.2

45

Page 55: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

2 KonsoleDer zweite größere Teil des Reiters ist die Konsole. Diese liefert Ausgaben, falls der imEditor vorhandene Code kompiliert wird. Hier tauchen sowohl Erfolgs- als auch Fehler-meldungen auf. In Abbildung 4.11 sind beide Arten vorhanden, wobei bei einem syntak-tischen Fehler zusätzlich die Zeile und Spalte des Fehlers und der Grund angezeigt wird.

3 KompilierenMit einem Druck auf diesen Knopf wird das im Editor befindliche Assemblerprogrammkompiliert und in eine Speicherdatei geschrieben (*.mem). Dies ist die Anbindung anden Compiler, der in Kapitel 3 erläutert wurde.

4 DebuggenDieser Knopf startet den Debug Vorgang und wechselt zum zweiten Reiter, dem Assem-bler Debugger. Als Eingabe für den Debugger wird der kompilierte Inhalt des Editorsbenutzt. Dies ist die Anbindung an den Debugger, der in Kapitel 3 erläutert wurde.

5 Datei sendenNach einem Druck auf diesen Knopf wird eine Speicherdatei an den FPGA gesendet.Dabei wird die Speicherdatei über einen Dialog erfragt. Somit muss für diese Funktionerst der Assembler Editor Inhalt kompiliert und in eine solche *.mem Datei geschriebenwerden, damit Sie in diesem Schritt ausgewählt werden kann.Dieses ist die erste Anbindung an das von Simon Hardt[5] entworfene RS232-Modul7, dadie Datei über diese Schnittstelle an den FPGA gesendet wird. Die Schnittstelle sowiederen Geschwindigkeit kann über den zuvor beschriebenen Menüpunkt Einstellungenvariiert werden.

7Siehe Abbildung 2.1

46

Page 56: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

4.3.4. Assembler Debugger

Abbildung 4.12.: Der Reiter Assembler Debugger

In diesem Reiter kann ein Assemblerprogramm auf semantische Fehler überprüft wer-den. In der Konsolenversion war dies auch möglich, jedoch bietet die grafische Oberflächemehr Übersicht und ist benutzerfreundlicher.Man gelangt auf diesen Reiter durch einen Klick auf diesen oder aber durch das Drückenauf Debuggen im Reiter des Assembler Editors. Der Reiter, und somit der Debugger, istdeaktiviert, solange das im Editor befindliche Assemblerprogramm nicht durch einenDruck auf den genannten Debuggen Knopf für das Debuggen vorbereitet wurde. DieseVorbereitung kompiliert das Assemblerprogramm und macht es somit im Debugger nutz-bar. Falls im Editor syntaktische Fehler auftauchen, bleibt der Reiter bis zur Behebungdieser deaktiviert.Alle in diesem Reiter befindlichen Informationen werden in HTML Tabellen angezeigt,wodurch auch der Export dieser als Operation angeboten wird.8.

8Siehe Abschnitt 4.3.2.1

47

Page 57: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

Der Assembler Debugger wird durch folgende Komponenenten realisiert:

1 ProgrammausführungDiese Komponente zeigt den aktuellen Status des Debuggers an, der aus den bereits inAbschnitt 4.2.2 erläuterten Informationen besteht:

• Der aktuelle Befehl

• Registerinhalte

• Befehlszähler

Eine Zeile in der Tabelle enstpricht einem Zustand der Ausführung, welcher aus denoben genannten Informationen besteht. Erneut ist zu erwähnen, dass der Status nachdem aktuellen Befehl angezeigt wird.

2 Veränderter SpeicherAuf der rechten Seite findet sich der veränderte Speicher9 und dessen Wert. Im Ge-gensatz zu der Statusanzeige des Debuggers ist hier nur der letzte Schritt zu sehen, imDebugger kann die gesamte Ausführungskette und deren Auswirkung betrachtet werden.

3 DarstellungIn diesem Feld kann zwischen den angebotenen Darstellungsformen hexadezimal sowiedezimal gewählt werden. Die Darstellung wird nach der nächsten Aktion (siehe dazu diefolgenden Abschnitte) in dem Debugger Status und im veränderten Speicher angepasst.Die hexadezimale Darstellung wurde aufgrund der Übersichtlichkeit gewählt, die dezi-male aufgrund der besseren Lesbarkeit gewählt. Eine binäre Variante war nach Testsaufgrund ihrer Unübersichtlichkeit entfernt worden.

4 NeustartMit Hilfe dieses Knopfes wird der gesamte Status des Debuggers, inklusive der Anzeigen,zurückgesetzt. Anschließend wird der Debugger neu gestartet, wodurch das im Editorbefindliche Assemblerprogramm neu kompiliert wird.

9Siehe Abschnitt 4.2.2

48

Page 58: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

5 1 SchrittEs wird ein Schritt des Assemblerprogramms im Debugger ausgeführt und der neueStatus in 1 und 2 angezeigt. Dieses entspricht dem schrittweisen Debuggen in der Kon-solenversion.

6 10 SchritteEs werden zehn Schritte des Assemblerprogramms im Debugger ausgeführt und der neueStatus in 1 und 2 angezeigt. Falls ein Breakpoint innerhalb dieser zehn Schritte auftaucht,wird die Ausführung an dieser Stelle abgebrochen und der aktuelle Status angezeigt.

7 Komplett ausführenMit einem Druck auf diesen Knopf wird das komplette Assemblerprogramm ausgeführtund die Statusanzeigen entsprechend mit den Ergebnissen befüllt. Falls ein Breakpointinnerhalb der Ausführung auftaucht, wird die Ausführung an dieser Stelle abgebrochenund der aktuelle Status angezeigt. Dies entspricht dem kompletten Debuggen in derKonsolenversion.

Alle Ausführungsaktionen zeigen bei Ein- und Ausgaben enstprechende Dialoge des De-buggers an, wie in Abbildung 4.12 zu sehen. Diese können hexadezimal oder dezimalein- und ausgegeben werden. Zusätzlich wird beim Vorkommen eines halt Befehls dieAusführung angehalten sowie eine Meldung und der enstprechende Status ausgegeben.Bei dem Vorkommen eines Breakpoints wird dieser in dem Status des Debuggers anenstprechender Stelle eingefügt, damit der Benutzer nach dem Exportieren der HTMLDateien auch zu späteren Zeitpunkten sehen kann, an welcher Stelle dieser vorkam.

49

Page 59: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

4.3.5. Memory-Viewer

Abbildung 4.13.: Der Reiter Memory-Viewer

Im letzten Reiter wird zum ersten Mal der Memory-Viewer der Anwendung realisiert.Hier kann der Speicher des Debuggers oder des FPGAs gelesen und beschrieben werden.Der Inhalt des Speichers wird in einer Tabelle in dezimaler und hexadezimaler Formdargestellt.Der Anwender kann dadurch den Speicher und somit, je nach Assemblerprogramm, dieberechneten Ergebnisse auslesen und bewerten.Falls keine Ausgaben im Assemblerprogramm enthalten sind, und die Ergebnisse nichtin den Registern gespeichtert sind, ist dies die einzige Möglichkeit, das Ergebnis derBerechnungen zu erhalten.Der Memory-Viewer benutzt zur Übertragung und Kommunikation mit dem FGPA dasvon Simon Hardt implementierte RS232 - Modul. Für mehr Informationen zu diesem seierneut auf [5] verwiesen. Mit Hilfe der folgenden Komponenten kann der Anwender dieentsprechenden Aktionen durchführen:

50

Page 60: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

1 Memory-ViewerIn diesem Teil des Reiters werden die Inhalte des Speichers der ausgewählten Quelleangezeigt. Die ersten beiden Spalten zeigen die hexadezimale Adresse und Wert desSpeichers an, wohingegen die folgenden beiden Spalten die entsprechenden dezimalenWerte anzeigt. Die letzte Spalte dient als Eingabemöglichkeit für den Benutzer. Dortkann der neue dezimale Wert an der entsprechenden Speicherstelle eingegeben werden.Wenn daraufhin ein Bereich oder der gesamte Speicher geschrieben wird, werden dieenstprechend eingetragenen Werte dafür benutzt.Es sollte noch erwähnt werden dass nur die weißen Felder bearbeitet und dementspre-chend geschrieben werden können. Diese sind beim Debugger auf veränderte Speicher-stellen beschränkt10, wohingegen der FPGA keine Beschränkungen der veränderbarenStellen besitzt.

2 QuellenauswahlHier kann zwischen dem Debugger und dem FPGA als Quelle für den Memory-Viewergewählt werden.

3 Komplett lesenMit einem Klick auf diesen Knopf wird der gesamte Speicher der gewählten Quelle aus-gelesen und im Memory-Viewer ausgegeben.Es sollte beachtet werden, dass dies im Falle des FPGAs aufgrund der 65536 Speicher-stellen und der Verwendung der RS232 Schnittstelle länger dauern kann.

4 NeustartUm in Verwendung mit einem FPGA die Bedienung so komfortabel wie möglich zugestalten, bietet dieser Knopf die Möglichkeit den FPGA mit Hilfe eines gesendetenKommandos neu zu starten. Bei der Verwendung des Debuggers als Quelle wird dieserneu gestartet, was der Funktionalität des Neustarts aus Abschnitt 4.3.4 enstpricht. Nachdem Neustart werden alle Anzeigen zurückgesetzt.

5 Komplett schreibenMit einem Klick auf diesen Knopf wird der gesamte Speicher der gewählten Quelle mitden Werten der letzten Spalte beschrieben.Es sollte beachtet werden, dass dieses im Falle des FPGAs aufgrund der 65536 Speicher-

10Siehe Abschnitt 4.2.2

51

Page 61: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

stellen und der Verwendung der RS232 Schnittstelle länger dauern kann.Die Anzeige im Memory-Viewer wird nicht aktualisiert, so dass nach einem Schreibenein erneutes Auslesen nötig ist, um die aktuellen Inhalte des Speichers angezeigt zu be-kommen.

6 Bereich lesenMit einem Klick auf diesen Knopf wird ein Bereich des Speichers der gewählten Quelleausgelesen und im Memory-Viewer ausgegeben. Die Start- und Endadresse des Bereichswird über einen Dialog erfragt.Je nach Bereichsgröße sollte beachtet werden, dass dieses im Falle des FPGAs aufgrundder 65536 Speicherstellen und der Verwendung der RS232 Schnittstelle länger dauernkann.

7 Bereich schreibenMit einem Klick auf diesen Knopf wird ein Bereich des Speichers der gewählten Quellemit den Werten der letzten Spalte beschrieben. Die Start- und Endadresse des Bereichswird über einen Dialog erfragt.Je nach Bereichsgröße sollte beachtet werden, dass dieses im Falle des FPGAs aufgrundder 65536 Speicherstellen und der Verwendung der RS232 Schnittstelle länger dauernkann.Die Anzeige im Memory-Viewer wird nicht aktualisiert, so dass nach einem Schreibenein erneutes Auslesen nötig ist, um die aktuellen Inhalte des Speichers angezeigt zu be-kommen.

8 Adresse lesenMit einem Klick auf diesen Knopf wird eine Adresse des Speichers der gewählten Quelleausgelesen und mit einem Ausgabedialog ausgegeben. Die zu lesende Adresse wird übereinen Dialog erfragt. Die Eingabe kann hexadezimal oder dezimal erfolgen.

9 Adresse schreibenMit einem Klick auf diesen Knopf wird eine Adresse des Speichers der gewählten Quellebeschrieben. Die zu schreibende Adresse und Wert werden über einen Dialog erfragt.Die Eingabe kann hexadezimal oder dezimal erfolgen.

52

Page 62: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

4.3.6. Ein- und Ausgabe

Reiterübergreifend bietet der Assembler-Compiler/-Debugger und Memory-Viewer dieMöglichkeit, die Ein- und Ausgaben des FPGAs zu verarbeiten. Mit Hilfe des RS232 -Moduls sendet der FPGA ein entsprechendes Signal, so dass der entsprechende Ein- bzwAusgabedialog angezeigt wird, welcher entsprechend vom Anwender beantwortet wird.Die Eingaben können hexadezimal oder dezimal vorgenommen werden und mit einemKlick auf OK startet der Sendevorgang an den FPGA.

4.3.7. Design-Entscheidungen

Während dem Entwurf der grafischen Oberfläche gab es einige zu treffende Design-Entscheidungen:

1. Fehlerausgabe beim Kompilieren

2. Darstellung des Debuggers

3. Visualisierung des Speichers

In den folgenden Abschnitten soll aufgezeigt werden, welche Gedanken hinter diesenEntscheidungen stehen und wie die entsprechenden Lösungen umgesetzt wurden.

Fehlerausgabe beim KompilierenUm dem Benutzer eine komfortable Möglichkeit zur Fehlersuche zu bieten, sollte bei ei-nem Syntax bedingten Fehler während dem Kompilieren die Stelle des Fehlers angezeigtwerden. Dieses wird von ANTLR[7] durch eine Exception Behandlung bereits abgedecktund liefert die Zeile, Spalte und den Grund des Fehlers. Die Ausgabe erfolgt auf derStandardausgabe. Wie bereits erwähnt, wurde der Assembler-Compiler/-Debugger undMemory-Viewer sowohl auf der Konsole als auch in einer grafische Oberfläche reali-siert. Aus diesem Grund konnten die entsprechenden Methoden nicht für eine grafischeAusgabe umgeschrieben werden, da die Konsolenversion dann ohne eine Fehlerausgabeauskommen müsste.

53

Page 63: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

4.3 Grafische Oberfläche

Um beide Arten der Anwendung gleichermaßen nutzbar und umfangreich zu realisieren,wurde die Klasse GuiConsole entwickelt, welche jegliche Standard- und Fehlerausgabeabfängt und in einem Textfeld ausgibt. Diese ist in der Abbildung 4.11 unter Punkt 2zu sehen.Durch diese Lösung konnte die Methode für die Fehlerausgabe im Compiler unange-tastet bleiben und beide Versionen der Anwendung bieten trotzdem den Komfort derFehlersuche.

Darstellung des DebuggersDer Debugger soll alle nötigen Funktionen bieten und dennoch nicht an Übersicht ver-lieren. Um dieses zu realisieren, bot sich eine Tabellenstruktur an, welche den aktuellenStatus des Debuggers anzeigt.Da die Konsolenversion vor der grafischen Oberfläche enstand war bereits die Idee füreine Ausgabe des Debuggers in eine Datei11 vorhanden. Um dieses in der grafischenOberfläche realisieren zu können, fiel die Wahl auf HTML Tabellen.Die Gründe für die Wahl von HTML sind:

• Reine Ausgabe, keine Editieroperationen des Anwenders

• Konkatenierbar

• Exportmöglichkeit

• Von jedem Browser interpretierbar

Aus diesem Grund wurden HTML Tabellen als Debugger Darstellung gewählt.

Visualisierung des SpeichersIm Gegensatz zum Debugger benötigt der Memory-Viewer die Möglichkeit, Inhalte zueditieren. Zusätzlich muss die Darstellung eine feldweise Adressierung für das spätereLesen und Schreiben anbieten.Aus diesem Grund konnten keine HTML Tabellen genutzt werden, um den Speicher zuvisualisieren. Die Wahl fiel auf die Klasse JTable, welche alle genannten Operationenund Möglichkeiten anbietet. Über diesen Weg war es möglich, den Speicher übersichtlichund funktional darzustellen.

11Siehe Abschnitt 4.2.2

54

Page 64: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

5. Zusammenfassung und Ausblick

Im Rahmen dieser Bachelorarbeit wurde die Anwendung Assembler-Compiler/-Debuggerund Memory-Viewer entwickelt. Diese dient als Schnittstelle für die Studenten des Hard-warepraktikums zwischen der Assemblerprogrammierung und des entworfenen Prozessorsauf einem FPGA. Die Anwendung wurde an Anlehnung an die beiden zuvor verwende-ten Programme Assemblercompiler von Andre Hertwig [3] und dem Assembler- undMemoryviewer von Carsten Giersbach entwickelt. Durch Praxiserfahrungen erschienendiese weder durch Funktionsumfang, Stabilität, Kompatibilität noch durch Erweiterbar-keit ausreichend. Der Assembler-Compiler/-Debugger und Memory-Viewer entstand alsNeuentwicklung dieser und bietet folgende Möglichkeiten:

• Entwerfen, Laden und Speichern von Assemblerprogrammen

• Kompilieren von Assemblerprogrammen

• Debuggen von Assemblerprogrammen direkt im Programm

• Unterstützung mehrerer Betriebssysteme

• Kommunikation mit einem angeschlossenen FPGA

• Lesen, Schreiben sowie Visualisieren des Speichers vom FPGA

Dies wurde durch eine Entwicklung in der Programmiersprache Java[6] mithilfe der Um-gebung ANTLR[7] realisiert. Der Anwender hat die Wahl zwischen einer Konsolen- undeiner grafischen Variante der Anwendung. Die Konsolenvariante dient zur reinen Bear-beitung, Kompilierung und Fehlersuche in Assemblerprogrammen und bietet die erstenvier Punkte der oben genannten Möglichkeiten. Die grafische Version, welche in JavaSwing realisiert wurde, bietet alle genannten Funktionen.

55

Page 65: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

In dieser Bachelorarbeit wurde die Entwicklung der Anwendung detailliert beleuchtet,indem zuerst die Ausgangslage und entsprechenden Anforderungen an die Anwendungerläutert wurden. Es folgte eine umfangreiche Erklärung des Quellcodes anhand von Bei-spielen, Design-Entscheidungen und Problemfällen. Schließlich wurde die Anwendungselber und deren Aufbau sowie Funktionsweise beschrieben.

Der Assembler-Compiler/-Debugger und Memory-Viewer bietet alle Funktionalität, dieim Hardwarepraktikum von den Studenten zur Zeit benötigt wird. Durch eine Erweite-rung oder Umgestaltung des Praktikums ergeben sich in Zukunft einige denkbare mögli-che Verbesserungen, die mit unterschiedlich viel Aufwand implementiert werden könnten.

Eine mögliche Erweiterung könnte das Anbinden eines Universal Serial Bus (USB) -Moduls sein. Zur Zeit bietet die Anwendung nur die Möglichkeit, die Kommunikationmit einem FPGA über die serielle Schnittstelle vorzunehmen. Diese hat im Gegensatzzu USB erhebliche Geschwindigkeitseinbuße und bietet nicht die Plug and Play Mög-lichkeiten des USB Anschlusses.Um dies zu realisieren, muss lediglich ein USB - Modul entworfen und in die Zugriffs-schicht eingebunden werden. Auf der hardwarenahen Seite müssen zur Kommunikationauch die entsprechenden Änderungen vorgenommen werden.

Als zweite mögliche Erweiterung ist die Ansteuerung von Sensoren oder Aktoren desFPGAs denkbar. Zurzeit beschränkt sich die Kommunikation auf das Neustarten desFPGAs sowie dessen Speicheroperationen. In diesem Zuge kann die grafische Oberflä-che erweitert werden und die neu benutzten Elemente anzeigen. Beispielhaft könnte die7-Segment Anzeige oder LEDs zusätzlich in der Oberfläche angezeigt und Operationenwie das Ändern dieser angeboten, oder aber eine Temperaturmessung mit Hilfe einesentsprechenden Sensors durchgeführt werden.Zur Realisierung dieser Erweiterung muss lediglich die grafische Oberfläche erweitertund entsprechende Signale in der Hardwareseite implementiert werden.

Bei diesen Erweiterungen zeigt sich erneut der Vorteil der Kapselung, da nur die je-weiligen Klassen und Methoden angepasst werden müssen, der Rest der Anwendungkann ohne Änderungen auskommen.

56

Page 66: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Anwendungsszenario für die in dieser Bachelorarbeit entwickelten AnwendungAssembler-Compiler/-Debugger und Memory-Viewer. Es wird ein kompletter denkbarer Arbeitsab-lauf für das Hardwarepraktikum durchgeführt, und so bei der Benutzung des Programmsgeholfen. Dazu wird schrittweise auf die benutzten Teile des Programms eingegangen,und versucht, den Arbeitsschritt zu erläutern.

57

Page 67: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Starten eines Arbeitsablaufs - Editor(Schritt 1)

Wir starten im Fenster Assembler Editor 1 und können hier ein Assembler Programmschreiben. Ob wir ein bereits gespeichertes Programm laden oder ein neues im Editorentwerfen, bleibt uns überlassen. Nachdem wir den Assembler Quellcode fertig editierthaben, können wir uns zwischen dem Kompilieren 3 und dem Debuggen 4 entscheiden.Wir entscheiden uns für das Debuggen 4, um unser Assembler Programm vor dem kom-pilieren und übertragen auf den FPGA auf inhaltliche Richtigkeit zu überprüfen. Dazuklicken wir auf Debuggen 4. Wenn keine syntaktischen Fehler im Assembler Quellcodevorliegen, gelangen wir auf den Reiter Assembler Debugger.

58

Page 68: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Überprüfen der Richtigkeit - Debugger(Schritt 2)

Danach befinden wir uns im Assembler Debugger, in welchem wir unser zuvor erstelltesAssemblerprogramm auf seine Richtigkeit überprüfen. Dazu können wir entweder in 1eroder 10er Schritten durch die Ausführung des Programms laufen, wodurch wir jederzeitden aktuellen Status der Register, des Befehlszählers 1 und des veränderten Speichers2 überprüfen können. Eingaben und Ausgaben werden entsprechend von uns beantwor-tet oder zur Kenntnis genommen. Wenn das Programm den HALT Befehl erreicht hat,erhalten wir eine Meldung und der Debugger hält an. Falls wir mit den Ergebnissenzufrieden sind, ist das Debuggen abgeschlossen und wir gehen zu Schritt 4. Falls je-doch Fehler in den Ergebnissen auftauchen, versuchen wir den Debugger neuzustarten4 und durch Schrittweises durchlaufen den Fehler zu suchen. Haben wir diesen gefun-den wechseln wir auf den Reiter Assembler Editor und der Arbeitsablauf beginnt erneutbei 1. Zusätzlich zu den oben genannten Informationen können wir auch in den ReiterMemory-Viewer wechseln, um den Speicherhinhalt zu überprüfen.

59

Page 69: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Überprüfen des Speicherinhalts(Debugger) - Memory-Viewer(Schritt 3)

Hier befinden wir uns im Memory-Viewer, in welchem wir den Speicherinhalt des De-buggers überprüfen wollen. Dazu klicken wir auf gesamten Speicher auslesen 3, wodurchwir den Speicher des Debuggers angezeigt bekommen. Wir vergleichen die Speicherhin-halte 1 mit den erwarteten Werten und versuchen so Fehler zu finden. Zu weiteren Testskönnen wir die weißen Felder mit neuen Werten füllen und den Speicher damit überdie Knöpfe 5,7,9 beschreiben oder Neustarten über den Knopf 4. Nach diesen Aktionenwollen wir entweder weiter testen, wodurch wir zu Punkt 2 gehen und den Debuggermit den neuen Speicherwerten weiter ausführen, oder aber wir sind zufrieden mit denErgebnissen und gehen zu Schritt 4.

60

Page 70: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Übertragen der Speicherdatei - Editor(Schritt 4)

Nachdem wir den Assemblercode mit Hilfe des Debuggers und Memory-Viewers aufseine Richtigkeit überprüft haben, wollen wir einen FPGA mit diesem Code beschreiben.Dazu wählen wir im Editor Fenster Kompilieren 3, woraufhin eine Speicherdatei mit derEndung *.mem erzeugt wird. Um diese Datei in den Speicher des FGPAs zu übertragen,drücken wir auf den Knopf Datei Senden 5. Ein Dateidialog öffnet sich, in welchem wirdie zuvor erstellte Speicherdatei auswählen. Daraufhin wird diese Datei in den Speicherdes FPGAs geschrieben, und je nach Wahl von uns neugestartet und das Programmim FPGA ausgeführt. Eingaben und Ausgaben des Prozessors werden durch Dialogeabgehandelt.Wenn der FPGA den HALT Status erreicht hat, was durch eine Light-emitting diode(LED) auf dem FPGA angezeigt wird, hat der Prozessor die Ausführung beendet. Umdie Ergebnisse im FPGA zu überprüfen, gehen wir zu Schritt 5.

61

Page 71: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

A. Anhang: Anwendungsszenario

Überprüfen des Speicherinhalts(FPGA) - Memory-Viewer(Schritt 5)

Daraufhin sind wir erneut im Memory-Viewer, diesmal wollen wir jedoch den Speicherdes FPGAs überprüfen. Dazu wählen wir den FPGA in der Quellenauswahl 2 und wäh-len eine entsprechende Aktion 3-9, um den Speicher auszulesen, zu beschreiben oderaber den FPGA neuzustarten. Wenn wir mit den Ergebnissen zufrieden sind, ist derkomplette Arbeitsablauf abgeschlossen und erfolgreich ein Assemblerprogramm erstelltund auf dem FPGA ausgeführt worden. Falls dem nicht so ist, haben wir einen Fehlerim Assemblercode oder beim entsprechenden Prozessorentwurf gemacht und beginnenerneut von vorne.

62

Page 72: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Dies ist die der Anwendung Assembler-Compiler/-Debugger und Memory-Viewer ver-wendete Grammatik. Sie basiert auf der im Hardwarepraktikum definierten Grammatik,um den Studenten eine hardwarenahe Erfahrung zu bieten. Es wird sowohl die EBNF,als auch die grafische Darstellung jedes Musters und jeder Regel aufgelistet.

63

Page 73: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

program

EBNF notation:program ::= line+ EOF

Railroad notation:

line

EBNF notation:line ::= (label? command (SLCOMMENT | MLCOMMENT | NEWLINE) | (SLCOM-MENT | MLCOMMENT) | label (SLCOMMENT | MLCOMMENT | NEWLINE) |NEWLINE)

64

Page 74: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

label

EBNF notation:label ::= (LABEL | BREAKPOINT)

Railroad notation:

command

EBNF notation:command ::= (st | ld | out | in | jmp | jz | jnz | add | sub | and | or | nop | not | sal | sar| org | equ | dw | halt)

65

Page 75: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

st

EBNF notation:st ::= (’st’ | ’ST’) (REGISTER’,’REGISTER | ’(’REGISTER’)”,’REGISTER | REGIS-TER’,”#’ (MINUS (DIGIT | NUMBER) | HEXNUMBER | IDENT))

66

Page 76: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

ld

EBNF notation:ld ::= (’ld’ | ’LD’) (REGISTER’,’REGISTER | REGISTER’,”(’REGISTER’)’ | REGIS-TER’,”#’ (MINUS (DIGIT | NUMBER) | HEXNUMBER | IDENT))

Railroad notation:

out

EBNF notation:out ::= (’out’ | ’OUT’) (REGISTER’,’REGISTER | ’(’REGISTER’)”,’REGISTER | RE-GISTER’,”#’ (MINUS (DIGIT | NUMBER) | HEXNUMBER | IDENT))

67

Page 77: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

in

EBNF notation:in ::= (’in’ | ’IN’) (REGISTER’,’REGISTER | REGISTER’,”(’REGISTER’)’ | REGIS-TER’,”#’ (MINUS (DIGIT | NUMBER) | HEXNUMBER | IDENT))

Railroad notation:

jmp

EBNF notation:jmp ::= (’jmp’ | ’JMP’) (REGISTER | ’#’ ((DIGIT | NUMBER) | HEXNUMBER |IDENT))

68

Page 78: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

jz

EBNF notation:jz ::= (’jz’ | ’JZ’) (REGISTER’,’REGISTER | ’#’ ((DIGIT | NUMBER) | HEXNUM-BER | IDENT) ’,’REGISTER)

Railroad notation:

jnz

EBNF notation:jnz ::= (’jnz’ | ’JNZ’) (REGISTER’,’REGISTER | ’#’ ((DIGIT | NUMBER) | HEX-NUMBER | IDENT) ’,’REGISTER)

69

Page 79: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

add

EBNF notation:add ::= (’add’ | ’ADD’) REGISTER’,’REGISTER’,’REGISTER

Railroad notation:

sub

EBNF notation:sub ::= (’sub’ | ’SUB’) REGISTER’,’REGISTER’,’REGISTER

Railroad notation:

and

EBNF notation:and ::= (’and’ | ’AND’) REGISTER’,’REGISTER’,’REGISTER

70

Page 80: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

or

EBNF notation:or ::= (’or’ | ’OR’) REGISTER’,’REGISTER’,’REGISTER

Railroad notation:

not

EBNF notation:not ::= (’not’ | ’NOT’) REGISTER’,’REGISTER

Railroad notation:

sal

EBNF notation:sal ::= (’sal’ | ’SAL’) REGISTER’,’REGISTER

Railroad notation:

71

Page 81: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

sar

EBNF notation:sar ::= (’sar’ | ’SAR’) REGISTER’,’REGISTER

Railroad notation:

halt

EBNF notation:halt ::= (’halt’ | ’HALT’)

Railroad notation:

nop

EBNF notation:nop ::= (’nop’ | ’NOP’)

Railroad notation:

org

EBNF notation:org ::= (’.org’ | ’.ORG’) ((DIGIT | NUMBER) | HEXNUMBER)

72

Page 82: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

equ

EBNF notation:equ ::= (’.equ’ | ’.EQU’) IDENT (MINUS (DIGIT | NUMBER) | HEXNUMBER)

Railroad notation:

dw

EBNF notation:dw ::= (’.dw’ | ’.DW’) IDENT (MINUS (DIGIT | NUMBER) | HEXNUMBER)

Railroad notation:

MINUS

EBNF notation:MINUS ::= ’-’

73

Page 83: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

DIGIT

EBNF notation:DIGIT ::= ’0..9’

Railroad notation:

HEXDIGIT

EBNF notation:HEXDIGIT ::= ((’A..F’ | ’a..f’) | DIGIT)

Railroad notation:

LETTER

EBNF notation:LETTER ::= (’a..z’ | ’A..Z’)

Railroad notation:

74

Page 84: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

REGISTER

EBNF notation:REGISTER ::= (’r’ | ’R’) ’0..7’

Railroad notation:

CHAR

EBNF notation:CHAR ::= (LETTER | DIGIT | ’_’ | ’$’ | ’#’)

Railroad notation:

IDENT

EBNF notation:IDENT ::= LETTERCHAR*

Railroad notation:

75

Page 85: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

NUMBER

EBNF notation:NUMBER ::= DIGIT+

Railroad notation:

HEXNUMBER

EBNF notation:HEXNUMBER ::= ’0x’HEXDIGIT+

Railroad notation:

LABEL

EBNF notation:LABEL ::= IDENT’:’

Railroad notation:

WHITESPACE

EBNF notation:WHITESPACE ::= (’ ’ | ’\t’ | ’\f’)+

76

Page 86: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

NEWLINE

EBNF notation:NEWLINE ::= (’\n’ | ’\r’)+

Railroad notation:

SLCOMMENT

EBNF notation:SLCOMMENT ::= ’//’ .* NEWLINE

Railroad notation:

MLCOMMENT

EBNF notation:MLCOMMENT ::= ’/*’ .* ’*/’NEWLINE

77

Page 87: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

B. Anhang: Assembler Grammatik

Railroad notation:

BREAKPOINT

EBNF notation:BREAKPOINT ::= ’!BREAK!’

Railroad notation:

78

Page 88: Entwurf eines Assembler-Compilers/-Debuggers und …pi.informatik.uni-siegen.de/dreuling/publications/downloads/...Assembler-Compilers/-Debuggers und ... Die für das Praktikum verwendete

Literaturverzeichnis

[1] Mentor Graphics,http://www.mentor.com/products/fpga/ , (29.04.2011), S. iii

[2] Xilinx Inc.,http://www.xilinx.com , (29.04.2011), S. iii, 24

[3] Hertwig, Andre ; Brück, Rainer: Entwurf digitaler Systeme,Carl Hanser Verlag, 2000 , S. iii, 1, 2, 6, 9, 12, 31, 55

[4] Fachgruppe für Mikrosystementwurf,http://www.uni-siegen.de/fb12/imt_mse/institut/ , (29.04.2011), S. iii

[5] Hardt, Simon: Entwurf eines Speicher- und IO-Interfaces auf einem FPGABachelorarbeit, 2011 , S. iv, 4, 5, 46, 50

[6] Java,http://www.java.com/ , (29.04.2011), S. 3, 55

[7] ANTLR,http://www.antlr.org/ , (29.04.2011)Autor/Entwickler: Terence Parr, S. 3, 5, 53, 55

[8] Aho, Alfred V. : Compilers,Pearson Studium, 2008 , S. 7

[9] Eclipse IDE,http://www.eclipse.org , (29.04.2011), S. 5

79