1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
\documentclass[12pt,a4paper,titlepage,oneside]{article}
\usepackage[utf8]{inputenc}
\usepackage{oop_prot}
\usepackage{url}
\usepackage{pdfpages}
\usepackage{booktabs}
\title{Beispiel 3}
\author{
Günther Neuwirth, \matrnr 0626638\\
{\small e0626638@student.tuwien.ac.at}\\
Manuel Mausz, \matrnr 0728348\\
{\small manuel-tu@mausz.at}\\
}
\begin{document}
% create titlepage
\maketitle
\tableofcontents
\newpage
%------------------------------------------------------------------
%------------------------------------------------------------------
\section{Aufgabenstellung - Beispiel 3}
\includegraphics[width=\textwidth,page=1]{../angabe.pdf}
\includegraphics[width=\textwidth,page=2]{../angabe.pdf}
\includegraphics[width=\textwidth,page=3]{../angabe.pdf}
%------------------------------------------------------------------
%------------------------------------------------------------------
\section{Beispiel 3}
\subsection{Design}\label{Design}
Abbildung~\ref{fig:classdiagram1} zeigt das Klassendiagramm der Aufgabe.
Als Datentyp für Register und Hauptspeicher der CPU wurde ein allgemeines
Template implementiert, welche andere Datentypen oder Klasse umhüllen kann.
Zudem wurden die gängigsten Operatoren definiert, die man sich von einem
Datentyp erwarten kann. Gemäß der Aufgabenstellung wurde der Datentyp CDat als
umhüllter Integer-Wert definiert.
Der Hauptspeicher der CPU wurde als abgeleitetes Template \mbox{CVectorMem} des
Templates \mbox{std::vector<T, Allocator>} implementiert, damit dieses um die
Methode \mbox{initialize} und \mbox{dump} erweitert werden konnten. Erstere
dient zur Initialisierung des Hauptspeichers bzw. Füllung des Vectors,
zweiteres zur Debugausgabe. Der Datentyp CMem wurde via typedef als
\mbox{CVectorMem} mit dem Templateargument CDat definiert. Somit enthält der
Hauptspeicher nur Elemente des Typs CDat.
Die geforderten zwei Display-Klassen \mbox{CDisplayWDEZ} und
\mbox{CDisplayWHEX} wurden von der abstrakten Klasse CDisplay abgeleitet, welche
selbst als Template CDisplayT mit dem Templateargument CDat definiert ist.
Der Programmspeicher \mbox{CProgram} wurde vom Template
\mbox{std::vector<CInstruction *>} abgeleitet. Somit ist diese Klasse, ähnlich
wie CMem, selbst ein Vector. Zudem wurden weitere Methoden hinzugefügt. Die
Methode \mbox{compile} dient zum Kompilieren bzw. Umwandeln des
Syntax der Programmdatei in Instanzen der Klasse CInstruction, die später von
der CPU ausgeführt werden. Zur Umwandlung werden bei der Instantiierung von
\mbox{CProgram} sämtliche erlaubten Instruktionen (also Instanzen von
\mbox{CInstruction}) in ein \mbox{std::set} eingefügt. Im Zuge der Methode
\mbox{compile} wird durch Iterieren die jeweilige Instruktion gesucht und durch
Anwendung des Designpattern \textit{Factory method pattern} die Instruktion
dupliziert und in \mbox{CProgram} gespeichert. Labels werden zwecks Effizienz in
einer \mbox{std::map} festgehalten.
Die jeweiligen unterstützen Instruktionen wurden wie gefordert von der Klasse
\mbox{CInstruction} abgeleitet. \mbox{CInstruction} fordert die
Implementierung einer Methode \mbox{compile}, die während des parsens der
Programmdatei von \mbox{CProgram} aufgerufen werden, als auch eine Methode
\mbox{execute}, die im Zuge der Ausführung des Programms von CCPU
aufgerufen werden.
Die eigentliche CPU wird durch die Klasse \mbox{CCPU} implementiert. Diese
dient hauptsächlich als Container für die einzelnen, notwendigen Teile
(Hauptspeicher, Programmspeicher, Displays, ...) und besitzt daher entsprechend
viele get- und set-Funktionen. Die Methode \mbox{run} dient zur Ausführung des
Programms und ist eine Schleife, die über die Instruktionen iteriert und die
Methode \mbox{execute} aufruft.
%==================================================================
\begin{center}
\begin{figure}[htb]
\epsfxsize=1.6\textwidth\epsfbox{mycpu.png}
\caption{Klassendiagramm 1}
\label{fig:classdiagram1}
\end{figure}
\end{center}
%==================================================================
\subsection{Verwaltung der Ressourcen}
Alle Objekte, die im Konstruktor alloziert werden, werden im Destruktor wieder
freigegeben. Die Objekte, die über die \textit{Factory method pattern}
alloziert werden, werden im Zuge des Destruktor des Vectors bzw.
von \mbox{CProgram} wieder freigegeben.
\subsection{Fehlerbehandlung}
Es wurden keine eigenen Exceptions eingeführt. Statt dessen werden Exceptions
meist in Exceptions des Typs \mbox{std::runtime\_error} umgewandelt. Da die
Hierarchie nicht sehr tief ist, fängt lediglich \mbox{CPropram::compile}
Exceptions des Typs \mbox{std::runtime\_error}, um zusätzliche Information an
den ursprünglichen Aufrufer der Methode weiterzugeben. Dies geschieht ebenfalls
per Exception des Typs \mbox{std::runtime\_error}.
\subsection{Implementierung}
Siehe Punkt~\ref{Design} und Abbildung~\ref{fig:classdiagram1} sowie
Punkt~\ref{Listings}.\\
Es wurde viel mit Templates gearbeitet.
\section{Projektverlauf}
\subsection{Probleme und Fallstricke}
Abgesehen von den mittlerweile üblichen Schwierigkeiten die Angabe bzw.
die Gedanken dessen Verfassers verstehen zu wollen, arbeitete das erste Design
noch vermehrt mit Text. Unter anderem hatte die Methode
\mbox{CInstruction::execute} einen Parameter des Typs \mbox{std::string}, was
zum dazu führte, das die Instruktion bei jeder Aufführung (zum Beispiel durch
Jumps) erneut geparsed werden musste.
\subsection{Arbeitsaufwand}
\begin{tabular}{ll}
\toprule
Entwicklungsschritt / Meilenstein & Arbeitsaufwand\\
\midrule
Erstes Design & 3 Stunden\\
\hline
Implementierung & 3 Tage\\
\hline
Anpassung des Designs und der Implementierung & 4 Stunden\\
\hline
Dokumentation (Doxygen) und Überprüfung aller\\
Anforderungen gemäß der Programmierrichtlinien & 4 Stunden\\
\hline
Erstellung des Protokolls & 3 Stunden\\
\bottomrule
\end{tabular}
%------------------------------------------------------------------
%------------------------------------------------------------------
\newpage
\section{Listings}\label{Listings}
\subsection{mycpu.cpp}
\lstinputlisting{../mycpu/mycpu.cpp}
\newpage
\subsection{cdat.h}
\lstinputlisting{../mycpu/cdat.h}
\newpage
\subsection{cmem.h}
\lstinputlisting{../mycpu/cmem.h}
\newpage
\subsection{cinstruction.h}
\lstinputlisting{../mycpu/cinstruction.h}
\newpage
\subsection{cinstruction.cpp}
\lstinputlisting{../mycpu/cinstruction.cpp}
\newpage
\subsection{instructions.h}
\lstinputlisting{../mycpu/instructions.h}
\newpage
\subsection{instructions.cpp}
\lstinputlisting{../mycpu/instructions.cpp}
\newpage
\subsection{cdisplay.h}
\lstinputlisting{../mycpu/cdisplay.h}
\newpage
\subsection{displays.h}
\lstinputlisting{../mycpu/displays.h}
\newpage
\subsection{cprogram.h}
\lstinputlisting{../mycpu/cprogram.h}
\newpage
\subsection{cprogram.cpp}
\lstinputlisting{../mycpu/cprogram.cpp}
\newpage
\subsection{ccpu.h}
\lstinputlisting{../mycpu/ccpu.h}
\newpage
\subsection{ccpu.cpp}
\lstinputlisting{../mycpu/ccpu.cpp}
\end{document}
|