
\section{Dateiformate}

\mtwoamiga\ verwendet drei spezielle Dateiformate: {\bf Objektdatei},
{\bf Referenz}- beziehungsweise {\bf Symboldatei} sowie {\bf Fehlerdatei}.
Diese drei Formate
werden nun ausf"uhrlich beschrieben.

Die Dateiformate werden mit Hilfe einer
{\bf EBNF}\footnote{Erweiterte Backus-Naur Form}-"ahnlichen
Sprache beschrieben. EBNF wird h"aufig zur Beschreibung der
Syntax einer Programmiersprache verwendet (z.B. \cite{pim4}).
Sie ist aber auch geeignet, das Format einer Datei zu beschreiben.
Allerdings sind die Terminalsymbole im Falle einer Datei keine
Worte --- wie beispielsweise "`{\tt IF}"' in \mtwo\ ---, sondern
entweder Konstanten oder Variablen, die einen
bestimmten Typ haben. Aus diesem Grund beschreiben wir
Terminalsymbole mit Hilfe von \mtwo-Typen und Konstanten.
Hier folgen die Elemente unserer "`EBNF"':

\begin{ebnf}{A}
\item[A] {\tt B\,C.} \\
  Diese Regel besagt, dass {\tt A} durch die Folge {\tt B\,C} ersetzt
  werden soll.
\item[A] {\tt B\,\verb'|'\,C.} \\
  {\tt A} soll durch {\tt B} oder {\tt C} ersetzt werden.
\item[A] {\tt [B].} \\
  {\tt A} soll durch {\tt B} ersetzt oder weggelassen werden.
\item[A] {\tt \{B\}.} \\
  {\tt A} soll durch eine Folge von 0, 1 oder mehreren {\tt B}
  ersetzt werden.
\item[A] {\tt \dq ARRAY [0..31] OF CHAR\dq.} \\
  {\tt A} besteht aus einer Zeichenkette von 32 Buchstaben.
\item[A] {\tt \dq INTEGER(7)\dq.} \\
  {\tt A} besteht aus der Konstanten 7, wobei in der
  Datei gleich viel Platz wie f"ur einen {\tt INTEGER} verwendet wird,
  in diesem Fall also 2 Byte. \\
\end{ebnf}

Der Punkt "`{\tt .}"' am Ende der Regel markiert deren Ende. Alles Nachfolgende
ist Kommentar. Die obigen Regeln k"onnen zu komplexeren Regeln
zusammengefasst werden, also beispielsweise "`{\tt A\,=\,B\,C\,\verb'|'\,D\,E.}"'.
Dabei bindet "`\verb'|'"' schw"acher als die einfache Folge. So bedeutet
"`{\tt A\,=\,B\,C\,\verb'|'\,D\,E.}"', dass "`{\tt A}"'
entweder durch die Folge "`{\tt B\,C}"'
oder durch "`{\tt D\,E}"' ersetzt werden darf. Dies kann durch Klammern
beeinflusst werden:
so besagt die Regel "`{\tt A\,=\,B\,(\,C\,\verb'|'\,D\,)\,E.}"',
dass "`{\tt A}"' durch "`{\tt B\,C\,E}"' oder
durch "`{\tt B\,D\,E}"' ersetzt werden darf.

Eine vollst"andige Dateibeschreibung k"onnte folgendermassen aussehen:

\setcounter{filefmt}{1}
\begin{ebnf}{NumBlocks}
\item[Datei] {\tt ID NumBlocks \{Block\} [Name].} \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[ID] {\tt \dq LONGINT(17)\dq.} \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[NumBlocks] {\tt \dq INTEGER\dq.}
  \hfill(\arabic{filefmt}\stepcounter{filefmt}) \\
  Dieser Wert enth"alt die Anzahl der folgenden Bl"ocke. 
\item[Block] {\tt Size(CodeId \verb'|' DataId) \{Word\}.}
  \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[Size] {\tt \dq LONGINT\dq.} \hfill(\arabic{filefmt}\stepcounter{filefmt}) \\
  Die Gr"osse des folgenden Blocks ohne die {\tt CodeId} bzw.
  {\tt DataId}. 
\item[CodeId] {\tt \dq INTEGER(1)\dq.} \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[DataId] {\tt \dq INTEGER(2)\dq.} \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[Word] {\tt \dq INTEGER\dq.} \hfill(\arabic{filefmt}\stepcounter{filefmt})
\item[Name] {\tt \dq ARRAY [0..7] OF CHAR\dq.}
  \hfill(\arabic{filefmt}\stepcounter{filefmt})
\end{ebnf}

