21 |
\begin{document} |
\begin{document} |
22 |
\DeclareGraphicsExtensions{.pdf,.eps,.png} |
\DeclareGraphicsExtensions{.pdf,.eps,.png} |
23 |
|
|
24 |
\title{\Large{Dokumentacja projektu} \\ \Huge{\textbf{SmArc}} } |
\author{{\large Michał Stochmiałek} % |
25 |
\author{\large{Michał Stochmiałek} % |
{\normalsize{\tt \(<\)misto@pld-linux.org\(>\)}} |
|
\normalsize{\texttt{\(<\)misto@pld-linux.org\(>\)}} |
|
26 |
\and% |
\and% |
27 |
\large{Tomasz Poradowski} % |
{\large Tomasz Poradowski} % |
28 |
\normalsize{\texttt{\(<\)batonik@batonik.net\(>\)}}} |
{\normalsize {\tt \(<\)batonik@batonik.net\(>\)}}} |
29 |
|
\title{{\Large Dokumentacja projektu} \\ \vspace{2mm} {\Huge SmArc} } |
30 |
|
|
31 |
\date{Politechnika Wrocławska, Wrocław, (c) 2002-2003} |
\date{\sf Politechnika Wrocławska, Wrocław, (c) 2002-2003} |
32 |
\maketitle |
\maketitle |
33 |
|
|
34 |
\newcommand{\spasm}{{\it spasm}} |
\newcommand{\spasm}{{\it spasm}} |
41 |
\section{Wstęp} |
\section{Wstęp} |
42 |
\label{sec:wstep} |
\label{sec:wstep} |
43 |
|
|
44 |
Wirtualna maszyna \SmArc\ powstała jako projekt akademicki, mający |
Wirtualna maszyna \SmArc\ powstała jako projekt akademicki, mający na |
45 |
na celu bliższe poznanie architektury oraz sposobu działania procesora |
celu bliższe poznanie architektury oraz sposobu działania procesora |
46 |
SPARC. \SmArc\ (od {\it Small SPARC}) zawiera jego wersję uproszczoną, jednakże |
SPARC. \SmArc\cite{komorowski} (od {\it Small SPARC}) zawiera jego |
47 |
wiernie oddaje ona realia i większość aspektów projektowych oraz |
wersję uproszczoną, jednakże wiernie oddaje ona realia i większość |
48 |
technologicznych zastosowanych w oryginale (więcej informacji w |
aspektów projektowych oraz technologicznych zastosowanych w oryginale |
49 |
specyfikacji SPARCv8\cite{SPARCv8}). |
(więcej informacji w specyfikacji SPARCv8\cite{SPARCv8}). |
50 |
|
|
51 |
|
|
52 |
\section{Elementy \SmArc} |
\section{Elementy \SmArc} |
53 |
\label{sec:elementy} |
\label{sec:elementy} |
54 |
|
|
55 |
W skład pakietu \SmArc\ wchodzą następujące składniki (szczegółowy opis |
W skład pakietu \SmArc\ wchodzą następujące składniki (szczegółowy opis |
56 |
znajduje się w dalszej części): |
znajduje się w~dalszej części): |
57 |
|
|
58 |
\begin{itemize} |
\begin{itemize} |
59 |
\item \vmachine\ - wirtulana maszyna oparta na uproszczonej wersji procesora |
\item \vmachine\ - wirtulana maszyna oparta na uproszczonej wersji procesora |
63 |
\item \despasm\ - deasembler plików wykonywalnych zapisanych w formacie maszyny |
\item \despasm\ - deasembler plików wykonywalnych zapisanych w formacie maszyny |
64 |
wirtualnej \SmArc |
wirtualnej \SmArc |
65 |
\item \smarcgui\ - interfejs graficzny wirtualnej maszyny \SmArc |
\item \smarcgui\ - interfejs graficzny wirtualnej maszyny \SmArc |
66 |
\item loader - moduł służacy do wczytania plików wykonywalnych \SmArc |
\item {\it loader} - moduł służacy do wczytania plików wykonywalnych \SmArc |
67 |
\item examples - przykładowe programy źródłowe w języku \SmArcAs |
\item {\it examples} - przykładowe programy źródłowe w języku \SmArcAs |
68 |
\end{itemize} |
\end{itemize} |
69 |
|
|
70 |
\vspace{2mm} |
\vspace{2mm} |
82 |
|
|
83 |
\vmachine\ jest głównym modułem projektu \SmArc. Jest to uproszczony |
\vmachine\ jest głównym modułem projektu \SmArc. Jest to uproszczony |
84 |
model procesora SPARC o klasycznej strukturze potoku 5-stopniowego. |
model procesora SPARC o klasycznej strukturze potoku 5-stopniowego. |
85 |
Symuluje wykonywanie programów z dokładnością do mikrooperacji |
Symuluje wykonywanie programów z~dokładnością do mikrooperacji |
86 |
wykonywanych w jednym cyklu zegara. \vmachine\ umożliwia zaobserwować |
wykonywanych w jednym cyklu zegara. \vmachine\ umożliwia zaobserwować |
87 |
przepływ danych w wewnętrznych rejestrach procesora, w szczególności |
przepływ danych we wewnętrznych rejestrach procesora, w szczególności |
88 |
sytuacje przestoju potoku ({\it stall}) oraz wyprzedzenia argumentów |
sytuacje przestoju potoku ({\it stall}) oraz wyprzedzenia argumentów |
89 |
({\it forwarding}). |
({\it forwarding}). |
90 |
|
|
125 |
składni języka, których brak nie powoduje jednakże błędów przy |
składni języka, których brak nie powoduje jednakże błędów przy |
126 |
generowaniu pliku wynikowego) (użycie NIE ZALECANE) \\ |
generowaniu pliku wynikowego) (użycie NIE ZALECANE) \\ |
127 |
\verb!-o <plikbin>! & określa nazwę pliku wynikowego, do którego ma zostać zapisany |
\verb!-o <plikbin>! & określa nazwę pliku wynikowego, do którego ma zostać zapisany |
128 |
program wykonywalny (!\verb!<plikbin>!); |
program wykonywalny (\verb!<plikbin>!); |
129 |
jeżeli parametr ten zostanie |
jeżeli parametr ten zostanie |
130 |
pominięty, to zostanie użyta domyślna nazwa pliku wynikowego |
pominięty, to zostanie użyta domyślna nazwa pliku wynikowego |
131 |
'spasm.output' \\ |
'spasm.output' \\ |
162 |
od początku, czyli adresu 0x0) na początku każdej linii \\ |
od początku, czyli adresu 0x0) na początku każdej linii \\ |
163 |
{\tt -n} & modyfikuje domyślny tryb wyświetlania nazw rejestrów w argumencie |
{\tt -n} & modyfikuje domyślny tryb wyświetlania nazw rejestrów w argumencie |
164 |
rozkazu z zapisu \verb!%r<N>! do bardziej przyjaznego |
rozkazu z zapisu \verb!%r<N>! do bardziej przyjaznego |
165 |
programiście zapisu alternatywnego - |
programiście zapisu alternatywnego: |
166 |
\verb!%g<M>!, \verb!%o<M>!, \verb!%i<M>!, |
\verb!%g<M>!, \verb!%o<M>!, \verb!%i<M>!, |
167 |
\verb!%l<M>!, \verb!%sp! oraz \verb!%fp! |
\verb!%l<M>!, \verb!%sp! oraz \verb!%fp! |
168 |
(gdzie $0\leq$ \verb!N! $\leq31$, $0\leq$ \verb!M! $\leq 7$). \\ |
(gdzie $0\leq$ \verb!N! $\leq31$, $0\leq$ \verb!M! $\leq 7$). \\ |
181 |
\subsection{smarcgui} |
\subsection{smarcgui} |
182 |
\label{sec:elementy:smarcgui} |
\label{sec:elementy:smarcgui} |
183 |
|
|
184 |
\smarcgui\ to graficzny interfejs maszyny wirtualnej \SmArc. Intuicyjna |
\smarcgui\ to graficzny interfejs maszyny wirtualnej \SmArc. Intuicyjna |
185 |
realizacja zapewnia łatwy i zorganizowany dostęp do wewnętrznych elementów |
realizacja zapewnia łatwy i zorganizowany dostęp do wewnętrznych elementów |
186 |
maszyny wirtualnej, takich jak rejestry i pamięć, oraz do stanów pośrednich w |
maszyny wirtualnej, takich jak rejestry i pamięć, oraz do stanów pośrednich w |
187 |
poszczególnych krokach przetwarzania potokowego. |
poszczególnych krokach przetwarzania potokowego. |
188 |
|
|
189 |
|
Interfejs składa się z pięciu poniższych części: |
190 |
|
\begin{itemize} |
191 |
|
\item pionowej listwy przycisków pozwalających kontrolować działanie symulatora |
192 |
|
\item przewijanej listy wyświetlającej wykonywany program. Aktualnie |
193 |
|
wykonywane instrukcje zostały odpowiednio zaznaczone kolorem. |
194 |
|
Pojawienie się przestoju potoku {\it stall} w danej fazie jest |
195 |
|
zaznaczone {\bf '!'} przed jej skrótem. Jest możliwe, że jedna |
196 |
|
instrukcja jest przetwarzana przez większą ilość faz. |
197 |
|
\item grupy pól tekstowych wyświetlających wartości wewnętrzny rejestrów |
198 |
|
procesora. |
199 |
|
\item listy wyświetlającej wszystkie rejestry programowe. |
200 |
|
Aktualne okno jest zaznaczone w tytułach kolumn. |
201 |
|
\item listy wyświetlającej pierwsze 4Kb pamięci danych |
202 |
|
\end{itemize} |
203 |
|
|
204 |
|
|
205 |
\subsection{loader} |
\subsection{loader} |
206 |
\label{sec:elementy:loader} |
\label{sec:elementy:loader} |
207 |
|
|
217 |
\item przesunięcie okna rejestrów |
\item przesunięcie okna rejestrów |
218 |
\item uruchomienie wczytanego programu |
\item uruchomienie wczytanego programu |
219 |
\item po powrocie programu (użycie komendy {\tt ret}) |
\item po powrocie programu (użycie komendy {\tt ret}) |
220 |
przesunięcie okna rejestrów z powrotem |
przesunięcie z powrotem okna rejestrów |
221 |
\item zatrzymanie wirtualnej maszyny (instrukcja o kodzie równym 0) |
\item zatrzymanie wirtualnej maszyny (instrukcja o kodzie równym 0) |
222 |
\end{itemize} |
\end{itemize} |
223 |
\end{itemize} |
\end{itemize} |
233 |
\item addloop.asm - pętla wykonywana zadaną ilość razy |
\item addloop.asm - pętla wykonywana zadaną ilość razy |
234 |
\item arith.asm - instrukcje arytmetyczne |
\item arith.asm - instrukcje arytmetyczne |
235 |
\item forward.asm - demonstracja {\it forwardingu} w procesorze SPARC |
\item forward.asm - demonstracja {\it forwardingu} w procesorze SPARC |
236 |
\item load.asm - odczyt i zapis z/do pamięci DCache |
\item load.asm - odczyt i zapis z/do pamięci danych |
237 |
\item logic.asm - operacje logiczne na rejestrach |
\item logic.asm - operacje logiczne na rejestrach |
238 |
\item loop.asm - instrukcje branch |
\item loop.asm - instrukcje branch |
239 |
\item memcpy.asm - kopiowanie danych |
\item memcpy.asm - kopiowanie danych |
243 |
|
|
244 |
|
|
245 |
|
|
|
|
|
246 |
\section{Założenia i szczegóły techniczne} |
\section{Założenia i szczegóły techniczne} |
247 |
\label{sec:zalozenia} |
\label{sec:zalozenia} |
248 |
|
|
258 |
danych do kolejnej fazy: odczyt z rejestrów programowych, przygotowanie |
danych do kolejnej fazy: odczyt z rejestrów programowych, przygotowanie |
259 |
stałych, sprawdzenie warunków przy skokach ({\it branch}) |
stałych, sprawdzenie warunków przy skokach ({\it branch}) |
260 |
\item {\bf EX/AC} ({\it Execution/Address Calculation}) - wykonanie |
\item {\bf EX/AC} ({\it Execution/Address Calculation}) - wykonanie |
261 |
rozkazów arytmetycznych, logicznych, przesunieć, innych |
rozkazów arytmetycznych, logicznych, przesunięć, innych |
262 |
obliczeń arytmetycznych potrzebnych rozkazom sterującym, |
obliczeń arytmetycznych potrzebnych rozkazom sterującym, |
263 |
przygotowanie adresu w rozkazach typu {\it load} i {\it store}. |
przygotowanie adresu w rozkazach typu {\it load} i {\it store}. |
264 |
\item {\bf MA} ({\it Memory Access}) - zapis lub odczyt do/z pamięci danych |
\item {\bf MA} ({\it Memory Access}) - zapis lub odczyt do/z pamięci danych |
282 |
|
|
283 |
\subsubsection{Założenia \SmArc\ i vmachine} |
\subsubsection{Założenia \SmArc\ i vmachine} |
284 |
|
|
285 |
Architektura \SmArc\ w stosunku architektury SPARC została |
Architektura \SmArc\cite{komorowski} w stosunku architektury SPARC została |
286 |
w celach dydaktycznych uproszczona. Zrezygnowano z implementacji |
w celach dydaktycznych uproszczona. Zrezygnowano z implementacji |
287 |
poniższych: |
poniższych: |
288 |
|
|
290 |
\item jednostka obliczeń zmiennoprzecinkowych, koprocesor |
\item jednostka obliczeń zmiennoprzecinkowych, koprocesor |
291 |
\item przerwania, wyjątki i pułapki |
\item przerwania, wyjątki i pułapki |
292 |
\item pewnej części listy instrukcji (patrz niżej) |
\item pewnej części listy instrukcji (patrz niżej) |
293 |
\item wewnętrzne rejestrów procesora {\bf Y, WIM, TBR}, częściowo {\bf PSR} |
\item wewnętrzne rejestry procesora {\bf Y, WIM, TBR}, częściowo {\bf PSR} |
294 |
\end{itemize} |
\end{itemize} |
295 |
|
|
296 |
W stosunku do specyfikacji SPARCv8\cite{SPARCv8} do listy instrukcji |
W stosunku do specyfikacji SPARCv8\cite{SPARCv8} do listy instrukcji |
302 |
\item rozkazy związane z obsługa przerwań, pułapek, wyjątków |
\item rozkazy związane z obsługa przerwań, pułapek, wyjątków |
303 |
\item {\it annul bit} w rozkazach warunkowych ({\it branch}) |
\item {\it annul bit} w rozkazach warunkowych ({\it branch}) |
304 |
\item rozkazy związane z odczytem oraz zapisem z/do pamięci podwójnych |
\item rozkazy związane z odczytem oraz zapisem z/do pamięci podwójnych |
305 |
słów {\it double-word} (64-bitowych) |
słów ({\it double-word}, 64-bitowe) |
306 |
\item rozkazy mnożenia oraz dzielenia liczb całkowitych |
\item rozkazy mnożenia oraz dzielenia liczb całkowitych |
307 |
\item rozkazy związane z odczytem/zapisem niezaimplementowanych rejestrów |
\item rozkazy związane z odczytem/zapisem niezaimplementowanych rejestrów |
308 |
({\bf Y, WIM, TBR}) lub częściowo zaimplementowanych {\bf PSR} |
({\bf Y, WIM, TBR}) lub częściowo zaimplementowanych ({\bf PSR}) |
309 |
\item {\tt ldstub, swap, stbar, flush} |
\item {\tt ldstub, swap, stbar, flush} |
310 |
\end{itemize} |
\end{itemize} |
311 |
|
|
314 |
Instrukcje zrealizowane w wirtualnej maszynie \SmArc\ są zgodne z |
Instrukcje zrealizowane w wirtualnej maszynie \SmArc\ są zgodne z |
315 |
opisem zawartym w specyfikacji SPARCv8 \cite{SPARCv8}. |
opisem zawartym w specyfikacji SPARCv8 \cite{SPARCv8}. |
316 |
|
|
317 |
|
|
318 |
\noindent Inne założenia symulatora \vmachine: |
\noindent Inne założenia symulatora \vmachine: |
319 |
\begin{itemize} |
\begin{itemize} |
320 |
\item 32 okien rejestrów, czyli w sumie 520 |
\item 32 okien rejestrów, czyli w sumie 520 |
321 |
\item rozdział na pamięć danych i instrukcji |
\item separacja pamięć na dane i instrukcje. Obie posiadają osobne |
322 |
|
przestrznie adresowe. Pamięć instrukcji |
323 |
|
jest tylko do odczytu (poprzez rejestr {\bf PC}), natomiast |
324 |
|
dostęp danych jest poprzez instrukcje typu {\it load} i {\it store}. |
325 |
|
\item odwołania do pamięci są zawsze trafione (nie obserwujemy procesu |
326 |
|
zapełniania pamięci cache i związanym z tym wstrzymaniem potoku) |
327 |
\item 256Kb pamięci danych |
\item 256Kb pamięci danych |
328 |
\item 256Kb pamięci instrukcji |
\item 256Kb pamięci instrukcji |
329 |
\item słowo rozkazowe o kodzie o wartości 0 zatrzymuje symulator |
\item słowo rozkazowe o kodzie o wartości 0 zatrzymuje symulator |
332 |
|
|
333 |
|
|
334 |
|
|
|
|
|
335 |
\subsection{Język \SmArcAs} |
\subsection{Język \SmArcAs} |
336 |
\label{sec:zalozenia:spasm} |
\label{sec:zalozenia:spasm} |
337 |
|
|
418 |
|
|
419 |
\vspace{1mm} |
\vspace{1mm} |
420 |
|
|
421 |
Dokładniejsze informacje dot. składni, formatu słów rozkazowych i kodowania |
Dokładniejsze informacje dotyczące składni, formatu słów |
422 |
rozkazów można znaleźć w specyfikacji SPARCv8 \cite{SPARCv8}. |
rozkazowych i kodowania rozkazów można znaleźć w specyfikacji |
423 |
Tam również znajdują się |
SPARCv8 \cite{SPARCv8}. Tam również znajdują się rozkazy procesora |
424 |
rozkazy procesora SPARC, których implementacja \SmArc\ nie obejmuje (inne |
SPARC, których implementacja \SmArc\ nie obejmuje (inne rozkazy |
425 |
rozkazy arytmetyczne, rozkazy korzystające z koprocesora, itp.) |
arytmetyczne, rozkazy korzystające z koprocesora, itp.) |
426 |
|
|
427 |
|
|
428 |
Pseudorozkazy rozpoznawane przez \spasm\ oraz ich interpretacja znajdują się |
Pseudorozkazy rozpoznawane przez \spasm\ oraz ich interpretacja znajdują się |
444 |
\verb!restore! & \verb!restore %g0, %g0, %g0! \\ |
\verb!restore! & \verb!restore %g0, %g0, %g0! \\ |
445 |
\verb!save! & \verb!save %g0, %g0, %g0! \\ |
\verb!save! & \verb!save %g0, %g0, %g0! \\ |
446 |
\verb!ret! & \verb!jmpl %i7 + 8, %g0! \\ |
\verb!ret! & \verb!jmpl %i7 + 8, %g0! \\ |
447 |
\verb!jmp <etykieta>! & \verb!jmpl <etykieta>, %g0! \\ |
\verb!jmp <addr>! & \verb!jmpl <addr>, %g0! \\ |
448 |
\verb!skipz! &\verb!bnz . + 8 !\footnotemark[1] \footnotemark[2]\\ |
\verb!skipz! &\verb!bnz . + 8 !\footnotemark[1] \footnotemark[2]\\ |
449 |
\verb!skipnz! &\verb!bz . + 8 !\footnotemark[1] \footnotemark[2]\\ |
\verb!skipnz! &\verb!bz . + 8 !\footnotemark[1] \footnotemark[2]\\ |
450 |
\verb!set <const>, %reg!&\verb!sethi %hi(<const>), %reg !\\ |
\verb!set <const>, %reg!&\verb!sethi %hi(<const>), %reg !\\ |
476 |
\verb!.align k! & Wyrównanie adresu do granicy |
\verb!.align k! & Wyrównanie adresu do granicy |
477 |
\verb!k! bajtów (\verb!k! = 2 lub 4) \\ |
\verb!k! bajtów (\verb!k! = 2 lub 4) \\ |
478 |
\verb!.skip n! & Rezerwacja n kolejnych bajtów \\ |
\verb!.skip n! & Rezerwacja n kolejnych bajtów \\ |
479 |
\verb!.byte w1,w2,w3,...!& Nadanie wartości w1, w2, .. kolejnym bajtom \\ |
\verb!.byte w1,w2,w3,...!& Nadanie wartości \verb!w1, w2,...! |
480 |
\verb!.half w1,w2,w3,...!& Nadanie wartości w1, w2, .. kolejnym półsłowom \\ |
kolejnym bajtom \\ |
481 |
\verb!.word w1,w2,w3,...!& Nadanie wartości w1, w2, .. kolejnym słowom \\ |
\verb!.half w1,w2,w3,...!& Nadanie wartości \verb!w1, w2,...! |
482 |
|
kolejnym półsłowom \\ |
483 |
|
\verb!.word w1,w2,w3,...!& Nadanie wartości \verb!w1, w2,...! |
484 |
|
kolejnym słowom \\ |
485 |
\verb!.ascii 'znaki..'! & Umieszczenie w kolejnych |
\verb!.ascii 'znaki..'! & Umieszczenie w kolejnych |
486 |
bajtach kodów znaków ASCII \footnotemark[3]\\ |
bajtach kodów znaków ASCII \footnotemark[3]\\ |
487 |
\verb!=! & Przypisanie nazwie (lewostronnej) |
\verb!=! & Przypisanie nazwie (lewostronnej) |
488 |
wartości (prawostronnej) \\ |
wartości (prawostronnej) \\ |
489 |
\end{tabular} |
\end{tabular} |
490 |
\end{center} |
\end{center} |
|
|
|
491 |
\footnotetext[3]{ Znaki sterujące zapisuje się następująco: |
\footnotetext[3]{ Znaki sterujące zapisuje się następująco: |
492 |
$\backslash b$ - backspace, |
$\backslash b$ - backspace, |
493 |
$\backslash n$ - new line, |
$\backslash n$ - new line, |
563 |
\section{Instalacja} |
\section{Instalacja} |
564 |
\label{sec:instal} |
\label{sec:instal} |
565 |
|
|
566 |
|
Projekt \SmArc\ został napisany na systemy typu Linux. |
567 |
|
Jak większość oprogramowania na ten system wymaga przebudowania |
568 |
|
źródeł. Pociąga to za sobą obowiązek zainstalowania środowiska |
569 |
|
programistycznego. Poniżej wymienione zostały pakiety, jakie |
570 |
|
powinny być zainstalowane dla poprawnego zbudowania \SmArc. |
571 |
|
Większość z nich jest już zainstalowana w każdej standardowej |
572 |
|
dystrybucji. |
573 |
|
|
574 |
|
\begin{itemize} |
575 |
|
\item gcc, gcc-c++, make |
576 |
|
\item automake, autoconf |
577 |
|
\item flex-devel, bison-devel, stdc++-devel |
578 |
|
\item gtk-devel, glade-devel |
579 |
|
\end{itemize} |
580 |
|
|
581 |
\subsection{Wymagania} |
Procedurę budowania \SmArc\ można wykonać na przykład w poniższy sposób: |
|
\label{sec:instal:wymagania} |
|
|
|
|
|
flex-devel, bison-devel, stdc++-devel, Gtk-devel, glade-devel, etc. |
|
|
|
|
|
\subsection{Budowanie pakietu \SmArc} |
|
|
\label{sec:instal:build} |
|
582 |
|
|
583 |
\begin{verbatim} |
\begin{verbatim} |
584 |
$ tar xzf smarc-XX.tar.gz |
$ tar xzf smarc-XX.tar.gz |
585 |
$ cd smarc |
$ cd smarc |
586 |
$ make |
$ make all |
587 |
\end{verbatim} |
\end{verbatim} |
588 |
|
|
589 |
|
Moduł \smarcgui\ do uruchomienia potrzebuje środowiska graficznego |
590 |
|
GNOME oraz GTK. |
591 |
|
|
592 |
\begin{thebibliography}{10} |
\begin{thebibliography}{10} |
593 |
\bibitem{SPARCv8} SPARCv8 (32-Bit SPARC) Architecture Book, \verb!http://www.sparc.org/standards.html! |
\bibitem{SPARCv8} SPARCv8 (32-Bit SPARC) Architecture Book, |
594 |
|
\verb!http://www.sparc.org/standards.html! |
595 |
|
\bibitem{komorowski} Materiały do wykładu z {\it Architektury komputerów}, |
596 |
|
\verb!ftp://ci-1.ci.pwr.wroc.pl/komorowski/! |
597 |
|
|
598 |
\end{thebibliography} |
\end{thebibliography} |
599 |
|
|
600 |
\end{document} |
\end{document} |