Die Bedeutung dieser Zeilen im einzelnen:
\begin{enumerate}
\item
  Die Datei besteht aus einer Kennzeichnung {\tt ID}, gefolgt von einer
  Zahl und keinem oder beliebig vielen Bl"ocken und eventuell
  einem Namen.
\item
  Die Kennzeichnung der Datei hat den Wert 17 und wird
  in vier Byte dargestellt.
\item
  Die Zahl der Bl"ocke ist durch zwei Byte gegeben. Mit dem
  Kommentar wird veranschaulicht, was die EBNF alleine nicht
  aufzeigen kann: die Zahl "`{\tt NumBlocks}"' gibt gerade die
  Anzahl der darauf"|folgenden Bl"ocke an. Hier handelt es
  sich um eine {\em semantische\/} Angabe zum Eintrag "`{\tt NumBlocks}"'.
\item
  Ein {\tt Block} besteht aus einer Gr"ossenangabe und einer Kennzeichnung,
  gefolgt von beliebig vielen Worten.
\item
  Die Gr"osse des Blocks wird durch vier Byte angegeben. Auch hier
  schliesst sich wieder ein Kommentar an, der die Beziehung zwischen
  dem Wert "`{\tt Size}"' und den folgenden Worten aufzeigt.
\item
  Die {\tt CodeId} belegt zwei Byte und hat den Wert 1.
\item
  Die {\tt DataId} belegt ebenfalls zwei Byte und hat den Wert 2.
\item
  Das {\tt Word} besteht aus zwei Byte mit beliebigem Inhalt.
\item
  Der {\tt Name} besteht aus acht Zeichen.
\end{enumerate}

Der folgende Hexdump stellt eine nach obigen Schema g"ultige Datei
dar. Diese enth"alt zun"achst die {\tt ID}. Darauf folgt die Angabe, dass
genau ein {\tt Block} vorhanden ist. Dieser {\tt Block} enth"alt vier Byte.
Es ist ein Datenblock und enth"alt die vier Byte 1E 84 95 0A.
Schliesslich folgt der {\tt Name} "`Test"'.

\begin{quote} \tt
00 00 00 11 00 01 00 00 00 04 00 02 1E 84 95 0A \\
53 65 74 73 00 00 00 00
\end{quote}

\subsection{Objektdatei}

\label{refObject}
Die folgenden Informationen zum Objekt-Format sind f"ur den "`normalen"'
\mtwo-Programmierer wahrscheinlich von geringer Bedeutung. F"ur Programmierer
jedoch, die \mtwoamiga-fremde Daten oder Prozeduren in ein Programm
einbinden oder \mtwo-Teile in fremden Sprachen benutzen wollen, sind
diese Informationen unerl"asslich.

Der Compiler erzeugt Objektfiles, die dem neuen Amiga-Standard
entsprechen. Dieses Format soll hier nicht vollst"andig erkl"art werden,
eine gute Beschreibung befindet sich in \cite{AmigaDOS}. Wir wollen
lediglich die M2Amiga-spezifischen Besonderheiten aufzeigen.

Jede Objekt-Datei besteht aus einer sogenannten {\bf Unit} (Einheit),
die beliebig
viele Hunks enth"alt. Die Unit definiert einen internen Namen, der im
\mtwoamiga-System immer identisch mit dem Namen des Moduls ist.

F"ur jede globale Prozedur (Level 0), jedes zum Hauptmodul lokale
Modul und f"ur das Hauptmodul selbst wird ein eigener Hunk erzeugt.

Jeder Hunk besteht aus einer Kennung, die den Typ festlegt, einem
Namen, den eigentlichen Daten und eventuell weiteren Informationen,
die Relokationen, externe Referenzen oder externe Definitionen beschreiben.

Es gibt neun verschiedene Hunktypen, welche die Art der Daten und den
Typ des Speichers bestimmen, in dem sie beim Programmlauf abgelegt
sind:

\label{refHunks}
\begin{description}
\item[CODE] enth"alt die ausf"uhrbaren Maschinenbefehle oder auch Daten, die
w"ahrend des Programmlaufes nicht ver"andert werden. Der Typ des Speichers
ist hier nicht festgelegt. Der Compiler erzeugt CODE-Hunks f"ur die Prozeduren
und die konstanten Zeichenketten.
\item[CHIPCODE] ist das gleiche wie CODE. Hunks dieses Typs werden aber
im Gegensatz zu CODE immer im CHIP-Speicher des Amiga abgelegt.
Auf diesen Speicher haben neben der CPU auch die Custom-Chips Zugriff.
Grafik- oder Musikdaten liegen bei diesem Hunktyp gleich beim
Programmstart im Chip-Speicher, wodurch man sich ein sp"ateres Umkopieren
in diesen Speicher erspart. Der Compiler erzeugt f"ur alle Prozeduren
und konstanten Zeichenketten eines Moduls CHIPCODE-Hunks, wenn die
Compiler-Option "`{\tt ChipCode:=TRUE}"' gesetzt wurde.
\item[DATA] sind Daten, die gleich beim Programmstart mit Werten
belegt sind, aber im Gegensatz zu CODE w"ahrend des Programmlaufes
ver"andert werden d"urfen.
Der Compiler erzeugt {\em keine\/} DATA-Hunks, sie k"onnen jedoch mit
Hilfe eines fremden Compilers oder Assemblers erstellt und vom Linker
in das Programm eingebunden werden. N"aheres hierzu erfahren Sie
im Abschnitt "`Externe Variablen"' (\ref{refExtVars}).
\item[CHIPDATA] sind initialisierte Daten, die gleich beim Programmstart
im Chip-Speicher liegen.
\item[BSS] sind Daten, die zu Beginn des Programmlaufs immer mit dem Wert
Null gef"ullt sind und ver"andert werden d"urfen. Der Compiler erzeugt
einen BSS-Hunk f"ur die globalen Variablen des Moduls.
\item[CHIPBSS] werden im Chip-Speicher angelegt und mit Nullen gef"ullt.
Der Compiler erzeugt einen CHIPBSS-Hunk, wenn die Compiler-Option
 "`{\tt ChipBSS:=TRUE}"' im Quelltext angegeben wurde.
\end{description}

\noindent Der Vollst"andigkeit halber seien noch die Hunktypen FASTCODE,
FASTDATA und FASTBSS erw"ahnt. F"ur diese Typen wird jeweils Fast-Speicher
angefordert. Das Betriebssystem wird aber auch ohne die Angabe "`FAST"'
immer Fast-Memory zur Verf"ugung stellen, da dieser normalerweise
die h"ochste Priorit"at hat. Im Fast-Memory laufen Programme schneller,
aber ein Programm, das explizit Fast-Memory anfordert, wird auf einem
Amiga ohne diese Art Speicher {\em nicht\/} ablauf"|f"ahig sein!
Deshalb werden
diese Hunktypen vom Compiler nicht unterst"utzt. Der Linker kann
sie aber ohne weiteres verarbeiten.

Der Name eines Hunks ist nur f"ur den Linker wichtig. Er versucht,
Hunks gleichen Namens zusammenzulegen bzw.\ Hunks mit unterschiedlichen
Namen zu trennen. Der Compiler erzeugt genau 3 verschiedene Namen:

\begin{description}
\item["`text"':] Alle CODE- und CHIPCODE-Hunks
\item["`"':] Einen leeren Namen haben BSS- und CHIPBSS-Hunks, die
globale Variablen im \far-Modell enthalten.
\item["`\_\_MERGED"'] Dies f"ur BSS- oder DATA-Hunks, die globale Variablen
im \near-Modell enthalten. Diese erfahren durch den Linker eine
besondere Behandlung, dass wir sogar von den Hunktypen "`MERGBSS"' und
"`MERGDATA"' sprechen. Man beachte, dass hier CHIP\ldots {\em nicht\/}
m"og"-lich ist!
\end{description}

\medskip
\mtwoamiga\ benutzt zwei neue Dinge, die im AmigaDos-Handbuch noch nicht
aufgef"uhrt sind und deshalb hier kurz erw"ahnt werden sollen:
\begin{itemize}
\item
In {\bf hunk\_\_ext} gibt es den neuen Wert {\bf ext\_\_dref16} (=134),
der das \near-Modell und residente Programme erst m"oglich macht.
Dies sind 16Bit Data-Referenzen auf die Basis der \near-Variablen
des Moduls.
\item
Die Bedeutung von {\bf ext\_\_ref16} ist erweitert worden. Nun ist
es erlaubt, {\em alle\/} Prozeduren mit einem 16Bit-Offset
anzuspringen, auch wenn sie in einem anderen Modul liegen.
Genaueres kann im Abschnitt \ref{refSpecLink} nachgelesen werden.
\end{itemize}

\noindent
Zum Abschluss eine Aufstellung der erzeugten Linker-Symbole und Hunks:
\begin{table}[h]
\begin{center}
\begin{tabular}{|l|l|l|l|}\hline
Typ                    & Symbol         & Hunkname      & Hunktyp\\\hline\hline
Exportierte Prozeduren & \cmsltt modul{\tt\_}Name& \bf text      & CODE\\ \hline
Interne Prozeduren     & \cmsltt modul{\tt\$}nr  & \bf text      & CODE\\ \hline
Lokale Moduln          & (kein Symbol)    & \bf text      & CODE\\ \hline
\near--Variablen       & \cmsltt modul\tt\_VAR & \bf\_\_MERGED & BSS \\ \hline
\far--Variablen        & \cmsltt modul\tt\_VAR & (ohne Namen)  & BSS \\ \hline
Konstanten             & \cmsltt modul\tt\_BY  & \bf text      & CODE \\ \hline
Impmodul               & \cmsltt modul{\tt\_}xxx\ldots & \bf text & CODE \\
\ldots--CLOSE          & \cmsltt modul\tt\_END &               & \\ \hline
Librarymodul           & \cmsltt modul{\tt\_}version & \bf text & CODE \\
\ldots--CLOSE          & \cmsltt modul\tt\_END &               & \\ \hline
Hauptmodul             & \tt\_\_main    & \bf text      & CODE \\
\ldots--CLOSE          & \tt\_\_mainEnd &               & \\ \hline
\end{tabular}
\end{center}
\caption{Linker-Symbole und Hunks}
\end{table}

\noindent
Fast jeder Name setzt sich also aus dem Modulnamen, einem Unterstrich
und einem bestimmten Bezeichner zusammen.
\begin{ttscript}{CODE, BSS}
\item[{\cmsltt modul}] ist jeweils durch den Modulnamen zu ersetzen.
\item[{\cmsltt nr}] ist eine interne Prozedurnummer. Da diese Prozeduren nicht
 exportiert sind, sollten sie auch nicht durch fremden Code angesprochen
 werden k"onnen!
\item[{\cmsltt version}] ist die Version der Library als Dezimalzahl.
\item[{\cmsltt xxx\ldots}] steht f"ur den Modul-Schl"ussel, der als 12stellige
 Hexadezimalzahl aus dem Zeitpunkt der Compilation des Definitionsmoduls
 erzeugt wird.
\item[CODE, BSS] muss jeweils bei entsprechender, 
eingeschalteter Compileroption
durch CHIPCODE bzw.\ CHIPBSS ersetzt werden.
\end{ttscript}

\begin{example}
\noindent
Ein Implementations-Modul "`Demo"' k"onnte beispielsweise folgende
Linker-Symbole exportieren:
\begin{itemize}
\item "`Demo\_Init"' ist eine im Definitionsmodul
  angegebene Prozedur {\tt Init}.
\item "`Demo\$3"' bezeichnet eine interne (nicht exportierte) Prozedur.
\item "`Demo\_123456789ABC"' kennzeichnet den Beginn des Hauptmoduls.
\item "`Demo\_END"' kennzeichnet den CLOSE-Teil des Hauptmoduls. Dies
Symbol liegt mit Demo\_123\ldots im selben Hunk.
\item "`Demo\_BY"' sind die konstanten Zeichenketten in einem CODE-Hunk.
\item "`Demo\_VAR"' bestimmt den Beginn der globalen Variablen im BSS-Hunk
\end{itemize}
\end{example}


\subsection{Symbol-/Referenzdatei}

Die Symboldatei wird vom Compiler erzeugt und auch von diesem
verwendet. Sie enth"alt in codierter Form alle wichtigen Angaben
eines Definitionsmoduls.

Die ebenfalls vom Compiler erzeugte Referenzdatei wird in erster
Linie vom Debugger verwendet. Sie enth"alt die vom Debugger
ben"otigten Informationen "uber die Lage der Variablen im Speicher,
sowie die Positionen der \mtwo-Anweisungen innerhalb des Codes.
Des weiteren greifen der Profiler und der Objekt-Decoder
auf die Referenzdatei zu.

\begin{ebnf}{ReferenceFile}
\item[ReferenceFile]
  {\tt REFFILE ModAnchor \{ModAnchor\} \\
  \{ObjList ModTag \verb'|' ObjList ProcTag\} \\
  ObjList RefTag.}
\item[ObjList]
  {\tt \{Structure \verb'|' Component \verb'|' Object \verb'|' Linkage \verb'|' PC-Block\}.}
\item[Structure]
  {\tt Enum \verb'|' Range \verb'|' Pointer \verb'|' Set \verb'|' ProcTyp \verb'|' FuncTyp \verb'|'
  Array \verb'|' DynArray \verb'|' Record \verb'|' Opaque.}
\item[Component]
  {\tt ParRef \verb'|' Par \verb'|' Field.}
\item[Object]
  {\tt VarRef \verb'|' Var \verb'|' Constant \verb'|' Type \verb'|' Procedure \verb'|' Function \verb'|'
  Module \verb'|' Code.}
\item[PC-Block]
  {\tt PCPos SourcePos.}
\item[ModAnchor]
  {\tt BYTE(0H) key name modmode [libname].} \\
  Der Wert "`{\tt libname}"'
  erscheint, wenn "`{\tt modmode}"' den Wert "`{\tt LIB}"' hat.
\item[ModTag]
  {\tt BYTE(1H) ModNo.}
\item[ProcTag]
  {\tt BYTE(2H) ProcNo.}
\item[RefTag]
  {\tt BYTE(3H) adr pno.} \\
  "`{\tt adr}"' bezeichnet die Adresse, von welcher an die Variablen des
  Implementationsmoduls alloziert werden d"urfen. \\
  "`{\tt pno}"' bezeichnet die Anzahl der deklarierten Prozeduren.
\item[Linkage]
  {\tt BYTE(4H) StrRef BaseRef.} \\
  Der Zeigertyp "`{\tt StrRef}"' zeigt auf den Typ
  "`{\tt BaseRef}"'.
\item[Enum]
  {\tt BYTE(10H) size NoConst.} \\
  "`{\tt size}"' bezeichnet die Anzahl der Byte, die f"ur eine
  Variable dieses Typs ben"otigt wird. Dies gilt auch f"ur die
  n"achsten neun Eintr"age. \newline
  Die Anzahl der Elemente in diesem Aufz"ahlungstyp wird durch "`{\tt NoConst}"'
  angegeben.
\item[Range]
  {\tt BYTE(11H) size BaseRef min max sign.} \newline
  "`{\tt BaseRef}"' bezeichnet den Grundtyp dieses Unterbereichtyps. \newline
  "`{\tt min}"' ist die untere Bereichsgrenze, "`{\tt max}"' die obere. \newline
  "`{\tt sign}"' gibt an, ob es sich um einen vorzeichenbehafteten Typ
  handelt oder nicht.
\item[Pointer]
  {\tt BYTE(12H) size.}
\item[Set]
  {\tt BYTE(13H) size BaseRef.} \newline
  "`{\tt BaseRef}"' bezeichnet den Elementtyp dieses Mengentyps.
\item[ProcTyp]
  {\tt BYTE(14H) size.}
\item[FuncTyp]
  {\tt BYTE(15H) size ResRef.} \newline
  Der Resultatstyp dieser Prozedur steht in "`{\tt ResRef}"'.
\item[Array]
  {\tt BYTE(16H) size ElemRef IndexRef.} \newline
  "`{\tt ElemRef}"' gibt den Elementtyp dieses Feldes. \newline
  "`{\tt IndexRef}"' bezeichnet den Indextyp.
\item[DynArray]
  {\tt BYTE(17H) size ElemRef.} \\
  "`{\tt ElemRef}"' enth"alt den Elementtyp des Feldes.
\item[Record]
  {\tt BYTE(18H) size.}
\item[Opaque]
  {\tt BYTE(19H) size.}
\item[BPointer]
  {\tt BYTE(1AH) size.}
\item[ParRef]
  {\tt BYTE(20H) StrRef parmode name.} \\
  "`{\tt StrRef}"' bezeichnet den Typ des Parameters. \\
  "`{\tt parmode}"' ist 0, falls es sich um einen Parameter handelt, der auf
  dem Stack "ubergeben wird. Andernfalls hat "`{\tt parmode}"' einen Wert
  zwischen 1 und 8 f"ur die Datenregister D0 -- D7 oder
  zwischen 9 und 17 f"ur die Adressregister A0 -- A7. \\
  "`{\tt name}"' enth"alt den Namen des Parameters. Dieser Name ist leer,
  wenn das Definitionsmodul ohne
  Bezeichnerkontrolle\footnote{Compileranweisung
  {\tt (*\$ NameChk := FALSE *)}, siehe Seite \pageref{nameChk}}
  compiliert wurde, oder es sich um ein Schnittstellenmodul handelt.
\item[Par]
  {\tt BYTE(21H) StrRef parmode name.} \\
  mit den analogen Bedeutungen wie bei "`{\tt ParRef}"'.
\item[Field]
  {\tt BYTE(22H) StrRef offset name.} \\
  "`{\tt StrRef}"' gibt den Typ dieses Record-Elementes an. \\
  "`{\tt offset}"' ist die Adresse des Feldes relativ
  zur Anfangsadresse des Records. \\
  "`{\tt name}"' ist der Name des Feldes. \\
\item[VarRef]
  {\tt BYTE(30H) StrRef level address varmode [extname] name exported.} \\
  "`{\tt StrRef}"': Typ dieser Variable. \\
  "`{\tt level}"' gibt die Schachtelungstiefe der Prozedur an, in der
  diese Variable deklariert wurde; f"ur globale Variablen
  ist dieser Wert 0. \\
  "`{\tt address}"' enth"alt die Adresse dieser Variablen, die genaue
  Bedeutung muss dem folgenden Wert entnommen werden. \\
  "`{\tt varmode}"' kennt folgende Werte:
  \begin{itemize}
  \item[0:] globale Variable im \near-Modell, "`{\tt address}"' bezeichnet
    den Offset
  \item[1:] absolute Variable, "`{\tt address}"' ist die Absolut-Adresse
  \item[2:] Register-Variable, "`{\tt address}"' enth"alt die Registernummer
  \item[3:] globale Variable im \far-Modell, "`{\tt address}"' bezeichnet den
    Offset
  \item[4:] externe Variable ({\tt [\dq{\cmsltt Name\/}\dq]}), "`{\tt address}"'
    enth"alt den F"ullwert 0, die Variable wird absolut adressiert
  \item[5:] externe Variable im \near-Modell
    ({\tt [<\dq{\cmsltt Name\/}\dq]}), "`{\tt address}"'
    enth"alt den F"ullwert 0, die Variable wird A4-relativ
    adressiert.
  \end{itemize}
  "`{\tt extname}"' ist der externe Name, unter der diese Variable vom Linker
  gesucht wird. Dieses Feld ist nur im Fall von externen Variablen
  vorhanden ("`{\tt varmode}"' = 4 oder "`{\tt varmode}"' = 5).
  "`{\tt name}"' ist der Name der Variablen.
  "`{\tt exported}"' schliesslich gibt an, ob die Variable exportiert
  wird.
\item[Var]
  {\tt BYTE(31H) StrRef level address varmode [extname] name exported.} \\
  Der Aufbau ist analog zu den Feldern von "`{\tt VarRef}"'.
\item[Constant]
  {\tt BYTE(32H) StrRef ModRef value name exported.} \\
  "`{\tt StrRef}"', "`{\tt name}"' und "`{\tt exported}"'
  siehe "`{\tt VarRef}"'. \\
  "`{\tt ModRef}"' ist die Nummer des Moduls, in der diese
  Konstante deklariert wurde. \\
  "`{\tt value}"' gibt den Wert der Konstante. \\
\item[String]
  {\tt BYTE(33H) StrRef string name exported.} \\
  "`{\tt string}"' enth"alt den Text dieser Zeichenkettenkonstante. \\
\item[Type]
  {\tt BYTE(34H) StrRef ModRef name exported.}
\item[Procedure]
  {\tt BYTE(35H) ProcNo level address size registers name exported.} \\
  "`{\tt ProcNo}"' ist die Nummer der Prozedur. \\
  "`{\tt level}"' bezeichnet die Schachtelungstiefe der Prozedur,
  wobei globale Prozeduren den {\tt level} 0 haben. \\
  "`{\tt address}"' ist die Adresse der Prozedur. \\
  "`{\tt size}"' gibt an, wieviel Platz die lokalen Variablen ben"otigen. \\
  "`{\tt registers}"' ist ein {\tt BITSET}, der die als Parameter verwendeten
  Register markiert.
\item[Function]
  {\tt BYTE(36H) ResRef ProcNo level address size registers name exported.} \\
  "`{\tt ResRef}"' ist der Resultatstyp der Funktion, die anderen Elemente
  sind wie bei "`{\tt Procedure}"'.
\item[Module]
  {\tt BYTE(37H) ModNo name exported.} \\
  "`{\tt ModNo}"': Nummer dieses lokalen Moduls.
\item[Code]
  {\tt BYTE(38H) cnum name exported.}` \\
  "`{\tt cnum}"' gibt den Offset dieser CODE-Prozedur.
\item[CodeFunc]
  {\tt BYTE(39H) ResRef cnum name exported.} \\
  "`{\tt ResRef}"' ist der Resultatstyp dieser CODE-Funktion.
\item[REFFILE]
  {\tt SYMFILE \verb'|' REF68000 \verb'|' REF68010 \verb'|' REF68020
  \verb'|' REF68030 \verb'|' REF68040 \verb'|' REF68881
  \verb'|' REFNoPC.}
\item[SYMFILE]
  {\tt LONGINT(10).}
\item[REF68000]
  {\tt LONGINT(10).}
\item[REF68010]
  {\tt LONGINT(11).}
\item[REF68020]
  {\tt LONGINT(12).}
\item[REF68030]
  {\tt LONGINT(13).}
\item[REF68040]
  {\tt LONGINT(14).}
\item[REF68881]
  {\tt LONGINT(18).}
\item[REFNoPC]
  {\tt LONGINT(19).} \\
  Dieser Wert wird f"ur Referenzdateien {\em ohne\/} PC-Informationen
  vergeben (Option "`{\tt +@}"'). Die Datei kann nur f"ur den
  Library-Linker und den Profiler
  verwendet werden.
\item[key]
  {\tt ARRAY [0..2] OF INTEGER.}
\item[name]
  {\tt string.}
\item[string]
  {\tt length \{char\}.} \\
  "`{\tt length}"' zeigt die L"ange der Zeichenkette an.
\end{ebnf}

Alle oben nicht ausdr"ucklich aufgef"uhrten Symbole sind Zahlen,
die nach einem speziellen, platzsparenden Verfahren kodiert sind.
Dabei richtet sich die Anzahl der verwendeten Byte nicht nach
dem m"oglichen Maximum, sondern nach dem effektiven Wert.

Zahlen im Bereich von -32 bis +31 werden in einem Byte kodiert.
Dazu werden nur sechs Bit ben"otigt. Die h"ochstwertigen zwei Bit
tragen so nicht zum Wert bei. Sie enthalten beide Null und geben
somit an, dass die Zahl in einem Byte kodiert wurde.

Zahlen innerhalb des Bereichs von -16\,384 -- -257 und 256 -- 16\,383
werden in zwei Byte kodiert. Dazu werden 14 Bit ben"otigt, und die
beiden verbleibenden h"ochstwertigen Bit geben wiederum das Format an.
Sie haben den Wert 01 um anzugeben, dass es sich um eine Zahl handelt,
die zwei Byte belegt.

Zahlen, die f"ur ihre Darstellung 17 -- 22 Bit ben"otigen,
werden in drei Byte abgelegt. Die beiden h"ochstwertigen Bit
haben den Wert 10 in Dual\-dar\-stel\-lung.

F"ur alle anderen Zahlen wird im ersten Byte nur die L"ange
in Byte der Zahl abgelegt. Die L"ange wird in den sechs
niederwertigsten Bit des h"ochstwertigen Byte vermerkt. Die
restlichen zwei Bit enthalten den Wert 11, um diese Art der Codierung
zu identifizieren. Auf dieses erste Byte folgen soviele Byte
wie verlangt.

\begin{example}
\begin{table}[h]
\begin{tabular}{rrl}
Zahl & Codierung (Hex) & Codierung (bin"ar) \\ \hline
5 & 05 & 0000 0101 \\
-5 & 3B & 0011 1011 \\
40 & C128 & 1100 0001 0010 1000 \\
300 & 412C & 0100 0001 0010 1100 \\
-300 & 7ED4 & 0111 1110 1101 0100 \\
65236 & C20ED4 & 1100 0010 0000 1110 1101 0100 \\
\end{tabular}
\end{table}
\end{example}

"`{\tt PCPos}"' stellt davon eine Ausnahme dieser Codierung dar.
Zahlen des Bereichs -32 -- 31 werden nicht in einem einzigen
Byte, sondern in 2 Byte codiert. So wird etwa die Zahl drei
als C103 abgelegt.\footnote{Durch die Verwendung der Codierung,
die im ersten Byte die Anzahl der folgenden Byte angibt und
durch zwei 1-Bit eingeleitet ist.} Auf diese Weise ist es m"oglich,
einen "`{\tt PC}"'-Block von den anderen
Elementen der "`{\tt ObjList}"' zu unterscheiden,
ohne dass ein zus"atzliches Byte vor einem "`{\tt PC}"'-Block stehen muss.

Alle Namen, die mit "`{\tt Ref}"' enden, stellen Referenzen auf
Strukturen dar. Die Strukturen werden fortlaufend numeriert, wobei
die Werte 1 bis 23 vordefinierten Typen entsprechen.
Alle in der Symboldatei selbst auftretenden Strukturdefinitionen
werden vom Wert 32 an aufsteigend numeriert. Wird eine
Referenz auf eine solche Struktur ben"otigt, ist in der
Symboldatei die Nummer der Struktur abgelegt. Beim Einlesen
der Datei wird daraus ein Zeiger auf die entsprechende
Struktur erzeugt. Die vordefinierten Strukturen sind in
der Tabelle \ref{preDefStruc} angegeben.

\begin{table}[bth]
\begin{center}
\begin{tabular}{rlrl}
1 & Undefiniert & 13 & {\tt BYTE} \\
2 & {\tt BOOLEAN} & 14 & {\tt WORD} \\
3 & {\tt CHAR} & 15 & {\tt LONDCARD} \\
4 & {\tt INTEGER} & 16 & UniversalInteger \\
5 & {\tt CARDINAL} & 17 & UniversalReal \\
6 & {\tt LONGINT} & 18 & {\tt FFP} \\
7 & {\tt REAL} & 19 & {\tt LONGSET} \\
8 & {\tt LONGREAL} & 20 & {\tt SHORTCARD} \\
9 & {\tt BITSET} & 21 & {\tt SHORTINT} \\
10 & {\tt PROC} & 22 & {\tt BPTR} \\
11 & String & 23 & {\tt SHORTSET} \\
12 & {\tt ADDRESS} \\
\end{tabular}
\end{center}
\caption{\label{preDefStruc} Vordefinierte Strukturen}
\end{table}

Die Strukturen 1, 11, 16 und 17 werden nur intern gebraucht
und stellen keine vordefinierten Typen dar.

Die Symboldatei stellt die Symboltabelle des Compilers dar. In ihr
sind alle deklarierten Objekte --- Variablen, Typen, Prozeduren ---
und deren Strukturen --- {\tt ARRAY}, {\tt RECORD} usw.\ --- abgelegt.
Die gew"ahlte Darstellung erlaubt eine ef"|fiziente Rekonstruktion
der Symboltabelle beim Einlesen der Symboldatei.

\subsection{Fehlerdatei und Fehlermeldungen}

Die Fehlerdatei wird vom Compiler beim "Ubersetzen eines fehlerhaften
Programms erzeugt. Sie enth"alt die Fehlermeldungen in codierter
Form. Der Editor {\tt m2emacs} und der Fehlerlister {\tt m2error}
sind in der Lage, diese Fehlermeldungen mit Hilfe der Datei
{\tt M2:Fehler-Meldungen} in Klartext
umzuwandeln\footnote{Naheliegenderweise enth"alt diese Datei die
deutschsprachigen Fehlermeldungen}. Das Fehlerdatei hat folgendes
Format:

\begin{ebnf}{SourcePos}
\item[ErrorFile]
  {\tt ERRFILE \{Error\}. End}
\item[Error]
  {\tt ErrorPos \{ErrorPart\}.}
\item[ErrorPos]
  {\tt ERR SourcePos.}
\item[ErrorPart]
  {\tt ErrorNum \verb'|' String.}
\item[ErrorNum]
  {\tt INTEGER.} \\
  Nur positive Zahlen sind zugelassen.
\item[String]
  {\tt STR \{CHAR\}.} 
\item[SourcePos]
  {\tt LONGINT.}
\item[ERRFILE]
  {\tt LONGINT(3).}
\item[ERR]
  {\tt LONGINT(0C1457272H).}
\item[STR]
  {\tt CHAR(0C2H).}
\item[End]
  {\tt INTEGER(-1).}
\end{ebnf}

Die Zeichenkette "`{\tt String}"' muss mit einem 0C-Zeichen abgeschlossen sein.
Ein zweites 0C-Zeichen ist dann n"otig, wenn die Zeichenkette an
einer geraden Adresse endet; das n"achste Element der Fehlerdatei muss auf
einer geraden Adresse liegen. "`{\tt SourcePos}"' bezeichnet
die Position des Fehlers
im Quelltext an. Der Wert "`{\tt ErrorNum}"' bezieht sich auf Meldungen,
die in der Datei {\tt M2:Fehler-Meldungen} abgelegt sind.

Diese
Datei enth"alt --- jeweils zusammen mit einer sie identifizierenden
Zahl --- alle Fehlermeldungen und Textbausteine, die f"ur
Fehlermeldungen ben"otigt werden. Die Struktur der Datei ist:

\begin{ebnf}{MessageFile}
\item[MessageFile]
  {\tt \{Message\} End.}
\item[Message]
  {\tt Next Number String.}
\item[Next]
  {\tt LONGINT.} \\
  Adresse der n"achsten Fehlermeldung relativ zum Dateianfang.
\item[Number]
  {\tt INTEGER.} \\
  Fehlernummer.
\item[String]
  {\tt \{CHAR\}.} \\
  Der Fehlertext, abgeschlossen mit einem 0C-Zeichen.
  Die n"achste Meldung muss auf einer geraden Adresse liegen; dazu
  wird unter Umst"anden ein weiteres 0C-Zeichen eingef"ugt.
\item[End]
  {\tt LONGINT(0) INTEGER(0).}
\end{ebnf}
