%%TITLE Bedienungsanleitung Makroassembler AS \documentstyle[german,12pt,dina4,twoside,makeidx]{report} \pagestyle{headings} \sloppy \textwidth 15cm \evensidemargin 0.5cm \oddsidemargin 0.5cm \topsep 1mm \parskip 0.3cm plus0.2cm minus0.2cm \hyphenation{Lis-ting-er-zeu-gung} \hyphenation{back-slash} \newif\ifelektor \elektorfalse \newcommand{\ii}[1]{{\it #1}} \newcommand{\bb}[1]{{\bf #1}} \newcommand{\tty}[1]{{\tt #1}} \newcommand{\tin}[1]{{\scriptsize #1}} \newcommand{\ttindex}[1]{\index{#1@{\tt #1}}} \font\mengft=cmss9 scaled \magstep1 \def \rz{\hbox{\mengft{I \hskip -1.7mm R}}} \makeindex %%=========================================================================== \begin{document} \thispagestyle{empty} \ \vspace{7cm}\par \begin{raggedright} {\large Alfred Arnold}\\ \vspace{1cm}\par {\huge Makroassembler AS V1.41r8}\\ \rule{9.5cm}{0.3mm}\\ \vspace{2mm}\par {\huge Benutzeranleitung} \vspace{1cm}\par {\large Stand November 1999} \end{raggedright} \clearpage \thispagestyle{empty} \ \vspace{4cm} {\em IBM, PPC403Gx, OS/2} und {\em PowerPC} sind eingetragene Warenzeichen der IBM Corporation. {\em Intel, MCS-48, MCS-51, MCS-251, MCS-96, MCS-196} und {\em MCS-296} sind eingetragene Warenzeichen der Intel Corp. . {\em Motorola} und {\em ColdFire} sind eingetragene Warenzeichen von Motorola Inc. . {\em UNIX} ist ein eingetragenes Warenzeichen der X/Open Company. {\em Linux} ist ein eingetragenes Warenzeichen von Linus Thorvalds. {\em Microsoft, Windows} und {\em MS-DOS} sind eingetragene Warenzeichen der Microsoft Corporation. Alle anderen Warenzeichen, die nicht ausdr"ucklich in diesem Abschnitt genannt wurden und in diesem Handbuch verwendet werden, sind Eigentum der entsprechenden Eigent"umer. \vspace{9cm} Dieses Dokument wurde mit dem LaTeX-Satzsystem unter den Betriebssystemen Digital Unix, Linux und OS/2 auf AMD K6- und DEC Alpha-Prozessoren angefertigt und formatiert. \clearpage %%=========================================================================== \ifelektor \thispagestyle{empty} \ \clearpage \thispagestyle{empty} \ \clearpage \fi %%=========================================================================== {\parskip 0cm plus0.1cm \tableofcontents} %%=========================================================================== \cleardoublepage \chapter{Allgemeines} Diese Anleitung wendet sich an Leute, die bereits in Assembler programmiert haben und sich dar"uber informieren m"ochten, wie man mit AS umgeht. Sie hat eher die Form eines Referenz- und nicht Benutzerhandbuches. Als solches macht sie weder den Versuch, die Sprache Assembler an sich zu erkl"aren, noch erl"autert sie die Architektur bestimmter Prozessoren. Im Literaturverzeichnis habe ich weiterf"uhrende Literatur aufgelistet, die bei der Implementation der einzelnen Codegeneratoren ma"sgebend war. Um Assembler von Grund auf zu lernen, kenne ich kein Buch; ich habe es im wesentlichen im ,,Trial and error''-Verfahren gelernt. %%--------------------------------------------------------------------------- \section{Lizenzbedingungen} \label{SectLicense} Bevor es in medias res geht, erst einmal der unvermeidliche Prolog: \par AS in der vorliegenden Version gebe ich als ,,Public Domain'' weiter, d.h. die Programm-und Overlaydatei sowie die dazugeh"orenden Hilfsprogramme d"urfen frei kopiert und benutzt werden. Es existieren keine Planungen, AS in ein kommerzielles oder Shareware-Programm umzuwandeln. Diese Erlaubnis gilt jedoch nur unter der Voraussetzung, da"s die Startmeldung der Programme --- insbesondere die Copyrightmeldung --- nicht entfernt oder "uberschrieben wird und f"ur das Kopieren/Verschicken nicht mehr als eine Aufwandsentsch"adigung (unter DM 20,-) verlangt wird. \par Auf Anfrage wird auch der Quellcode dieses Programmes ausgegeben. Daraus abgeleitete oder darauf aufbauende Programme m"ussen unter den gleichen Bedingungen weitergegeben werden wie dieses Programm. \par Ich fordere ausdr"ucklich dazu auf, dieses Programm per Diskette oder Mailbox/Netzwerk zu verbreiten! \par Es mag sein, da"s Sie dieses Programm als Beilage zu einem kommerziellen Programm erhalten haben. Die f"ur das kommerzielle Programm geltenden Lizenzbedingungen beziehen sich jedoch auf keinen Fall auf AS. \par Sollte Ihnen der Assembler so gut gefallen, da"s sie mir unbedingt Geld daf"ur schicken wollen, so fordere ich Sie dazu auf, den Betrag f"ur Greenpeace zu spenden. \par Ich habe mich bem"uht, das Programm so fehlerfrei wie nur irgendm"oglich zu machen. Da es aber grunds"atzlich keine fehlerfreie Software gibt (die einzigen Leute, die keine Fehler machen, liegen auf dem Friedhof!), "ubernehme ich keine Garantie f"ur die Funktion von AS in einer bestimmten Umgebung (Hard-oder Software) oder Haftung f"ur entstehende Sch"aden. F"ur Hinweise auf Fehler bin ich selbstverst"andlich immer dankbar und werde mich bem"uhen, sie zu korrigieren. \par Um eine m"oglichst schnelle Fehlerdiagnose und -korrektur zu erm"oglichen, bitte ich, dem Fehlerbericht folgende Angaben beizuf"ugen: \begin{itemize} \item{Hardware: \begin{itemize} \item{Prozessortyp (mit/ohne Koprozessor)} \item{Speicherausbau} \item{Grafikkarte} \item{Festplatte und Typ deren Interfaces} \end{itemize}} \item{Software: \begin{itemize} \item{Betriebssystem (MS/DR/Novell-DOS, OS/2, Windows) und Version} \item{installierte speicherresidente Programme} \item{benutzte Version von AS + Datum des EXE-Files} \end{itemize}} \item{m"oglicht die Quelldatei, bei der der Fehler auftritt} \end{itemize} Zu erreichen bin ich folgenderma"sen: \begin{itemize} \item{per Post: \begin{description} \item{Alfred Arnold} \item{Hirschgraben 29} \item{52062 Aachen} \end{description}} \item{per E-Mail: \tty{alfred@ccac.rwth-aachen.de}} \end{itemize} Wer mir pers"onlich Fragen stellen will (und in der N"ahe von Aachen wohnt), kann dies mit hoher Wahrscheinlichkeit donnerstags von 19.00 bis 21.00 Uhr im Computerclub an der RWTH Aachen (Eilfschornsteinstra"se 16, Keller Philosophengeb"aude R"uckseite). \par Von Telefonanrufen bitte ich abzusehen. Erstens, weil sich die komplizierten Zusammenh"ange am Telefon nur "au"serst schwer er"orten lassen, und zweitens ist die Telekom schon reich genug... \par Die neueste Version von AS (DOS,DPMI,OS/2) findet sich auf folgendem FTP-Server: \begin{verbatim} ftp.uni-stuttgart.de Verzeichnis pub/systems/msdos/programming/as \end{verbatim} Die Quellen der C-Version k"onnen von folgendem Server geholt werden: \begin{verbatim} sunsite.unc.edu Verzeichnis pub/Linux/devel/lang/assemblers/asl-.tar.gz \end{verbatim} ...und damit nat"urlich von jedem Sunsite-Spiegel der Welt! \par Wer "uber keinen FTP-Zugang verf"ugt, kann den Assembler auch von mir anfordern. Ich werde aber nur Anfragen beantworten, die zwei Disketten (f"ur 720K/1,2M-Format 4/3 St"uck) und einen passenden, frankierten R"uckumschlag enthalten. \bb{KEIN} Geld schicken!!! \par So. Nach diesem unvermeidlichen Vorwort k"onnen wir wohl beruhigt zur eigentlichen Anleitung schreiten: %%--------------------------------------------------------------------------- \section{allgemeine F"ahigkeiten des Assemblers} AS bietet im Gegensatz zu normalen Assemblern die M"oglichkeit, Code f"ur v"ollig verschiedene Prozessoren zu erzeugen. Momentan sind folgende Prozessorfamilien implementiert: \begin{itemize} \item{Motorola 68000..68040,683xx inkl. Koprozessor und MMU} \item{Motorola ColdFire} \item{Motorola DSP5600x,DSP56300} \item{Motorola/IBM MPC601/MPC505/PPC403} \item{Motorola M-Core} \item{Motorola 6800, 6805, 68HC08, 6809, 68(HC)11, 68HC12, 68HC16 sowie Hitachi 6301} \item{Hitachi 6309} \item{Hitachi H8/300(H)} \item{Hitachi H8/500} \item{Hitachi SH7000/7600/7700} \item{Rockwell 6502 und 65(S)C02} \item{CMD 65816} \item{Mitsubishi MELPS-740} \item{Mitsubishi MELPS-7700} \item{Mitsubishi MELPS-4500} \item{Mitsubishi M16} \item{Mitsubishi M16C} \item{Intel 4004} \item{Intel MCS-48/41} \item{Intel MCS-51/251} \item{Intel MCS-96/196(Nx)/296} \item{Intel 8080/8085} \item{Intel i960} \item{Signetics 8X30x} \item{Philips XA} \item{Atmel AVR} \item{AMD 29K} \item{Siemens 80C166/167} \item{Zilog Z80, Z180, Z380} \item{Zilog Z8} \item{Toshiba TLCS-900(L)} \item{Toshiba TLCS-90} \item{Toshiba TLCS-870} \item{Toshiba TLCS-47} \item{Toshiba TLCS-9000} \item{Microchip PIC16C54..16C57} \item{Microchip PIC16C84/PIC16C64} \item{Microchip PIC17C42} \item{SGS-Thomson ST6} \item{SGS-Thomson ST7} \item{SGS-Thomson ST9} \item{SGS-Thomson 6804} \item{Texas Instruments TMS32010/32015} \item{Texas Instruments TMS3202x} \item{Texas Instruments TMS320C3x} \item{Texas Instruments TMS320C20x/TMS320C5x} \item{Texas Instruments TMS320C6x} \item{Texas Instruments TMS9900} \item{Texas Instruments TMS7000} \item{Texas Instruments TMS370xxx} \item{Texas Instruments MSP430} \item{National Semiconductor SC/MP} \item{National Semiconductor COP8} \item{National Semiconductor SC144xx} \item{Fairchild ACE} \item{NEC $\mu$PD78(C)1x} \item{NEC $\mu$PD75xxx (alias 75K0)} \item{NEC $\mu$PD78xxx (alias 78K0)} \item{NEC $\mu$PD7720/7725} \item{NEC $\mu$PD77230} \item{Fujitsu F$^2$MC8L} \item{Symbios Logic SYM53C8xx (ja, die kann man programmieren!)} \end{itemize} in Arbeit / Planung / "Uberlegung : \begin{itemize} \item{Intel 8008} \item{Analog Devices ADSP21xx} \item{SGS-Thomson ST20} \item{Texas Instruments TMS320C4x} \item{Texas Instruments TMS320C8x} \item{Toshiba TC9331} \end{itemize} Noch gesucht werden Unterlagen f"ur: \begin{itemize} \item{NEC 78K4} \item{die ganze Palette der OKI-Controller} \end{itemize} ungeliebt, aber {\it doch} vorhanden : \begin{itemize} \item{Intel 8086, 80186, NEC V30\&V35 inkl. Koprozessor 8087} \end{itemize} Die Umschaltung des Codegenerators darf dabei auch mitten in der Datei erfolgen, und das beliebig oft! \par Der Grund f"ur diese Flexibilit"at ist, da"s AS eine Vorgeschichte hat, die auch in der Versionsnummer deutlich wird: AS ist als Erweiterung eines Makroassemblers f"ur die 68000er-Familie entstanden. Auf besonderen Wunsch habe ich den urspr"unglichen Assembler um die F"ahigkeit zur "Ubersetzung von 8051-Mnemonics erweitert, und auf dem Weg (Abstieg?!) vom 68000 zum 8051 sind eine Reihe anderer fast nebenbei abgefallen...die restlichen Prozessoren wurden allesamt auf Benutzeranfrage hin integriert. Zumindest beim prozessorunabh"angigen Kern kann man also getrost davon ausgehen, da"s er gut ausgetestet und von offensichtlichen Bugs frei ist. Leider habe ich aber h"aufig mangels passender Hardware nicht die M"oglichkeit, einen neuen Codegenerator praktisch zu testen, so da"s bei Neuerungen "Uberraschungen nie ganz auszuschlie"sen sind. Das in Abschnitt \ref{SectLicense} gesagte hat also schon seinen Grund... \par Diese Flexibilit"at bedingt ein etwas exotisches Codeformat, f"ur dessen Bearbeitung ich einige Tools beigelegt habe. Deren Beschreibung findet sich in Abschnitt \ref{ChapTools}. \par AS ist ein Makroassembler, d.h. dem Programmierer ist die M"oglichkeit gegeben, sich mittels Makros neue ,,Befehle'' zu definieren. Zus"atzlich beherrscht er die bedingte Assemblierung. Labels in Makror"umpfen werden automatisch als lokal betrachtet. \par Symbole k"onnen f"ur den Assembler sowohl Integer-, String- als auch Gleitkommawerte haben. Diese werden --- wie Zwischergebnisse bei Formeln --- mit einer Breite von 32 Bit f"ur Integerwerte, 80/64 Bit f"ur Gleitkommawerte und 255 Zeichen f"ur Strings gespeichert. F"ur eine Reihe von Mikrokontrollern besteht die M"oglichkeit, durch Segmentbildung die Symbole bestimmten Klassen zuzuordnen. Dem Assembler kann man auf diese Weise die --- begrenzte --- M"oglichkeit geben, Zugriffe in falsche Adre"sr"aume zu erkennen. \par Der Assembler kennt keine expliziten Beschr"ankungen bzgl. Verschachtelungstiefe von Includefiles oder Makros, eine Grenze bildet lediglich die durch den Hauptspeicher beschr"ankte Rekursionstiefe. Ebenso gibt es keine Grenze f"ur die Symboll"ange, diese wird nur durch die maximale Zeilenl"ange begrenzt. \par Ab Version 1.38 ist AS ein Mehrpass-Assembler. Dieser hochtrabende Begriff bedeutet nicht mehr, als das die Anzahl der Durchg"ange durch die Quelltexte nicht mehr zwei sein mu"s. Sind keine Vorw"artsreferenzen im Quellcode enthalten, so kommt AS mit einem Durchgang aus. Stellt sich dagegen im zweiten Durchgang heraus, da"s ein Befehl mit einer k"urzeren oder l"angeren Kodierung benutzt werden mu"s, so wird ein dritter (vierter, f"unfter...) Durchgang eingelegt, um alle Symbolreferenzen richtig zu stellen. Mehr steckt hinter dem Begriff ,,Multipass'' nicht...er wird im weiteren Verlauf dieser Anleitung deswegen auch nicht mehr auftauchen. \par Nach soviel Lobhudelei ein dicker Wermutstropfen: AS erzeugt keinen linkf"ahigen Code. Eine Erweiterung um einen Linker w"are mit erheblichem Aufwand verbunden und ist momentan nicht in Planung. \par Zum Thema ,,Herausgabe von Sourcen'': Die Sourcen von AS sind nicht in einer Form, die ein einfaches Verst"andnis erm"oglicht (== null Kommentare). Sourcen werde ich daher nur f"ur den Fall herausgeben, da"s jemand wirklich damit etwas anfangen will (z.B. AS auf einen anderen Rechner portieren) und das daraus entstehende wiederum Public Domain wird. Insbesondere will ich verhindern, da"s jemand 5 Zeilen "andert (bevorzugt den Copyrighteintrag) und das Ergebnis dann kommerziell als ,,sein'' Programm vertreibt. %%---------------------------------------------------------------------- \section{Unterst"utzte Plattformen} Obwohl AS als ein reines DOS-Programm \marginpar{{\em DOS}} angefangen hat, stehen auch eine Reihe von Versionen zur Verf"ugung, die etwas mehr als den Real-Mode eines Intel-Prozessors ausnutzen k"onnen. Diese sind in ihrer Benutzung soweit als m"oglich kompatibel gehalten zur DOS-Version, es ergeben sich nat"urlich bisweilen Unterschiede in der Installation und der Einbindung in die jeweilige Betriebssystemumgebung. Abschnitte in dieser Anleitung, die nur f"ur eine bestimmte Version von AS gelten, sind mit einer entsprechenden Randbemerkung (an diesem Absatz f"ur die DOS-Version) gekennzeichnet. Im einzelnen existieren die folgenden, weiteren Versionen (die als getrennte Pakete distributiert werden): F"ur den Fall, da"s \marginpar{{\em DPMI}} man bei der "Ubersetzung gro"ser, komplexer Programme unter DOS Speicherplatzprobleme bekommt, existiert eine DOS-Version, die mittels eines DOS-Extenders im Protected Mode abl"auft und so das komplette Extended Memory eines ATs nutzen kann. Die "Ubersetzung wird durch den Extender merklich langsamer, aber immerhin l"auft es dann noch... F"ur Freunde von IBM's Betriebssystem OS/2 \marginpar{{\em OS/2}} gibt es eine native OS/2-Version von AS. Diese ist zwar zur Zeit nur 16-bittig, aber man erspart sich immerhin den Umweg "uber DOS-Boxen und hat auch keine Probleme mehr mit l"angeren Dateinamen. Den reinen PC-Bereich verl"a"st man mit der \marginpar{{\em UNIX}} C-Version von AS, die so gehalten wurde, da"s sie auf einer m"oglichst gro"sen Zahl von UNIX-artigen Systemen (dazu z"ahlt aber auch OS/2 mit dem emx-Compiler) ohne gro"sartige Verrenkungen "ubersetzbar ist. Im Gegensatz zu den vorherigen Versionen (die auf den auf Anfrage erh"altlichen Pascal-Sourcen basieren) wird die C-Version im Quellcode ausgeliefert, d.h. man mu"s sich mittels eines Compilers selbst die Binaries erzeugen. Dies ist aber (f"ur mich) der eindeutig einfachere Weg, als ein Dutzend Binaries f"ur Maschinen vorzukompilieren, auf die ich auch nicht immer Zugriff habe... Wer die bisherige \marginpar{{\em ???}} Aufz"ahlung liest, wird feststellen, da"s das meistverkaufte Betriebssystem der Welt aus Redmont in dieser Aufz"ahlung fehlt. Wer mich pers"onlich kennt, wei"s, da"s ich Windows (egal, ob 3.X, 95 oder NT) {\em nicht} f"ur das Ei des Kolumbus halte. Kurzgesagt, ich bin ein ,,Windows-Hasser''. Auch wenn eine gro"se Zahl an Leuten diese Einstellung f"ur "uberholt bis l"acherlich erachten und mir jetzt vorhalten, ich w"urde hier einem gro"sen Teil potentieller Anwender AS vorenthalten, so werden sie sich doch damit abfinden m"ussen: Ich treibe die Entwicklung an AS prim"ar weiter, weil sie mir {\em Spa"s} macht; AS ist ein nicht-kommerzielles Projekt und ich nehme mir deswegen die Freiheit, nicht auf potentielle Marktanteile zu schielen. Ich suche mir die Plattformen aus, auf denen das Programmieren {\em mir} Spa"s macht, und Programmieren unter Windows macht mir definitiv keinen Spa"s! Ich habe "ubrigens durchaus schon einmal Windows-Programme schreiben m"ussen, es ist also nicht so, da"s ich hier ohne Erfahrung etwas daherreden w"urde. Sofern irgendjemand AS in diese Richtung portieren will, werde ich mich ihm nicht in den Weg stellen, "uber die Sourcen hinaus hat er aber nicht viel Hilfe von mir zu erwarten (und mu"s sich selber mit den Anfragen der Qualit"at herumschlagen, warum AS denn jetzt nicht mehr l"auft, nachdem man den Brummi-CAD 18.53-Eintrag in der Registry von Gro"s- in Kleinbuchstaben ge"andert hat...). %%=========================================================================== \cleardoublepage \chapter{Benutzung des Assemblers} \begin{quote}\begin{raggedright}{\it Scotty: Captain, we din\verb!'! can reference it! \\ Kirk: Analysis, Mr. Spock? \\ Spock: Captain, it doesn\verb!'!t appear in the symbol table. \\ Kirk: Then it\verb!'!s of external origin? \\ Spock: Affirmative. \\ Kirk: Mr. Sulu, go to pass two. \\ Sulu: Aye aye, sir, going to pass two. \\ }\end{raggedright}\end{quote} %%--------------------------------------------------------------------------- \section{Hardware-Anforderungen} Je nach Version von AS variieren die Hardware-Anforderungen deutlich: Die DOS-Version \marginpar{{\em DOS}} l"auft prinzipiell auf allen IBM-kompatiblen PCs, angefangen vom PC/XT mit vierkommawenig Megaherz bis hin zum Pentium. Wie bei vielen anderen Programmen aber auch, steigt der Lustgewinn mit der Hardware-Ausstattung. So d"urfte ein XT-Benutzer ohne Festplatte erhebliche Probleme haben, die "uber 500 Kbyte gro"se Overlay-Datei von AS auf einer Diskette unterzubringen...eine Festplatte sollte der PC also schon haben, allein um vern"unftige Ladezeiten zu erreichen. Im Hauptspeicherbedarf ist AS recht gen"ugsam: Das Programm selber belegt knapp 300 Kbyte Hauptspeicher, AS sollte also ab einer Hauptspeichergr"o"se von 512 Kbyte ausf"uhrbar sein. Die Version von AS f"ur das \marginpar{{\em DPMI}} DOS-Protected-Mode-Interface (DPMI) ben"otigt zum Ablaufen mindestens einen 80286-Prozessor und 1 Mbyte freies extended memory. Daher stellen 2 Mbyte Hauptspeicher das absolute Minimum dar, wenn man im XMS sonst keine anderen Spielereien (Platten-Cache, RAM-Disk, hochgeladenes DOS) installiert hat, sonst entsprechend mehr. Falls man die DPMI-Version in einer DOS-Box von OS/2 laufen l"a"st, so sollte DPMI auch in den DOS-Einstellungen der Box erlaubt sein (Einstellung \tty{An} oder \tty{Auto}) und der Box eine entsprechende Menge von XMS-Speicher zugeordnet sein. Die virtuelle Speicherverwaltung von OS/2 sorgt hier "ubrigens daf"ur, da"s man sich keine Gedanken machen mu"s, ob der eingestellte Speicher auch real verf"ugbar ist. Die Hardware-Anforderungen der \marginpar{{\em OS/2}} OS/2-Version ergeben sich weitestgehend durch die des darunterliegenden Betriebssytemes, d.h. mindestens ein 80386SX-Prozessor, 8 Mbyte RAM (bzw. 4 ohne grafische Benutzeroberfl"ache) sowie ca 100..150 Mbyte Platz auf der Festplatte. Da AS2 nur eine 16-Bit-Applikation ist, sollte er theoretisch auch auf "alteren OS/2-Versionen (und damit 80286-Prozessoren) lauff"ahig sein; ausprobieren konnte ich dies aber nicht. Die C-Version \marginpar{{\em UNIX}} von AS wird im Quellcode ausgeliefert und erfordert damit ein Unix- oder OS/2-System mit einem C-Compiler. Der Compiler mu"s dem ANSI-Standard gen"ugen (GNU-C erf"ullt diese Bedingung zum Beispiel). Ob Ihr UNIX-System bereits getestet und die n"otigen Definitionen vorgenommen wurden, k"onnen Sie der \tty{README}-Datei entnehmen. Als zur Kompilation ben"otigten Plattenplatz sollten Sie ca. 15 Mbyte veranschlagen; dieser Wert (und der nach der "Ubersetzung noch ben"otigte Platz f"ur die "ubersetzten Programme) variiert allerdings stark von System zu System, so da"s man diesen Wert nur als Richtschnur betrachten sollte. %%--------------------------------------------------------------------------- \section{Lieferumfang} Prinzipiell erh"alt man AS in einer von zwei Formen: Als {\em Bin"ardistribution} oder {\em Quellcodedistribution}. Im Falle einer Bin"ardistribution bekommt man AS mit den zugeh"origen Dienstprogrammen und Hilfsdateien fertig "ubersetzt, so da"s man nach dem Auspacken des Archivs an die gew"unschte Stelle direkt loslegen kann. Bin"ardistributionen werden f"ur verbreitete Plattformen gemacht, bei denen die Mehrzahl der Benutzer keinen Compiler hat oder die "Ubersetzung trickreich ist (im Moment sind dies DOS und OS/2). Eine Quellcodedistribution enth"alt im Gegensatz den kompletten Satz an C-Quellen, um AS zu generieren; es ist letzten Endes ein Schnappschu"s des Quellenbaumes, an dem ich AS weiterentwickele. Die Generierung von AS aus dem Quellcode und dessen Struktur ist n"aher in Anhang \ref{ChapSource} beschrieben, weshalb an dieser Stelle nur auf den Umfang und die Installation einer Bin"ardistribution beschrieben wird: Das Archiv des Lieferumfangs gliedert sich in einige Unterverzeichnisse, so da"s man nach dem Auspacken sofort einen Verzeichnisbaum erh"alt. Die Verzeichnisse enthalten im einzelnen: \begin{itemize} \item{{\tt BIN}: ausf"uhrbare Programme, Text-Resourcen;} \item{{\tt INCLUDE}: Include-Dateien f"ur Assemblerprogramme, z.B. Registerdefinitionen oder Standardmakros;} \item{{\tt MAN}: Kurzreferenzen f"ur die Programme im Unix-Man-Format;} \item{{\tt DOC}: diese Dokumentation in verschiedenen Formaten;} \item{{\tt LIB}: vorgesehen f"ur Initialisierungsdateien.} \end{itemize} Eine Auflistung der Dateien, die in jeder Bin"ardistribution enthalten sind, findet sich in den Tabellen \ref{TabCommonPackageList1} und \ref{TabCommonPackageList2}. Falls eine der in diesen (oder den folgenden) Tabellen aufgef"uhrten Dateien fehlt, hat jemand (im Zweifelsfalle ich) beim Kopieren geschlafen... \begin{table*}[htp] \begin{center}\begin{tabular}{|l|l|} \hline Datei & Funktion \\ \hline \hline {\bf Verzeichnis BIN} & \\ \hline AS.EXE & Programmdatei Assembler \\ PLIST.EXE & listet Inhalt von Codedateien auf \\ PBIND.EXE & kopiert Codedateien zusammen \\ P2HEX.EXE & wandelt Code- in Hexdateien um \\ P2BIN.EXE & wandelt Code- in Bin"ardateien um \\ AS.MSG & Textresourcen zu AS \\ PLIST.MSG & Textresourcen zu PLIST \\ PBIND.MSG & Textresourcen zu PBIND \\ P2HEX.MSG & Textresourcen zu P2HEX \\ P2BIN.MSG & Textresourcen zu P2BIN \\ TOOLS.MSG & gemeinsame Textresourcen zu den Tools \\ CMDARG.MSG & gemeinsame Textresourcen zu allen Programmen \\ DECODECMD.MSG & \\ IOERRS.MSG & \\ \hline \hline {\bf Verzeichnis DOC} & \\ \hline AS\_DE.DOC & deutsche Dokumentation, ASCII-Format \\ AS\_DE.HTML & deutsche Dokumentation, HTML-Format \\ AS\_DE.TEX & deutsche Dokumentation, LaTeX-Format \\ AS\_EN.DOC & englische Dokumentation, ASCII-Format \\ AS\_EN.HTML & englische Dokumentation, HTML-Format \\ AS\_EN.TEX & englische Dokumentation, LaTeX-Format \\ \hline \hline {\bf Verzeichnis INCLUDE} & \\ \hline BITFUNCS.INC & Funktionen zur Bitmanipulation \\ CTYPE.INC & Funktionen zur Klassifizierung von \\ & Zeichen \\ 80C50X.INC & Registeradressen SAB C50x \\ 80C552.INC & Registeradressen 80C552 \\ H8\_3048.INC & Registeradressen H8/3048 \\ REG166.INC & Adressen \& Befehlsmakros 80C166/167 \\ REG251.INC & Adressen \& Bits 80C251 \\ REG29K.INC & Peripherieadressen AMD 2924x \\ REG53X.INC & Registeradressen H8/53x \\ REG683XX.INC & Registeradressen 68332/68340/68360 \\ REG7000.INC & Registeradressen TMS70Cxx \\ REG78K0.INC & Registeradressen 78K0 \\ REG96.INC & Registeradressen MCS-96 \\ REGACE.INC & Registeradressen ACE \\ \hline \end{tabular}\end{center} \caption{Standardumfang einer Bin"ardistribution - Teil 1 \label{TabCommonPackageList1}} \end{table*} \begin{table*}[htp] \begin{center}\begin{tabular}{|l|l|} \hline Datei & Funktion \\ \hline \hline {\bf Verzeichnis INCLUDE} & \\ \hline REGAVR.INC & Register- \& Bitadressen AVR-Familie \\ REGCOP8.INC & Registeradressen COP8 \\ REGHC12.INC & Registeradressen 68HC12 \\ REGM16C.INC & Registeradressen Mitsubishi M16C \\ REGMSP.INC & Registeradressen TI MSP430 \\ REGST9.INC & Register- \& Makrodefinitionen ST9 \\ REGZ380.INC & Registeradressen Z380 \\ STDDEF04.INC & Registeradressen 6804 \\ STDDEF16.INC & Befehlsmakros und Registeradressen \\ & PIC16C5x \\ STDDEF17.INC & Registeradressen PIC17C4x \\ STDDEF18.INC & Registeradressen PIC16C8x \\ STDDEF2X.INC & Registeradressen TMS3202x \\ STDDEF37.INC & Register- \& Bitadressen TMS370xxx \\ STDDEF3X.INC & Peripherieadressen TMS320C3x \\ STDDEF47.INC & Befehlsmakros TLCS-47 \\ STDDEF51.INC & Definition von SFRs und Bits f"ur \\ & 8051/8052/80515 \\ STDDEF56K.INC & Registeradressen DSP56000 \\ STDDEF5X.INC & Peripherieadressen TMS320C5x \\ STDDEF60.INC & Befehlsmakros \& Registeradressen \\ & PowerPC \\ STDDEF62.INC & Registeradressen \& Makros ST6 \\ STDDEF75.INC & Registeradressen 75K0 \\ STDDEF87.INC & Register- \& Speicheradressen TLCS-870 \\ STDDEF90.INC & Register- \& Speicheradressen TLCS-90 \\ STDDEF96.INC & Register- \& Speicheradressen TLCS-900 \\ STDDEFXA.INC & SFR-\& Bitadressen Philips XA \\ STDDEFZ8.INC & Registeradressen Z8-Familie \\ \hline \hline {\bf Verzeichnis LIB} & \\ \hline \hline {\bf Verzeichnis MAN} & \\ \hline ASL.1 & Kurzanleitung zu AS \\ PLIST.1 & Kurzanleitung zu PLIST \\ PBIND.1 & Kurzanleitung zu PBIND \\ P2HEX.1 & Kurzanleitung zu P2HEX \\ P2BIN.1 & Kurzanleitung zu P2BIN \\ \hline \end{tabular}\end{center} \caption{Standardumfang einer Bin"ardistribution - Teil 2 \label{TabCommonPackageList2}} \end{table*} Je nach Plattform kann eine Bin"ardistribution aber noch weitere Dateien enthalten, um einen Betrieb zu erm"oglichen, wie es z.B. bei DOS-Extendern der Fall ist. F"ur die DOS-DPMI-Version \marginpar{{\em DPMI}} ergeben sich die in Tabelle \ref{TabDPMIPackageList} gelisteten Erg"anzungen. Es spricht "ubrigens nichts dagegen, als Hilfsprogramme die Versionen aus einer DOS-Distribution zu verwenden, da diese einerseits ohne den Extender-Overhead deutlich schneller ablaufen und andererseits den vom Extender bereitgestellten erweiterten Speicher nicht ben"otigen. \begin{table*}[htp] \begin{center}\begin{tabular}{|l|l|} \hline Datei & Funktion \\ \hline \hline {\bf Verzeichnis BIN} & \\ \hline DPMI16BI.OVL & DPMI-Server f"ur den Assembler \\ RTM.EXE & Laufzeit-Modul des Extenders \\ \hline \end{tabular}\end{center} \caption{Zus"atzliche Dateien in einer DPMI-Bin"ardistribution \label{TabDPMIPackageList}} \end{table*} Eine OS/2-Bin"ardistribution \marginpar{{\em OS/2}} enth"alt neben den Basisdateien eine Reihe von DLLs, die zur Laufzeitumgebung des verwendeten emx-Compilers geh"oren (Tabelle \ref{TabOS2PackageList}). Falls man diese DLLs (oder neuere Versionen davon) bereits besitzt, kann man diese auch wieder l"oschen und seine eigenen benutzen. \begin{table*}[htp] \begin{center}\begin{tabular}{|l|l|} \hline Datei & Funktion \\ \hline \hline {\bf Verzeichnis BIN} & \\ \hline EMX.DLL & Laufzeitbibliotheken f"ur AS und \\ EMXIO.DLL & die Dienstprogramme \\ EMXLIBC.DLL & \\ EMXWRAP.DLL & \\ \hline \end{tabular}\end{center} \caption{Zus"atzliche Dateien in einer OS/2-Bin"ardistribution \label{TabOS2PackageList}} \end{table*} %%--------------------------------------------------------------------------- \section{Installation} Eine besondere \marginpar{{\em DOS}} Installation ist f"ur die Nutzung einer Bin"ardistribution nicht notwendig, es gen"ugt, das Archiv an passender Stelle auszupacken und dann noch einige Kleinigkeiten zu erg"anzen. Als Beispiel hier eine Installation, wie sie vielleicht ein UNIX-Anh"anger vornehmen w"urde: Legen Sie ein Verzeichnis \verb!c:\as! an (im folgenden nehme ich an, da"s Sie AS auf Laufwerk C installieren wollen), wechseln Sie in dieses und entpacken Sie das Archiv unter Erhalt der Verzeichnisnamen (bei Verwendung von PKUNZIP ist dazu die Kommandozeilenoption \verb!-d! erforderlich). Sie sollten jetzt folgenden Verzeichnisbaum haben: \begin{verbatim} c:\as c:\as\bin c:\as\include c:\as\lib c:\as\man c:\as\doc \end{verbatim} Erg"anzen Sie jetzt die \tty{PATH}-Anweisung in Ihrer \tty{AUTOEXEC.BAT} um das Verzeichnis \verb!c:\as\bin!, so da"s AS und seine Hilfsprogramme vom System gefunden werden. In dem \tty{lib}-Verzeichnis erzeugen Sie mit einem beliebigen Texteditor eine Datei \tty{AS.RC} mit folgendem Inhalt: \begin{verbatim} -i c:\as\include \end{verbatim} Diese sogenannte {\em Key-Datei} zeigt AS, in welchem Verzeichnis er seine Include-Dateien suchen soll. Damit AS diese Key-Datei bei Start auch beachtet, mu"s noch folgende Anweisung in die \tty{AUTOEXEC.BAT}: \begin{verbatim} set ASCMD=@c:\as\lib\as.rc \end{verbatim} Was Sie alles noch in der Key-Datei voreinstellen k"onnen, steht im folgenden Abschnitt. Die Installation der DPMI-Version \marginpar{{\em DPMI}} sollte im Prinzip genauso verlaufen wie der reinen DOS-Version; wenn der Pfad das {\tt bin}-Verzeichnis enth"alt, werden die Dateien des DOS-Extenders automatisch gefunden und man sollte von dieser Mimik (mit Ausnahme der l"angeren Anlaufzeit...) nichts mitbekommen. Theoretisch ist es m"oglich, da"s Sie auf 80286-Rechnern beim ersten Start mit einer Meldung der folgenden Form konfrontiert werden: \begin{verbatim} machine not in database (run DPMIINST) \end{verbatim} Da das Tool DPMIINST bei neueren Versionen des DOS-Extenders von Borland aber nicht mehr dabei ist, nehme ich einmal an, da"s diese Sache sich erledigt hat...falls doch nicht, bitte ich um R"uckmeldung! Die Installation der OS/2-Version \marginpar{{\em OS/2}} kann in weiten Z"ugen genauso ablaufen wie f"ur die DOS-Version, nur da"s dem System noch die DLLs bwkannt gemacht werden m"ussen. Wenn Sie den {\tt LIBPATH}-Eintrag in Ihrer {\tt CONFIG.SYS} nicht erweitern wollen, ist es nat"urlich auch m"oglich, die DLLs in ein Verzeichnis zu verschieben, das bereits dort aufgef"uhrt ist. Wie bereits erw"ahnt, beschr"ankt sich die Installationsbeschreibung hier nur auf Bin"ardistributionen. Da eine Installation unter Unix \marginpar{{\em UNIX}} im Augenblick immer eine Quellcodedistribution ist, geht der Verweis hier unisono in Anhang \ref{ChapSource}. %%--------------------------------------------------------------------------- \section{Aufruf, Parameter}\label{SectCallConvention} AS ist ein kommandozeilengesteuertes Programm, d.h. alle Parameter und Dateiangaben sind in der Kommandozeile anzugeben. Zu AS geh"ort eine Reihe Reihe von Nachrichtendateien (erkennbar an der Endung {\tt MSG}, aus denen AS zur Laufzeit die f"ur die jeweilige Landessprache dynamisch nachl"adt. AS sucht nach diesen Dateien in den folgenden Verzeichnissen: \begin{itemize} \item{im aktuellen Verzeichnis;} \item{im Verzeichnis der EXE-Datei;} \item{in dem in der Environment-Variablen {\tt AS\_MSGPATH} angegebenen Verzeichnis, oder alternativ in den in der {\tt PATH}-Variablen gelisteten Verzeichnissen;} \item{In dem Verzeichnis, das AS zur Kompilationszeit durch das Makro {\tt LIBDIR} mitgegeben wurde.} \end{itemize} Diese Dateien werden von AS {\em zwingend} zum Betrieb ben"otigt, d.h. findet AS diese Dateien nicht, bricht er an dieser Stelle sofort ab. Die Auswahl der Sprache (momentan Deutsch oder Englisch) orientiert sich unter DOS und OS/2 an der {\tt COUNTRY}-Einstellung in der {\tt CONFIG.SYS}, unter Unix an der {\tt LANG}-Environment-Variablen. Um den \marginpar{{\em DOS}} Speicherbedarf von AS unter DOS "uberhaupt befriedigen zu k"onnen, wurden die verschiedenen Codegeneratormodule in der DOS-Version in einen Overlay verlegt, der Teil des EXE-Files ist. Eine getrennte OVR-Datei wie bei fr"uheren Versionen von AS existiert also nicht mehr, AS versucht aber wie bisher auch weiterhin, die durch das Overlaying entstehenden Verzögerungen durch Nutzung von eventuellem EMS- oder XMS-Speicher zu reduzieren. Sollte diese Verwendung zu Problemen f"uhren, so k"onnen Sie die Verwendung von EMS bzw. XMS unterbinden, indem Sie einer Environment-Variablen \tty{USEXMS} bzw. \tty{USEEMS} den Wert \tty{n} zuweisen. So kann man z.B. mit dem Befehl \begin{verbatim} SET USEXMS=n \end{verbatim} die Verwendung von extended memory verhindern. \par Da AS alle Ein-und Ausgaben "uber das Betriebssystem abwickelt (und daher unter DOS auch auf nicht ganz so kompatiblen PC's laufen sollte) und eine rudiment"are Bildschirmsteuerung ben"otigt, gibt er w"ahrend der Assemblierung ANSI-Steuersequenzen aus. Falls Sie in den Ausgaben von AS \marginpar{{\em DOS/}} also seltsame Zeichen sehen sollten, fehlt offensichtlich in Ihrer CONFIG.SYS die Einbindung des ANSI-Trei\-bers (\tty{device=\-ansi.sys}), die weitere Funktion von AS \marginpar{{\em DPMI}} wird dadurch aber nicht beeinflu"st. Alternativ k"onnen Sie aber auch die Ausgabe von ANSI-Sequenzen durch das Setzen der Environment-Variablen \tty{USEANSI} auf \tty{n} ganz unterdr"ucken. Der DOS-Extender der DPMI-Version \marginpar{{\em DPMI}} l"a"st sich in seiner Speicherbelegung durch diverse Kommandozeilenoptionen beeinflussen. Diese k"onnen Sie bei Bedarf der Datei DPMIUSER.DOC entnehmen. Zus"atzlich ist ASX in der Lage, bei Bedarf den vorhandenen Speicher durch eine Swap-Datei zu ,,erweitern''. Dazu belegt man eine Environment-Variable \tty{ASXSWAP} folgenderma"sen: \begin{quote}{\tt SET ASXSWAP=$<$Gr"o"se$>$[,Dateiname] }\end{quote} Die Gr"o"senangabe erfolgt in Megabytes und \bb{mu"s} gemacht werden. Der Name der Datei ist dagegen optional; fehlt er, so wird die Swap-Datei im aktuellen Verzeichnis unter dem Namen \tty{ASX.TMP} angelegt. In jedem Falle wird die Swap-Datei nach Programmende wieder gel"oscht. Die Kommandozeilenparameter k"onnen grob in drei Klassen eingeteilt werden: Schalter, Key-File-Referenzen (s.u.) und Dateispezifikationen. Parameter dieser beiden Klassen k"onnen beliebig gemischt in der Kommandozeile auftreten, AS wertet zuerst alle Parameter aus und assembliert dann die angegebenen Dateien. Daraus folgen zwei Dinge: \begin{itemize} \item{Die angegebenen Schalter wirken auf alle angegebenen Quelldateien. Sollen mehrere Quelldateien mit unterschiedlich gesetzten Schaltern assembliert werden, so mu"s dies in getrennten L"aufen erfolgen.} \item{Es k"onnen in einem Durchgang mehrere Dateien assembliert werden. Um der Sache die Krone aufzusetzen, d"urfen die Dateiangaben Jokerzeichen enthalten.} \end{itemize} Schalterparameter erkennt AS daran, da"s sie durch einen Schr"agstrich (/) oder Bindestrich (-) eingeleitet werden. Es gibt dabei sowohl Schalter, die nur aus einem Buchstaben bestehen, als auch Schalter, die aus einem ganzen Wort bestehen. Immer wenn AS einen Schalter nicht als ,,Wort-Schalter'' verstehen kann, so versucht er, die Buchstaben des Wortes als einzelne Schalter zu interpretieren. Wenn man also z.B. \begin{verbatim} -queit \end{verbatim} anstelle von \begin{verbatim} -quiet \end{verbatim} geschrieben h"atte, w"urde AS die Buchstaben \tty{q, u, e, i} und \tty{t} als einzelne Schalter auffassen. Mehrbuchstabige Schalter unterscheiden sich weiterhin von einbuchstabigen dadurch, da"s AS bei ihnen beliebige Gro"s-und Kleinschreibungen akzeptiert, w"ahrend einbuchstabige Schalter je nach Gro"s- oder Kleinschreibung unterschiedliche Bedeutung haben. \par Momentan sind folgende Schalter definiert: \ttindex{SHARED} \begin{itemize} \item{\tty{l}: Assemblerlisting auf Konsole ausgeben. Falls mehrere Passes ausgef"uhrt werden m"ussen, landen im Gegensatz zur n"achsten Option die Listings aller Durchg"ange auf der Ausgabe!} \item{\tty{L}: Assemblerlisting auf Datei schreiben. Die Listdatei erh"alt dabei den gleichen Namen wie die Quelldatei, lediglich die Endung wird durch \tty{LST} ersetzt.} \item{\tty{o}:Bestimmt einen neuen Namen f"ur die von AS zu erzeugende Code-Datei. Wird diese Option mehrfach verwendet, so werden die angegebenen Namen nacheinander den zu assemblierenden Quelldateien zugeordnet; Negation (s.u.) dieser Option in Verbindung mit einem Namen l"oscht den Namen aus der Liste; Negation ohne Namensangabe l"oscht die komplette Liste.} \item{\tty{SHAREOUT}:dito, nur f"ur eine eventuell zu erzeugende SHARE-Datei} \item{\tty{c}: SHARED-Variablen werden in einem Format abgelegt, das die Einbindung in eine C-Quelldatei erlaubt. Die Endung der Datei ist \tty{H}.} \item{\tty{p}: SHARED-Variablen werden in einem Format abgelegt, das die Einbindung in den \tty{CONST}-Block eines Pascal- oder Modula-Programmes erlaubt. Die Endung der Datei ist \tty{INC}.} \item{\tty{a}: SHARED-Variablen werden in einem Format abgelegt, das die Einbindung in eine Assembler-Quelldatei erlaubt. Die Endung der Datei ist \tty{INC}.} \end{itemize} Zu Sinn und Funktion der SHARED-Symbole siehe Kapitel \ref{ChapShareMain} bzw. \ref{ChapShareOrder}. \begin{itemize} \item{\tty{g [Format]}: Mit diesem Schalter erzeugt AS zus"atzlich eine Datei, die Debug-Informationen f"ur dieses Programm enth"alt. Als Format ist dabei entweder ein AS-eigenes \tty{MAP}-Format, eine \tty{NoICE}-kompatible Kommandodatei oder das \tty{ATMEL}-Format der AVR-Tools erlaubt. Zu den im MAP-Format gespeicherten Informationen geh"ort zum einen die Symboltabelle, zum anderen eine Zuordnung von Quellzeilen zu Maschinenadressen. Eine genauere Beschreibung des benutzten MAP-Dateiformates findet sich in Abschnitt \ref{SectDebugFormat}. Die Endung der Datei ist \tty{MAP}, \tty{NOI} bzw. \tty{OBJ}, je nach gew"ahltem Format. Wird keine explizite Formatangabe gemacht, wird das MAP-Format gew"ahlt.} \item{\tty{w}: Ausgabe von Warnungen unterdr"ucken;} \item{\tty{E [Datei]}: Die von AS erzeugten Fehlermeldungen und Warnungen in eine Datei umleiten. Anstatt einer Datei k"onnen auch die 5 Standardhandles (STDIN..STDPRN) als !0 bis !4 angegeben werden. Default ist !2, also STDERR. Wird die Dateiangabe weggelassen, so ist der Name der Fehlerdatei gleich dem der Quelldatei, nur mit der Endung \tty{LOG}.} \item{\tty{q}: Dieser Schalter unterdr"uckt alle Meldungen von AS mit Ausnahme von Fehlermeldungen und vom Programm selber erzeugten Ausgaben. Die Assemblierzeit kann dadurch geringf"ugig reduziert werden, und beim Aufruf aus einer Shell heraus kann man sich eine Umleitung ersparen. Der Nachteil ist, da"s man u.U. einige Minuten ,,im Dunklen'' steht... Anstelle von 'q' darf auch 'quiet' geschrieben werden.} \item{\tty{h}: Hexadezimalzahlen mit Klein- anstelle von Gro"sbuchstaben ausgeben. Diese Option ist in erster Linie eine Frage des pers"onlichen Geschmacks.} \item{\tty{i $<$Pfadliste$>$}: gibt eine Liste von Verzeichnissen an, in denen der Assembler automatisch nach Include-Dateien suchen soll, falls er diese nicht im aktuellen Verzeichnis findet. Die einzelnen Verzeichnisse m"ussen durch Semikolons getrennt werden.} \item{\tty{u}: eine Liste der in den Segmenten belegten Bereiche berechnen. Sie ist nur sinnvoll, falls ein Listing erzeugt wird. Diese Option ben"otigt erhebliche zus"atzliche Speicher- und Rechenleistung, im Normalbetrieb sollte sie daher abgeschaltet sein. Da AS aber unabh"angig vom eingeschalteten Listing mit dieser Option auf "uberlappende Speicherbelegung pr"uft, hat sie auch unabh"angig vom Listing einen gewissen Sinn...} \item{\tty{C}: erzeugt eine Liste mit Querverweisen. Aufgelistet wird, welche (globalen) Symbole in welchen Dateien in welchen Zeilen benutzt werden. Auch diese Liste wird nur generiert, falls ein Listing erzeugt wird und belegt w"ahrend der Assemblierung zus"atzlichen Speicherplatz.} \item{\tty{s}: eine Liste aller Sektionen (s. Abschnitt \ref{ChapLocSyms}) ausgeben. Die Verschachtelung wird dabei durch Einr"uckungen angedeutet.} \item{\tty{I}: Analog zur Sektionsliste eine Liste aller bearbeiteten Include-Dateien ausgeben.} \item{\tty{t $<$Maske$>$}: Mit diesem Schalter lassen sich einzelne Komponenten des standardm"a"sig ausgegebenen Assemblerlistings ein-und ausblenden. Welcher Teil dabei welchem Bit zugeordnet ist, ist im "ubern"achsten Abschnitt, der genauer auf das Format des Assemblerlistings eingeht, nachgelesen werden.} \item{\tty{D $<$Symbolliste$>$}: Symbole definieren. Die hinter dieser Option angegebenen, durch Kommas getrennten Symbole werden in der globalen Symboltabelle vor Beginn der Assemblierung abgelegt. Defaultm"a"sig werden diese Symbole als ganze Zahlen mit dem Wert TRUE abgelegt, mit einem nachgestellten Gleichheitszeichen kann aber auch eine andere Belegung gew"ahlt werden. Der dem Gleichheitszeichen folgende Ausdruck darf dabei auch Operatoren oder interne Funktionen beinhalten, jedoch \bb{KEINE} anderen Symbole, selbst wenn diese schon davor in der Liste definiert sein sollten! Zusammen mit den Befehlen zur bedingten Assemblierung (siehe dort) k"onnen so per Kommandozeile aus einer Quelldatei unterschiedliche Programmversionen erzeugt werden.} \item{\tty{A}: Die Liste globaler Symbole in einer anderen, kompakteren Form ablegen. Verwenden Sie diese Option, wenn der Assembler bei langen Symboltabellen mit einem Stapel"uberlauf abst"urzt. Eventuell kann diese Option die Arbeitsgeschwindigkeit des Assemblers erh"ohen, dies h"angt jedoch von den Quellen ab.} \item{\tty{x}: Legt die Ausf"uhrlichkeitsstufe von Fehlermeldungen fest. Jedesmal, wenn diese Option angegeben wird, wird die Stufe um eins erh"oht oder gesenkt. W"ahrend auf Stufe 0 (Vorgabe) nur der Fehler selber ausgegeben wird, wird ab Stufe 1 noch eine erweiterte Meldung ausgegeben, anhand der die Identifizierung des Fehlers erleichtert werden soll. Welche Fehlermeldungen welche Zusatzinformationen tragen k"onnen, steht in Anhang \ref{ChapErrMess} mit der Liste aller Fehlermeldungen. Auf Stufe 2 (Maximum) wird zus"atzlich noch die betroffene Quellzeile mit ausgegeben.} \item{\tty{n}: Wird diese Option angegeben, so werden Fehlermeldungen nicht nur mit ihrem Klartext, sondern auch mit ihren im Anhang \ref{ChapErrMess} genannten internen Nummern ausgegeben. Diese Option ist prim"ar f"ur Shells und Entwicklungsumgebungen gedacht, denen mit diesen Nummern die Identifizierung von Fehlern erleichtert werden soll.} \item{\tty{U}: Mit dieser Option schaltet man AS in den case-sensitiven Modus um, d.h. in Namen von Symbolen, Sektionen, Makros, Zeichentabellen und selbstdefinierte Funktionen werden Klein- und Gro"sbuchstaben unterschieden, was normalerweise nicht der Fall ist.} \item{\tty{P}: weist AS an, den von Makroprozessor und bedingter Assemblierung bearbeiteten Quelltext in einer Datei abzulegen. Dieser Datei fehlen zus"atzlich Leer- und reine Kommentarzeilen. Die Endung der Datei ist \tty{I}.} \item{\tty{M}: mit diesem Schalter erzeugt AS eine Datei, in der die Definitionen der Makros aus der Quelldatei abgespeichert werden, die die \tty{EXPORT}-Option verwenden. Diese neue Datei hat den gleichen Namen wie die Quelldatei, lediglich die Endung wird in \tty{MAC} ge"andert.} \item{\tty{G}: Dieser Schalter bestimmt, ob AS Code erzeugen soll oder nicht. Ist er ausgeschaltet, wird die Datei zwar assembliert, aber keine Code-Datei geschrieben. Dieser Schalter ist defaultm"a"sig aktiviert (logisch, sonst bek"ame man ja auch gar kein Codefile).} \item{\tty{r [n]}: Warnungen ausgeben, falls Situationen eintreten, die einen weiteren Pass erfordern. Diese Information kann genutzt werden, um die Anzahl der Durchl"aufe zu verringern. Optional kann man die Nummer des Passes angeben, ab dem diese Warnungen erzeugt werden; ohne Angabe kommen die Warnungen ab dem ersten Pass. Machen Sie sich aber so oder so auf einen ziemlichen Haufen an Meldungen gefa"st!!} \item{\tty{Y}: Mit diesem Schalter weist man AS an, alle Fehlermeldungen wegen zu langer Sprungdistanzen zu verwerfen, sobald die Notwendigkeit eines neuen Durchlaufs feststeht. In welchen (seltenen) Situationen dieser Schalter notwendig ist, kann man in Abschnitt \ref{ForwRefs} nachlesen.} \item{\tty{cpu $<$Name$>$}: Hiermit kann man man den Zielprozessor vorgeben, f"ur den AS Code erzeugen soll, wenn die Quelldatei keinen {\tt CPU}-Befehl enth"alt und es sich nicht um 68008-Code handelt.} \item{\tty{alias $<$neu$>$=$<$alt$>$}:\\ definiert den Prozessortyp \tty{$<$neu$>$} als einen Alias f"ur den Typen \tty{$<$alt$>$}. Zu den Sinn und Zweck von Aliassen siehe Abschnitt \ref{SectAlias}} \end{itemize} Sofern Schalter keine Argumente ben"otigen und ihre Zusammenziehung keinen mehrbuchstabigen Schalter ergibt, k"onnen mehrere Schalter auch auf einen Rutsch angegeben werden, wie z.B im folgenden Beispiel: \begin{verbatim} as test*.asm firstprog -cl /i c:\as\8051\include \end{verbatim} Es werden alle Dateien TEST*.ASM sowie die Datei FIRSTPROG.ASM assembliert, wobei f"ur alle Dateien Listings auf der Konsole ausgegeben und Sharefiles im C-Format erzeugt werden. Nach Includes soll der Assembler zus"atzlich im Verzeichnis \verb! C:\AS\8051\INCLUDE ! suchen. \par Dieses Beispiel zeigt nebenbei, da"s AS als Defaultendung f"ur Quelldateien \tty{ASM} annimmt. \par Etwas Vorsicht ist bei Schaltern angebracht, die ein optionales Argument haben: Folgt auf einen solchen Schalter ohne Argument ein Dateiname, so versucht AS, diesen als Argument zu verwerten, was naturgem"a"s schief geht: \begin{verbatim} as -g test.asm \end{verbatim} Die L"osung w"are in diesem Fall, die \tty{-g}-Option ans Ende der Kommandozeile zu setzen oder ein explizites \tty{MAP}-Argument zu spezifizieren. \par Neben der Angabe in der Kommandozeile k"onnen dauernd ben"otigte Optionen in der Environment-Variablen ASCMD abgelegt werden. Wer z.B. immer Listdateien haben m"ochte und ein festes Includeverzeichnis hat, kann sich mit dem Befehl \begin{verbatim} set ASCMD=-L -i c:\as\8051\include \end{verbatim} eine Menge Tipparbeit ersparen. Da die Environment-Optionen vor der Kommandozeile abgearbeitet werden, k"onnen Optionen in der Kommandozeile widersprechende im Environment "ubersteuern. \par Bei sehr langen Pfaden kann es jedoch auch in der ASCMD-Variablen eng werden. F"ur solche F"alle kann auf eine sog. \ii{Key}- Datei ausgewichen werden, in der die Optionen genauso wie in der Kommandozeile oder ASCMD-Variablen abgelegt werden k"onnen, nur da"s diese Datei mehrere Zeilen mit jeweils maximal 255 Zeichen enthalten darf. Wichtig ist dabei, da"s bei Optionen, die ein Argument ben"otigen, sowohl Schalter als auch Argument in \bb{einer} Zeile stehen m"ussen. Der Name der Datei wird AS dadurch mitgeteilt, da"s er mit einem vorangestellten Klammeraffen in der ASCMD-Variablen abgelegt wird, z.B. \begin{verbatim} set ASCMD=@c:\as\as.key \end{verbatim} Um Optionen in der ASCMD-Variablen (oder der Key-Datei) wieder aufzuheben, kann die Option mit einem vorangestellten Pluszeichen wieder aufgehoben werden. Soll in einem Einzelfall z.B. doch kein Listing erzeugt werden, so kann es mit \begin{verbatim} as +L \end{verbatim} wieder aufgehoben werden. Nat"urlich ist es nicht ganz logisch, eine Option mit einem Pluszeichen zu negieren...UNIX soit qui mal y pense. \par Referenzen auf eine Key-Datei k"onnen nicht nur von der {\tt ASCMD}-Variablen aus erfolgen, sondern auch direkt von der Kommandozeile aus, indem man analog zur {\tt ASCMD}-Variablen dem Dateinamen einen Klammeraffen voranstellt: \begin{verbatim} as @ .... \end{verbatim} Die in einem solchen Fall aus dem Key-File gelesenen Optionen werden so eingearbeitet, als h"atten sie anstelle dieser Referenz in der Kommandozeile gestanden - es ist also {\em nicht} wie bei der {\tt ASCMD}-Variablen so, da"s sie vor allen anderen Kommandozeilenoptionen abgearbeitet werden w"urden. \par Das Referenzieren eines Key-Files von einem Key-File selber ist nicht erlaubt und wird von AS mit einer Fehlermeldung quittiert. \par F"ur den Fall, da"s Sie AS von einem anderen Programm oder einer Shell aufrufen wollen und diese Shell nur Klein- oder Gro"sbuchstaben in der Kommandozeile "ubergeben will, existiert folgendes Workaround: Wird vor den Buchstaben der Option eine Tilde gesetzt, so werden die folgenden Buchstaben immer als Kleinbuchstaben interpretiert. Analog erzwingt ein Lattenzaun die Interpretation als Gro"sbuchstaben. Es ergeben sich z.B. folgende Transformationen: \begin{quote}{\tt /\verb!~!I $\longrightarrow$ /i \\ -\verb!#!u $\longrightarrow$ -U} \end{quote} \par Abh"angig vom Ablauf der Assemblierung endet der Assembler mit folgenden Returncodes: \begin{description} \item[0]{fehlerfreier Ablauf, h"ochstens Warnungen aufgetreten} \item[1]{Der Assembler hat nur die Aufrufparameter ausgegeben und endete danach sofort.} \item[2]{Es sind Fehler bei der Assemblierung aufgetreten, es wurde kein Codefile erzeugt.} \item[3]{Es trat ein fataler Fehler w"ahrend des Ablaufes auf, der zum sofortigen Abbruch gef"uhrt hat.} \item[4]{Bereits w"ahrend des Starts des Assemblers ist ein Fehler aufgetreten. Dies kann ein Parameterfehler oder eine fehlerhafte Overlay-Datei sein.} \item[255]{Bei der Initialisierung ist irgendein interner Fehler aufgetreten, der auf keinen Fall auftreten sollte...neu booten, noch einmal probieren, und bei Reproduzierbarkeit mit mir Verbindung aufnehmen!} \end{description} Zus"atzlich endet jede Assemblierung einer Datei mit einer kleinen Statistik, die Fehlerzahlen, Laufzeit, Anzahl der Durchl"aufe und freien Speicher ausgibt. Bei eingeschaltetem Assembler-Listing wird diese Statistik zus"atzlich auch in das Listing geschrieben. OS/2 \marginpar{{\em OS/2}} erweitert wie Unix das Datensegment einer Anwendung erst dann, wenn sie wirklich mehr Speicher anfordert. Eine Angabe wie \begin{quote}{\tt 511 KByte verf"ugbarer Restspeicher }\end{quote} bedeutet also nicht einen nahenden Systemabsturz wegen Speichermangel, sondern stellt nur den Abstand zu der Grenze dar, bei der OS/2 einfach ein paar mehr Kohlen in den Ofen schaufelt... Da es unter C \marginpar{{\em UNIX}} auf verschiedenen Betriebssystemen keine kompatible M"oglichkeit gibt, den noch verf"ugbaren Speicher bzw. Stack zu ermitteln, fehlen bei der C-Version diese beiden Angaben ganz. %%--------------------------------------------------------------------------- \section{Format der Eingabedateien} \label{AttrTypes} Wie die meisten Assembler auch erwartet AS genau einen Befehl pro Zeile (Leerzeilen sind nat"urlich auch zugelassen). Die Zeilen d"urfen nicht l"anger als 255 Zeichen werden, dar"uber hinaus gehende Zeichen werden abgeschnitten. \par Eine einzelne Zeile hat folgendes Format: \begin{verbatim} [Label[:]][.Attribut] [Parameter[,Parameter..]] [;Kommentar] \end{verbatim} Der Doppelpunkt nach dem Label ist optional, falls das Label in der ersten Spalte beginnt (woraus folgt, da"s der Befehl niemals in Spalte 1 beginnen darf). Man mu"s ihn aber setzen, falls das Label nicht in der ersten Spalte beginnt, damit AS es von einem Befehl unterscheiden kann. In letzterem Fall mu"s "ubrigens zwischen Doppelpunkt und dem Befehl mindestens ein Leerzeichen stehen, falls der eingestellte Zielprozessor zu denjenigen geh"ort, bei denen das Attribut auch eine mit einem Doppelpunkt abgetrennte Formatangabe sein darf. Dieser Knopf ist aus Eindeutigkeitsgr"unden n"otig, da sonst keine Unterscheidung zwischen Befehl mit Format und Label mit Befehl m"oglich w"are. \par Einige Signalprozessorreihen von Texas Instruments verwenden den f"ur das Label vorgesehenen Platz wahlweise auch f"ur einen Doppelstrich (\verb!||!), der die parallele Ausf"uhrung mit der vorangehenden Instruktion anzeigt. Wenn diese beiden Instruktionen auf Maschinenebene in einem einzigen Wort vereinigt werden (C3x), macht ein zus"atzliches Label vor der zweiten Anweisung nat"urlich keinen Sinn und ist auch nicht vorgesehen. Anders sieht es beim C6x mit seinen Instruktionspaketen variabler L"ange aus: Wer dort (unsch"onerweise...) mitten in ein Paket hineinspringen will, mu"s das Label daf"ur in eine Extrazeile davor setzen (das gleiche gilt "ubrigens auch f"ur Bedingungen, die aber zusammen mit dem Doppelstrich in einer Zeile stehen d"urfen). \par Das Attribut wird von einer Reihe von Prozessoren benutzt, um Spezialisierungen oder Kodierungsvarianten eines bestimmten Befehls zu spezifizieren. Die bekannteste Nutzung des Attributs ist die Angabe der Operandengr"o"se, wie z. B. bei der 680x0-Familie (Tabelle \ref{TabAttrs}). \begin{table*}[htb] \begin{center}\begin{tabular}{|l|l|l|} \hline Attribut & arithmetisch-logischer Befehl & Sprungbefehl \\ \hline \hline B & Byte (8 Bit) & --------- \\ W & Wort (16 Bit) & --------- \\ L & Langwort (32 Bit) & 16-Bit-Displacement \\ Q & Vierfachwort (64 Bit) & --------- \\ S & Single Precision (32 Bit) & 8-Bit-Displacement \\ D & Double Precision (64 Bit) & --------- \\ X & Extended Precision (80/96 Bit) & 32-Bit-Displacement \\ P & Dezimalgleitkomma (80/96 Bit) & --------- \\ \hline \end{tabular}\end{center} \caption{Erlaubte Attribute (Beispiel 680x0) \label{TabAttrs}} \end{table*} \par Da sich diese Anleitung nicht gleichzeitig als Handbuch f"ur die von AS unterst"utzten Prozessorfamilien versteht, ist dies leider auch nicht der richtige Platz, um hier alle m"oglichen Attribute f"ur alle unterst"utzten Familien aufzuz"ahlen. Es sei aber angemerkt, da"s i.a. nicht alle Befehle alle Attribute zulassen, andererseits das Fortlassen eines Attributs meist zur Verwendung der f"ur diese Familie ,,nat"urlichen'' Operandengr"o"se f"uhrt. Zum genaueren Studium greife man auf ein Programmierhandbuch f"ur die jeweilige Familie zur"uck, z.B. in \cite{Williams} f"ur die 68000er. \par Bei TLCS-9000, H8/500 und M16(C) dient das Attribut sowohl der Angabe der Operandengr"o"se, falls diese nicht durch die Operanden klar sein sollte, als auch der des zu verwendenden Befehlsformates. Dieses mu"s durch einen Doppelpunkt von der Operandengr"o"se getrennt werden, z.B. so: \begin{verbatim} add.w:g rw10,rw8 \end{verbatim} Was dieses Beispiel nicht zeigt, ist, da"s die Formatangabe auch ohne Operandengr"o"se geschrieben werden darf. Steht demgegen"uber eine Operandengr"o"se ohne Formatangabe, verwendet AS automatisch das k"urzeste Format. Die erlaubten Befehlsformate und Operandengr"o"sen sind vom Maschinenbefehl abh"angig und k"onnen z.B. \cite{Tosh9000}, \cite{HitH8_5}, \cite{MitM16} bzw. \cite{MitM16C} entnommen werden. \par Die Zahl der Befehlsparameter ist abh"angig vom Befehl und kann prinzipiell zwischen 0 und 20 liegen. Die Trennung der Parameter voneinander erfolgt ausschlie"slich durch Kommas (Ausnahme: DSP56xxx, dessen parallele Datentransfers durch Leerzeichen getrennt werden), wobei in Klammern oder Hochkommas eingeschlossene Kommas nat"urlich nicht beachtet werden. \par Anstelle eines Kommentars am Ende kann die Zeile auch nur aus einem Kommentar bestehen, wenn er in der ersten Spalte beginnt. \par Bei den Leerzeichen zur Trennung einzelnen Komponenten darf es sich genauso gut um Tabulatoren handeln. %%--------------------------------------------------------------------------- \section{Format des Listings} Das von AS bei Angabe der Kommandozeilenoptionen \tty{l} oder \tty{L} erzeugte Listing l"a"st sich grob in folgende Teile gliedern: \begin{enumerate} \item{Wiedergabe des assemblierten Quellcodes;} \item{Symbolliste;} \item{Makroliste;} \item{Funktionsliste;} \item{Belegungsliste;} \item{Querverweisliste.} \end{enumerate} Letztere beide werden nur erzeugt, wenn sie durch zus"atzliche Kommandozeilenoptionen angefordert wurden. \par Im ersten Teil listet AS den kompletten Inhalt aller Quelldateien inklusive des erzeugten Codes auf. Eine Zeile in diesem Listing hat dabei folgende Form: \begin{verbatim} [] / \end{verbatim} Im Feld $n$ zeigt AS die Include-Verschachtelungstiefe an. Die Hauptdatei (die Datei, mit der die Assemblierung begann), hat dabei die Tiefe 0, von dort aus eingebundene Dateien haben Tiefe 1 usw. Die Tiefe 0 wird dabei nicht angezeigt. \par Im Feld \tty{Zeile} wird die Zeilennummer bezogen auf die jeweilige Datei ausgegeben. Die erste Zeile einer Datei hat dabei Nummer 1. Die Adresse, an der der f"ur diese Zeile erzeugte Code abgelegt wurde, folgt hinter dem Schr"agstrich im Feld \tty{Adresse}. \par Der erzeugte Code selber steht dahinter im Feld \tty{Code} in hexadezimaler Schreibweise. Je nach Prozessortyp und aktuellem Segment k"onnen die Werte entweder als Bytes oder 16/32-Bit-Worte formatiert sein. Sollte mehr Code erzeugt worden sein, als in das Feld hineinpa"st, so werden im Anschlu"s an die Zeile weitere Zeilen erzeugt, in denen nur dieses Feld belegt ist. \par Im Feld \tty{Quelle} schlu"sendlich wird die Zeile aus der Quelldatei in ihrer Originalform ausgegeben. \par Die Symboltabelle ist so ausgelegt, da"s sie nach M"oglichkeit immer in 80 Spalten dargestellt werden kann. F"ur Symbole ,,normaler L"ange'' wird eine zweispaltige Ausgabe gew"ahlt. Sollten einzelne Symbole mit ihrem Wert die Grenze von 40 Spalten "uberschreiten, werden sie in einer einzelnen Zeile ausgegeben. Die Ausgabe erfolgt in alphabetischer Reihenfolge. Symbole, die zwar definiert, aber nie benutzt wurden, werden mit einem vorangestellten Stern (\verb!*!) gekennzeichnet. \par Die bisher genannten Teile sowie die Auflistung aller definierten Makros / Funktionen lassen sich selektiv aus dem Gesamtlisting ein-und ausblenden, und zwar mit dem bereits erw"ahnten \tty{t}-Kommandozeilenschalter. Intern existiert in AS ein Byte, dessen Bits repr"asentieren, welche Teile ausgegeben werden sollen. Die Zuordnung von Bits zu den Teilen ist in Tabelle \ref{TabTBits} aufgelistet. \par \begin{table*}[p] \begin{center}\begin{tabular}{|l|l|} \hline Bit & Teil \\ \hline \hline 0 & Quelldatei(en)+erzeugter Code \\ 1 & Symboltabelle \\ 2 & Makroliste \\ 3 & Funktionsliste \\ 4 & Zeilennumerierung \\ 5 & Registersymboltabelle \\ 7 & Zeichentabellenliste \\ \hline \end{tabular}\end{center} \caption{Zuordnung der Bits zu den Listingkomponenten\label{TabTBits}} \end{table*} Defaultm"a"sig sind alle Bits auf 1 gesetzt, bei Verwendung des Schalters \begin{verbatim} -t \end{verbatim} werden die in \verb!! gesetzten Bits gel"oscht, so da"s die entsprechenden Listing-Teile unterdr"uckt werden. Analog lassen sich mit einem Pluszeichen einzelne Teile wieder einschalten, falls man es in der \tty{ASCMD}-Variablen "ubertrieben hat...will man z.B. nur die Symboltabelle haben, so reicht \begin{verbatim} -t 2 . \end{verbatim} In der Belegungsliste werden f"ur jedes Segment einzeln die belegten Bereiche hexadezimal ausgegeben. Handelt es sich bei einem Bereich um eine einzige Adresse, wird nur diese ausgegeben, ansonsten erste und letzte Adresse. \par In der Querverweisliste wird f"ur jedes definierte Symbol in alphabetischer Reihenfolge eine Ausgabe folgender Form erzeugt: \begin{verbatim} Symbol (=,/): Datei : [(m1)] ..... [(mk)] . . Datei : [(m1)] ..... [(mk)] \end{verbatim} F"ur jedes Symbol wird aufgelistet, in welchen Dateien es in welchen Zeilen angesprochen wurde. Sollte ein Symbol mehrmals in der gleichen Zeile benutzt worden sein, so wird dies durch eine in Klammern gesetzte Anzahl hinter der Zeilennummer angedeutet. Sollte ein Symbol niemals benutzt worden sein, erscheint es auch nicht in der Liste; entsprechend erscheint eine Datei auch "uberhaupt nicht in der Liste eines Symbols, falls es in der entsprechenden Datei nicht referenziert wurde. \par \bb{ACHTUNG!} AS kann dieses Listing nur dann korrekt aufs Papier bringen, wenn man ihm vorher die L"ange und Breite des Ausgabemediums mit Hilfe des \tty{PAGE}-Befehls (siehe dort) mitgeteilt hat! Der voreingestellte Default sind 60 Zeilen und eine unbegrenzte Zeilenbreite. %%--------------------------------------------------------------------------- \section{Symbolkonventionen} \label{SectSymConv} Symbole d"urfen zwar (wie in der Einleitung bereits angedeutet) bis zu 255 Zeichen lang werden und werden auch auf der ganzen L"ange unterschieden, die Symbolnamen m"ussen aber einigen Konventionen gen"ugen: \par Symbolnamen d"urfen aus einer beliebigen Kombination von Buchstaben, Ziffern, Unterstrichen und Punkten bestehen, wobei das erste Zeichen keine Ziffer sein darf. Der Punkt wurde nur zugelassen, um der MCS-51-Notation von Registerbits zu gen"ugen, und sollte m"oglichst nicht in eigenen Symbolnamen verwendet werden. Zur Segmentierung von Symbolnamen sollte auf jeden Fall der Unterstrich und nicht der Punkt verwendet werden. \par Defaultm"a"sig ist AS nicht case-sensitiv, es ist also egal, ob man Gro"s-oder Kleinbuchstaben verwendet. Mittels des Kommandozeilenschalters \tty{U} l"a"st sich AS jedoch in einen Modus umschalten, in dem Gro"s- und Kleinschreibung unterschieden wird. Ob AS umgeschaltet wurde, kann mit dem vordefinierten Symbol \tty{CASESENSITIVE} ermittelt werden: TRUE bedeutet Unterscheidung, FALSE keine. \par Tabelle \ref{TabPredefined} zeigt die wichtigsten, von AS vordefinierten Symbole. \begin{table*}[p] \begin{center}\begin{tabular}{|l|l|} \hline Name & Bedeutung \\ \hline \hline \tty{TRUE} & logisch ,,wahr'' \\ \tty{FALSE} & logisch ,,falsch'' \\ \tty{CONSTPI} & Kreiszahl Pi (3.1415.....) \\ \tty{VERSION} & Version von AS in BCD-Kodierung, \\ & z.B. 1331 hex f"ur Version 1.33p1 \\ \tty{ARCHITECTURE} & Zielplattform, f"ur die AS "ubersetzt wurde, \\ & in der Form Prozesor-Hersteller-Betriebssystem \\ \tty{DATE} & Datum und \\ \tty{TIME} & Zeitpunkt der Assemblierung (Beginn) \\ \tty{MOMCPU} & momentan gesetzte Ziel-CPU \\ \tty{MOMCPUNAME} & dito, nur als voll ausgeschriebener String \\ \tty{MOMFILE} & augenblickliche Quelldatei \\ \tty{MOMLINE} & Zeilennummer in Quelldatei \\ \tty{MOMPASS} & Nummer das laufenden Durchgangs \\ \tty{MOMSECTION} & Name der aktuellen Sektion oder \\ & Leerstring \\ \tty{MOMSEGMENT} & Name des mit \tty{SEGMENT} gew"ahlten \\ & Adre"sraumes \\ \verb!*!, \$ bzw. \tty{PC} & mom. Programmz"ahler \\ \hline \end{tabular}\end{center} \caption{Vordefinierte Symbole\label{TabPredefined}} \end{table*} \bb{VORSICHT!} W"ahrend es im case-insensitiven Modus egal ist, mit welcher Kombination von Gro"s- und Kleinbuchstaben man vordefinierte Symbole anspricht, mu"s man sich im case-sensitiven Modus exakt an die oben angegebene Schreibweise (nur Gro"sbuchstaben) halten! \par Zus"atzlich definieren einige Pseudobefehle noch Symbole, die eine Abfrage des damit momentan eingestellten Wertes erm"oglichen. Deren Beschreibung findet sich bei den zugeh"origen Befehlen. \par Ein etwas verstecktes (und mit Vorsicht zu nutzendes) Feature ist, Symbolnamen aus String-Variablen zusammenzubauen, indem man den Namen des Strings mit geschweiften Klammern in den Symbolnamen einbaut. So kann man z.B. den Namen eines Symbols anhand des Wertes eines anderen Symbols festlegen: \begin{verbatim} cnt set cnt+1 temp equ "\{CNT}" jnz skip{temp} . . skip{temp}: nop \end{verbatim} \bb{ACHTUNG!} Der Programmierer ist selber daf"ur verantwortlich, da"s sich dabei g"ultige Symbolnamen ergeben! \par Eine vollst"andige Auflistung aller von AS verwendeten Symbolnamen findet sich in Anhang \ref{AppInternSyms}. \par Neben seinem Wert besitzt auch jedes Symbol eine Markierung, zu welchen {\em Segment} es geh"ort. In erster Linie wird eine solche Unterscheidung bei Prozessoren ben"otigt, die mehrere Adre"sr"aume besitzen. AS kann mit dieser Zusatzinformation bei Zugriffen "uber ein Symbol warnen, wenn ein f"ur diesen Adre"sraum ungeeigneter Befehl verwendet wird. Ein Segmentattribut wird einem Symol automatisch angeh"angt, wenn es als Label oder mit einem Spezialbefehl (z.B. \tty{BIT}) definiert wird; ein mit dem ,,Universalbefehl'' \tty{SET} oder \tty{EQU} definiertes Symbol ist jedoch ,,typenlos'', d.h. seine Verwendung wird niemals Warnungen ausl"osen. Das Segmentattribut eines Symbols kann mit der eingebauten Funktion \tty{SYMTYPE} abgefragt werden, etwa so: \begin{verbatim} Label: . . Attr equ symtype(Label) ; ergibt 1 \end{verbatim} Den einzelnen Segmenttypen sind die in Tabelle \ref{TabSegNums} aufgelisteten Nummern zugeordnet. Die aus der Ordnung normaler Symbole etwas herausfallenden Registersymbole sind n"aher in Abschnitt \ref{SectRegSyms} erl"autert. Mit einem undefinierten Symbol als Argument liefert die \tty{SYMTYPE}-Funktion -1 als Ergebnis. \begin{table}[htb] \begin{center} \begin{tabular}{|l|c|} \hline Segment & R"uckgabewert \\ \hline $<$keines$>$ & 0 \\ CODE & 1 \\ DATA & 2 \\ IDATA & 3 \\ XDATA & 4 \\ YDATA & 5 \\ BITDATA & 6 \\ IO & 7 \\ REG & 8 \\ ROMDATA & 9 \\ $<$Registersymbol$>$ & 128 \\ \hline \end{tabular} \end{center} \caption{R"uckgabewerte der \tty{SYMTYPE}-Funktion\label{TabSegNums}} \end{table} %%--------------------------------------------------------------------------- \section{Formelausdr"ucke} An den meisten Stellen, an denen der Assembler Zahlenangaben erwartet, k"onnen nicht nur einfache Symbole oder Konstanten angegeben werden, sondern ganze Formelausdr"ucke. Bei den Komponenten der Formelausdr"ucke kann es sich sowohl um ein einzelnes Symbol als auch um eine Konstante handeln. Konstanten d"urfen entweder Integer-, Gleitkomma-, oder Stringkonstanten sein. \subsection{Integerkonstanten} \label{SectIntConsts} Integerkonstanten bezeichnen ganze Zahlen. Sie d"urfen entweder als eine Folge von Ziffern oder als eine Reihe von in {\em einfachen} Hochkommas eingeschlossenen Zeichen geschrieben werden. Werden sie als Ziffernfolgen geschrieben, so kann dies in verschiedenen Zahlensystemen erfolgen, deren Kennzeichnung von verwendeten Zielprozessor abh"angt (Tabelle \ref{TabSystems}). \par \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|c|c|c|} \hline & Intel-Modus & Motorola-Modus & C-Modus \\ & (Intel, Zilog, & (Rockwell, Motorola, & (PowerPC, \\ & Thomson, Texas, & Microchip, Thomson, & AMD29K, \\ & Toshiba, NEC, & Hitachi, Atmel) & National,\\ & Siemens, Philips, & & Symbios) \\ & Fujitsu, Fairchild) & & \\ \hline \hline dezimal & direkt & direkt & direkt \\ hexadezimal & nachgestelltes H & vorangestelltes \$ & vorangestelltes 0x \\ bin"ar & nachgestelltes B & vorangestelltes \% & vorangestelltes 0b \\ oktal & nachgestelltes O & vorangestelltes @ & vorangestellte 0 \\ \hline \end{tabular}\end{center} \caption{m"ogliche Zahlensysteme\label{TabSystems}} \end{table*} Falls das Zahlensystem nicht explizit durch vor-oder nachgestelle Zeichen vorgegeben wird, nimmt AS die Basis an, die mit dem {\tt RADIX}-Befehl vorgegeben wurde (der Default dieser Einstellung ist wiederum 10). Mit diesem Befehl lassen sich auch ,,ungew"ohnliche" Zahlensysteme, d.h. andere als 2, 8, 10 oder 16 einstellen. G"ultige Ziffern sind die Zahlen 0 bis 9 sowie die Buchstaben A bis Z (Wert 10 bis 35) bis zur Basis des Zahlensystems minus eins. Die Verwendung von Buchstaben in Integerkonstanten bringt allerdings auch einige Mehrdeutigkeiten mit sich, da Symbolnamen ja auch Ketten aus Zahlen und Buchstaben sind: Ein Symbolname darf nicht mit einem Zeichen von 0 bis 9 beginnen, was bedeutet, da"s eine Integerkonstante, die nicht durch ein anderes Sonderzeichen eindeutig als solche erkennbar ist, niemals mit einem Buchstaben beginnen darf; notfalls mu"s man eine eigentlich "uberfl"ussige Null voranstellen. Der bekannteste Fall ist das Scheiben von Hexadezimalkonstanten im Intel-Modus: Ist die vorderste Stelle zwischen A und F, so hilft das hintangestellte H "uberhaupt nichts, es mu"s noch eine Null davor (statt F0H also 0F0H). Die Motorola-oder C-Syntax, die beide das Zahlensystem am Anfang einer Integerkonstante kennzeichnen, kennen dieses Problem nicht. (\ii{hihihi!}). Reichlich heimt"uckisch ist auch, da"s bei immer h"oheren, mit {\tt RADIX} eingestellten Zahlensystemen, die bei Intel- und C-Syntax benutzten Buchstaben zur Zahlensystemkennung immer weiter ,,aufgefressen'' werden; so kann man z.B. nach {\tt RADIX 16} keine bin"aren Konstanten mehr schreiben, und ab {\tt RADIX 18} in Intel-Syntax auch keine hexadezimalen Konstanten mehr. Also {\bf VORSICHT!} Mit Hilfe des \tty{RELAXED}-Befehls (siehe Abschnitt \ref{SectRELAXED}) kann die starre Zuordnung einer Schreibweise zu einem Zielprozessor aufgehoben werden, so da"s man eine beliebige Schreibweise verwenden kann (auf Kosten der Kompatibilit"at zu Standard-Assemblern). Defaultm"a"sig ist diese Option aber ausgeschaltet. Wie bereits angesprochen, k"onnen Integer-Konstanten auch als ASCII-Werte geschrieben werden, so entsprechen \begin{verbatim} 'A' ==$41 'AB' ==$4142 'ABCD' ==$41424344 \end{verbatim} Wichtig ist, da"s hier die Zeichen in {\em einfachen Hochkommas} geschrieben werden, um sie von den weiter unten beschriebenen Stringkonstanten zu unterscheiden. \subsection{Gleitkommakonstanten} Gleitkommazahlen werden in der "ublichen halblogarithmischen Schreibweise geschrieben, die in der allgemeinsten Form \begin{verbatim} [-][.Nachkommastellen][E[-]Exponent] \end{verbatim} lautet. \bb{ACHTUNG!} Der Assembler versucht eine Konstante zuerst als Integerkonstante zu verstehen und macht erst dann einen Versuch mit Gleitkomma, falls dies gescheitert ist. Will man aus irgendwelchen Gr"unden die Auswertung als Gleitkommazahl erzwingen, so kann man dies durch Dummy-Nachkommastellen erreichen, z.B. \tty{2.0} anstelle \tty{2}. \subsection{Stringkonstanten} \label{SectStringConsts} Stringkonstanten m"ussen in {\em doppelte Hochkommas} (um sie von den oben beschrieben ASCII-Integers zu unterscheiden) eingeschlossen werden. Um nun aber auch G"ansef"u"schen und Sonderzeichen ohne Verrenkungen in String-Konstanten einbauen zu k"onnen, wurde ein ,,Escape-Mechanismus'' eingebaut, der Programmierer(inne)n aus C bekannt vorkommen d"urfte: Schreibt man einen Backslash mit einer maximal dreiziffrigen Zahl im String, so versteht der Assembler dies als Zeichen mit dem entsprechenden dezimalen ASCII-Wert. Alternativ kann der Zahlenwert auch hexadezimal oder oktal mit einem vorangestellten x oder einer vorangestellten 0 geschrieben werden. F"ur die hexadezimale Schreibweise reduziert sich die Maximalanzahl von Stellen auf 2. So kann man z.B. mit {\tt\verb!\3!} ein ETX-Zeichen definieren. Vorsicht allerdings mit der Definition von NUL-Zeichen! Da die C-Version \marginpar{{\em UNIX}} von AS momentan intern zur Speicherung von String-Symbolen C-Strings benutzt (die durch NUL-Zeichen terminiert werden), sind NUL-Zeichen in Strings momentan nicht portabel! Einige besonders h"aufig gebrauchte Steuerzeichen kann man auch mit folgenden Abk"urzungen erreichen: \begin{quote}\begin{tabbing} \hspace{4cm} \= \hspace{4cm} \= \kill \verb!\b! : Backspace \> \verb!\a! : Klingel \> \verb!\e! : Escape \\ \verb!\t! : Tabulator \> \verb!\n! : Zeilenvorschub \> \verb!\r! : Wagenr"ucklauf \\ \verb!\\! : Backslash \> \verb!\'! oder \verb!\h! : Hochkomma \\ \verb!\"! oder \verb!\i! : G"ansef"u"schen \\ \end{tabbing}\end{quote} Die Kennbuchstaben d"urfen sowohl gro"s als auch klein geschrieben werden. \par "Uber dieses Escape-Zeichen k"onnen sogar Formelausdr"ucke in den String eingebaut werden, wenn sie in geschweifte Klammern eingefa"st werden: z.B. ergibt \begin{verbatim} message "Wurzel aus 81 : \{sqrt(81)}" \end{verbatim} die Ausgabe \begin{verbatim} Wurzel aus 81 : 9 \end{verbatim} Der Assembler w"ahlt anhand des Formelergebnistyps die richtige Ausgabeform, zu vermeiden sind lediglich weitere Stringkonstanten im Ausdruck, da der Assembler bei der Gro"s-zu-Kleinbuchstabenumwandlung sonst durcheinanderkommt. Integer-Ausdr"ucke werden defaultm"a"sig hexadezimal ausgegeben, dies l"a"st sich jedoch mit dem \tty{OUTRADIX}-Befehl "andern. \par Bis auf den Einbau von Formelausdr"ucken ist dieser Escape-Mechanismus auch in als ASCII definierten Integerkonstanten zul"assig, z.B. so: \begin{verbatim} move.b #'\n',d0 \end{verbatim} Jedoch hat alles seine Grenzen, weil der dar"uberliegende Splitter, der die Zeile in Opcode und Parameter zerlegt, nicht wei"s, womit er da eigentlich arbeitet, z.B. hier: \begin{verbatim} move.l #'\'abc',d0 \end{verbatim} Nach dem dritten Hochkomma findet er das Komma nicht mehr, weil er vermutet, da"s eine weitere Zeichenkonstante beginnt, und eine Fehlermeldung "uber eine falsche Parameterzahl ist die Folge. Abhilfe w"are z.B., \verb!\h! anstelle \verb!\'! zu schreiben. \subsection{Evaluierung} Die Berechnung von im Formelausdruck entstehenden Zwischenergebnissen erfolgt immer mit der h"ochsten verf"ugbaren Wortbreite, d.h. 32 Bit f"ur Ganzzahlen, 80 Bit f"ur Gleitkommazahlen und 255 Zeichen f"ur Strings. Eine eventuelle Pr"ufung auf Wertebereichs"uberschreitung findet erst am Endergebnis statt. \par Die portable C-Version \marginpar{{\em UNIX}} kann nur mit 64-Bit-Gleitkommazahlen umgehen, ist daher auf einen Maximalwert von ca. $10^{308}$ beschr"ankt. Als Ausgleich werden auf einigen Plattformen Integers mit 64 Bit Breite behandelt. \subsection{Operatoren} Der Assembler stellt zur Verkn"upfung die in Tabelle \ref{TabOps} genannten Operanden zur Verf"ugung. \begin{table*}[htbp] \begin{center}\begin{tabular}{|c|l|c|c|c|c|c|} \hline Op. & Funktion & \#Ops. & Int & Float & String & Rang \\ \hline \hline $<>$ & Ungleichheit & 2 & ja & ja & ja & 14 \\ $>=$ & gr"o"ser o. gleich & 2 & ja & ja & ja & 14 \\ $<=$ & kleiner o. gleich & 2 & ja & ja & ja & 14 \\ $<$ & echt kleiner & 2 & ja & ja & ja & 14 \\ $>$ & echt gr"o"ser & 2 & ja & ja & ja & 14 \\ $=$ & Gleichheit & 2 & ja & ja & ja & 14 \\ $==$ & Alias f"ur $=$ & & & & & \\ & & & & & & \\ $!!$ & log. XOR & 2 & ja & nein & nein & 13 \\ $||$ & log. OR & 2 & ja & nein & nein & 12 \\ \&\& & log. AND & 2 & ja & nein & nein & 11 \\ \verb! ~~ ! & log. NOT & 1 & ja & nein & nein & 2 \\ & & & & & & \\ - & Differenz & 2 & ja & ja & nein & 10 \\ + & Summe & 2 & ja & ja & ja & 10 \\ \# & Modulodivision & 2 & ja & nein & nein & 9 \\ / & Quotient & 2 & ja*) & ja & nein & 9 \\ \verb! * ! & Produkt & 2 & ja & ja & nein & 9 \\ \verb! ^ ! & Potenz & 2 & ja & ja & nein & 8 \\ & & & & & & \\ $!$ & bin"ares XOR & 2 & ja & nein & nein & 7 \\ $|$ & bin"ares OR & 2 & ja & nein & nein & 6 \\ \& & bin"ares AND & 2 & ja & nein & nein & 5 \\ $><$ & Bitspiegelung & 2 & ja & nein & nein & 4 \\ $>>$ & log. Rechtsschieben & 2 & ja & nein & nein & 3 \\ $<<$ & log. Linksschieben & 2 & ja & nein & nein & 3 \\ \verb! ~ ! & bin"ares NOT & 1 & ja & nein & nein & 1 \\ \hline \multicolumn{7}{|l|}{*) Rest wird verworfen} \\ \hline \end{tabular}\end{center} \caption{in AS definierte Operatoren\label{TabOps}} \end{table*} Unter ,,Rang'' ist dabei die Priorit"at zu verstehen, die dieser Operator bei der Teilung eines Ausdruckes in Unterausdr"ucke hat, der rangh"ochste Operator wird also \ii{zuletzt} ausgewertet. Die Reihenfolge der Evaluierung l"a"st sich durch Klammerung neu festlegen. \par Die Vergleichsoperatoren liefern TRUE, falls die Bedingung zutrifft, und FALSE falls nicht. Vergleiche betrachten Integerzahlen dabei als 32 Bit breit und vorzeichenbehaftet. F"ur die logischen Operatoren ist ein Ausdruck TRUE, falls er ungleich 0 ist, ansonsten FALSE. \par Die Bitspiegelung ist wohl etwas erkl"arungsbed"urftig: Der Operator spiegelt die untersten Bits im ersten Operanden, l"a"st die dar"uberliegenden Bits aber unver"andert. Die Zahl der zu spiegelnden Bits ist der rechte Operand und darf zwischen 1 und 32 liegen. \par Eine keine Fu"sangel beim bin"aren Komplement: Da die Berechnung grunds"atzlich auf 32- oder 64-Bit-Ebene erfolgt, ergibt seine Anwendung auf z.B. 8-Bit-Masken "ublicherweise Werte, die durch voranstehende Einsen nicht mehr im entferntesten in 8-Bit-Zahlen hineinpassen. Eine bin"are UND-Verkn"upfung mit einer passenden Maske ist daher unvermeidlich! \subsection{Funktionen} Zus"atzlich zu den Operatoren definiert der Assembler noch eine Reihe in erster Linie transzendenter Funktionen mit Gleitkommaargument, die Tabellen \ref{TabFuncs1} und \ref{TabFuncs2} auflisten. \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|l|l|l|} \hline Name & Funktion & Argument & Ergebnis \\ \hline \hline SQRT & Quadratwurzel & $arg \geq 0$ & Gleitkomma \\ & & & \\ SIN & Sinus & $arg \in \rz$ & Gleitkomma \\ COS & Kosinus & $arg \in \rz$ & Gleitkomma \\ TAN & Tangens & $arg \neq (2*n+1)*\frac{\pi}{2}$ & Gleitkomma \\ COT & Kotangens & $arg \neq n*\pi$ & Gleitkomma \\ & & & \\ ASIN & inverser Sinus & $\mid arg \mid \leq 1$ & Gleitkomma \\ ACOS & inverser Kosinus & $\mid arg \mid \leq 1$ & Gleitkomma \\ ATAN & inverser Tangens & $arg \in \rz$ & Gleitkomma \\ ACOT & inverser Kotangens & $arg \in \rz$ & Gleitkomma \\ & & & \\ EXP & Exponentialfunktion & $arg \in \rz$ & Gleitkomma \\ ALOG & 10 hoch Argument & $arg \in \rz$ & Gleitkomma \\ ALD & 2 hoch Argument & $arg \in \rz$ & Gleitkomma \\ SINH & hyp. Sinus & $arg \in \rz$ & Gleitkomma \\ COSH & hyp. Kosinus & $arg \in \rz$ & Gleitkomma \\ TANH & hyp. Tangens & $arg \in \rz$ & Gleitkomma \\ COTH & hyp. Kotangens & $arg \neq 0$ & Gleitkomma \\ & & & \\ LN & nat. Logarithmus & $arg > 0$ & Gleitkomma \\ LOG & dek. Logarithmus & $arg > 0$ & Gleitkomma \\ LD & 2er Logarithmus & $arg > 0$ & Gleitkomma \\ ASINH & inv. hyp. Sinus & $arg \in \rz$ & Gleitkomma \\ ACOSH & inv. hyp. Kosinus & $arg \geq 1$ & Gleitkomma \\ ATANH & inv. hyp. Tangens & $\mid arg \mid < 1$ & Gleitkomma \\ ACOTH & inv. hyp. Kotangens & $\mid arg \mid > 1$ & Gleitkomma \\ & & & \\ INT & ganzzahliger Anteil & $arg \in \rz$ & Integer \\ & & & \\ BITCNT & bin"are Quersumme & Integer & Integer \\ FIRSTBIT & niedrigstes 1-Bit & Integer & Integer \\ LASTBIT & h"ochstes 1-Bit & Integer & Integer \\ BITPOS & einziges 1-Bit & Integer & Integer \\ & & & \\ SGN & Vorzeichen (0/1/-1) & Integer oder & Integer \\ & & Gleitkomma & \\ \hline \end{tabular}\end{center} \caption{vordefinierte Funktionen in AS - Teil 1 (Integer- und Gleitkommafunktionen)\label{TabFuncs1}} \end{table*} \begin{table*}[htb] \begin{center}\begin{tabular}{|l|l|l|l|} \hline Name & Funktion & Argument & Ergebnis \\ \hline \hline ABS & Betrag & Integer oder & Integer oder \\ & & Gleitkomma & Gleitkomma \\ TOUPPER & pass. Gro"sbuchstabe & Integer & Integer \\ TOLOWER & pass. Kleinbuchstabe & Integer & Integer \\ UPSTRING & wandelt alle Zeichen & String & String \\ & in Gro"sbuchstaben & & \\ LOWSTRING & wandelt alle Zeichen & String & String \\ & in Kleinbuchstaben & & \\ STRLEN & liefert L"ange eines & String & Integer \\ & Strings & & \\ SUBSTR & extrahiert Teil eines & String, & String \\ & Strings & Integer, & \\ & & Integer & \\ STRSTR & sucht Teilstring in & String, & Integer \\ & einem String & String & \\ VAL & evaluiert Stringin- & String & abh. von \\ & halt als Ausdruck & & Argument \\ \hline \end{tabular}\end{center} \caption{vordefinierte Funktionen in AS - Teil 2 (Integer- und String-Funk\-tio\-nen)\label{TabFuncs2}} \end{table*} Die Funktionen \tty{FIRSTBIT}, \tty{LASTBIT} und \tty{BITPOS} liefern als Ergebnis -1, falls "uberhaupt kein bzw. nicht genau ein Bit gesetzt ist. Zus"atzlich gibt \tty{BITPOS} in einem solchen Fall eine Fehlermeldung aus. \par Die String-Funktion \tty{SUBSTR} erwartet als ersten Parameter den Quellstring, als zweiten die Startposition und als dritten die Anzahl zu extrahierender Zeichen (eine 0 bedeutet, alle Zeichen bis zum Ende zu extrahieren). \tty{STRSTR} liefert das erste Auftreten des zweiten Strings im ersten bzw. -1, falls das Suchmuster nicht gefunden wurde. Beide Funktionen numerieren die Zeichen in einem String ab 0 durch! \par Wenn eine Funktion auch Gleitkommaargumente erwartet, so soll dies nicht bedeuten, da"s man nicht z.B. \begin{verbatim} wur2 equ sqrt(2) \end{verbatim} schreiben d"urfte --- in solchen F"allen findet automatisch eine Typkonvertierung statt. Umgekehrt mu"s allerdings die \tty{INT}-Funktion angewandt werden, um eine Gleitkommazahl ganz zu bekommen. Bei der Benutzung dieser Funktion ist zu beachten, da"s sie als Ergebnis immer einen vorzeichenbehafteten Integer liefert, sie hat also einen Wertebereich von ca. +/-2.0E9. \par Schaltet man AS in den case-sensitiven Modus, so k"onnen im Gegensatz zu vordefinierten Symbolen die vordefinierten Funktionen weiterhin in beliebiger Schreibweise angesprochen werden. Bei selbstdefinierten Funktionen (siehe Abschnitt \ref{SectFUNCTION} wird allerdings unterschieden. Dies hat zur Folge, da"s z.B. bei der Definition einer Funktion \tty{Sin} man mit \tty{Sin} diese Funktion auch erreicht, mit allen anderen Schreibweisen jedoch die eingebaute Funktion. \par F"ur die korrekte Umwandlung \marginpar{{\em DOS/}} von Klein-zu Gro"sbuchstaben ist eine DOS-Version $\geq$ 3.30 erforderlich. \vspace{2mm} \marginpar{{\em DPMI}} %%--------------------------------------------------------------------------- \section{Vorw"artsreferenzen und andere Desaster} \label{ForwRefs} Dieser Abschnitt ist das Produkt eines gewissen Grolls auf die (durchaus legale) Art und Weise, wie einige Leute programmieren, die in Zusammenhang mit AS bisweilen das eine oder andere Problem verursachen kann. Die Rede ist hier von sogenannten ,,Vorw"artsreferenzen''. Was unterscheidet eine Vorw"artsreferenz von einer normalen Referenz? Dazu sehe man sich folgendes Programmbeispiel an (man sehe mir bitte meine -- auch im Rest dieser Anleitung anzutreffende -- 68000-Lastigkeit nach): \begin{verbatim} move.l d0,#10 loop: move.l d1,(a1) beq skip neg.l d1 skip: move.l (a1+),d1 dbra d0,loop \end{verbatim} Denkt man sich den Scheifenrumpf mit dem Sprung weg, so bleibt ein "au"serst angenehm zu assemblierendes Programm "ubrig: die einzige Referenz ist der R"ucksprung zum Anfang des Rumpfes, und da ein Assembler ein Programm von vorne nach hinten durcharbeitet, hat er den Symbolwert bereits ermittelt, bevor er ihn zum erstem Mal ben"otigt. Sofern man ein Programm hat, das nur solche R"uckw"artsreferenzen besitzt, ist man in der angenehmen Lage, nur einmal durch den Quellcode gehen zu m"ussen, um den korrekten und optimalen Maschinencode zu finden. Einige Hochsprachen wie Pascal mit ihrer strikten Regel, da"s alles vor der ersten Benutzung definiert sein mu"s, nutzen genau diese Eigenschaft aus, um den "ubersetzungsvorgang zu beschleunigen. Leider ist die Sache im Falle von Assembler nicht so einfach, denn man will ja bisweilen auch vorw"arts im Code springen oder mu"s aus bestimmten Gr"unden Variablendefinitionen hinter den Code verlegen. Dies ist im Beispiel der Fall f"ur den bedingten Sprung, mit dem ein anderer Befehl "ubersprungen wird. Wenn der Assembler im ersten Durchlauf auf den Sprungbefehl trifft, so sieht er sich mit der Situation konfrontiert, entweder die Teilfelder der Instruktion, die die Sprungadresse beinhalten, leerzulassen, oder seitens des Formelparsers (der das Adre"sargument ja auswerten mu"s) anstelle des korrekten, aber unbekannten Wertes einen Wert anzubieten, der ,,niemandem wehtut''. Bei einem einfachen Assembler, der nur eine Zielarchitektur kennt und bei dem sich die betroffenen Befehle an einer Hand abz"ahlen lassen, wird man sicher die erste Variante w"ahlen, bei AS mit seinen vielen Dutzend Zielen w"are die Zahl der Sonderabfragen aber extrem hoch geworden, so da"s nur der zweite Weg in Frage kam: Falls im ersten Pass ein unbekanntes Symbol auftaucht, so liefert der Formelparser den momentanen Stand des Programmz"ahlers als Ergebnis zur"uck! Nur dieser Wert ist geeignet, relativen Spr"ungen mit Sprungdistanzen unbekannter L"ange eine Adresse anzubieten, die nicht zu Fehlern f"uhrt. Dies beantwortet auch die bisweilen gestellte Frage, warum in einem Listing des ersten Passes (dies bleibt z.B. stehen, wenn AS aufgrund anderer Fehler den zweiten Pass erst gar nicht beginnt), z.T. falsche Adressen im erzeugten Bin"arcode gezeigt werden - dies sind noch nicht aufgel"oste Vorw"artsreferenzen. Das obige Beispiel offenbart allerdings noch eine weitere Schwierigkeit von Vorw"artsreferenzen: Je nach Abstand von Quelle und Ziel im Code kann der Sprungbefehl entweder lang oder kurz sein. Diese Entscheidung "uber die Code-L"ange - und damit auch die Adressen folgender Labels - kann jedoch mangels genauer Kenntnis der Zieladresse im ersten Pass nicht erfolgen. Sofern der Programmierer nicht explizit kenntlich gemacht hat, ob der Sprung lang oder kurz sein soll, behelfen sich reine 2-Pass-Assembler wie "altere MASM-Versionen von Microsoft damit, im ersten Pass (nach diesem m"ussen alle Adressen festliegen) Platz f"ur die l"angste Version zu reservieren und im zweiten Pass den "ubersch"ussigen Platz mit \tty{NOP}s aufzuf"ullen. AS-Versionen bis 1.37 taten dieses ebenfalls, danach bin ich auf das Multipass-Verfahren "ubergegangen, das die strenge Einteilung in zwei Passes aufhebt und beliebig viele Durchg"ange erlaubt. Dazu wird im ersten Pass der optimale Code mit den angenommenen Symbolwerten erzeugt. Stellt AS fest, da"s im zweiten Pass durch Codel"angenver"anderungen sich Werte von Symbolen ge"andert haben, so wird einfach noch ein dritter Pass eingelegt, und da durch die neuen Symbolwerte des zweiten Passes auch im dritten Pass sich der Code wieder verk"urzen oder verl"angern kann, ist ein weiterer Pass nicht unm"oglich. Ich habe schon 8086-Programme erlebt, bei denen erst nach 12 Durchg"angen alles stimmte. Leider erlaubt dieser Mechanismus nicht die Vorgabe einer Maximalzahl von Durchl"aufen, ich kann als Regel nur sagen, da"s die Anzahl von Durchl"aufen sinkt, je mehr man davon Gebrauch macht, Sprung- oder Adre"sl"angen explizit vorzugeben. Speziell bei gro"sen Programmen kann es zu einer interessanten Situation kommen: Die Lage eines vorw"arts gerichteten Sprunges hat sich im zweiten Pass so weit gegen"uber dem ersten verschoben, da"s der jetzt noch benutzte Label-Wert aus dem ersten Pass au"serhalb der erlaubten Sprungdistanz liegt. AS ber"ucksichtigt solche Situationen, indem er jegliche Fehlermeldungen "uber zu weite Sprungdistanzen unterdr"uckt, sobald er erkannt hat, da"s er wegen sich "andernder Symbolwerte ohnehin einen weiteren Durchlauf machen mu"s. Dies funktioniert zwar in 99\% aller F"alle, es gibt jedoch auch Konstrukte, in denen der erste, derartig kritische Befehl bereits auftaucht, bevor AS eine Chance hat, zu erkennen, da"s ein neuer Pass erforderlich ist. Das folgende Beispiel konstruiert eine solche Situation mit Hilfe einer Vorw"artsreferenz (und war der Anla"s f"ur die "Uberschrift dieses Abschnitts...): \begin{verbatim} cpu 6811 org $8000 beq skip rept 60 ldd Var endm skip: nop Var equ $10 \end{verbatim} Aufgrund der Adre"slage nimmt AS im ersten Pass lange Adressen f"ur die \tty{LDD}-Befehle an, was eine Code-L"ange von 180 Bytes ergibt und im zweiten Pass (zum Zeitpunkt des \tty{BEQ}-Befehls ist noch der ,,falsche'' Wert von \tty{skip} aktuell, d.h. AS wei"s zu diesem Zeitpunkt noch nicht, da"s der Code in Wirklichkeit nur 120 Bytes lang ist) gibt es eine Fehlermeldung wegen einer "uberschrittenen Sprungdistanz. Dieser Fehler l"a"st sich auf drei Arten vermeiden: \begin{enumerate} \item{Weisen Sie AS explizit darauf hin, da"s er f"ur die \tty{LDD}-Befehle kurze Adressen verwenden darf (\tty{ldd label $ \end{verbatim} erzeugt aber ein Symbol mit korrekten Attributen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BIT} \ttindex{BIT} {\em G"ultigkeit: MCS-(2)51, XA, 80C166, 75K0, ST9} \tty{BIT} dient dazu, ein einzelnes Bit einer Speicherstelle mit einem symbolischen Namen gleichzusetzen. Da die Art und Weise, wie verschiedene Prozessoren Bitverarbeitung und -adressierung betreiben, stark variiert, verh"alt sich auch dieser Befehl je nach Zielplattform anders: \par F"ur die MCS/51-Familie, die einen eigenen Adre"sraum f"ur Bitoperanden besitzt, ist die Funktion von \tty{BIT} ganz analog zu \tty{SFR}, d.h. es wird einfach ein Integer-Symbol mit dem angegebenen Wert und dem Segment BDATA erzeugt. F"ur alle anderen Prozessoren wird die Bitadressierung dagegen zweidimensional mit Adresse und Bitstelle vorgenommen. In diesem Fall verpackt AS beide Teile in einer vom jeweiligen Prozessor abh"angigen Weise in ein Integer-Symbol und dr"oselt dieses bei der Benutzung wieder in die beiden Teile auseinander. Letzterer Fall trifft auch schon f"ur den 80C251 zu: W"ahrend zum Beispiel der Befehl \begin{verbatim} Mein_Carry bit PSW.7 \end{verbatim} auf einem 8051 noch dem Symbol \tty{Mein\_Carry} den Wert 0d7h zuweisen w"urde, w"urde auf einem 80C251 dagegen ein Wert von 070000d0h generiert werden, d.h. die Adresse steht in Bit 0..7 sowie die Bitstelle in Bit 24..26. Dieses Verfahren entspricht dem, das auch beim DBIT- Befehl des TMS370 angewendet wird und funktioniert sinngem"a"s so auch beim 80C166, nur da"s dort Bitstellen von 0 bis 15 reichen d"urfen: \begin{verbatim} MSB BIT r5.15 \end{verbatim} Beim Philips XA findet sich in Bit 0..9 die Bitadresse, wie sie auch in die Maschinenbefehle eingesetzt wird, f"ur Bits aus den RAM-Speicher wird in Bit 16..23 die 64K-Bank eingesetzt. \par Noch etwas weiter geht der \tty{BIT}-Befehl bei der 75K0-Familie: Da dort Bitadressierungen nicht nur absolute Basisadressen verwenden d"urfen, sind sogar Ausdr"ucke wie \begin{verbatim} bit1 BIT @h+5.2 \end{verbatim} erlaubt. \par Beim ST9 ist es hingegen m"oglich, Bits auch invertiert anzusprechen, was beim \tty{BIT}-Befehl auch ber"ucksichtigt wird: \begin{verbatim} invbit BIT r6.!3 \end{verbatim} N"aheres zum \tty{BIT}-Befehl beim ST9 findet sich bei den prozessorspezifischen Hinweisen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DBIT} \ttindex{DBIT} {\em G"ultigkeit: TMS 370xxx} Die TMS370-Reihe hat zwar kein explizites Bit-Segment, jedoch k"onnen einzelne Bits als Symbol durch diesen Befehl simuliert werden. \tty{DBIT} ben"otigt zwei Operanden, n"amlich einmal die Adresse der Speicherstelle, in der das Bit liegt, sowie die genaue Position des Bits im Byte. So definiert man z.B. mit \begin{verbatim} INT3 EQU P019 INT3_ENABLE DBIT 0,INT3 \end{verbatim} das Bit, welches Interrupts von Anschlu"s INT3 freigibt. So definierte Bits k"onnen dann von den Befehlen \tty{SBIT0, SBIT1, CMPBIT, JBIT0} und \tty{JBIT} genutzt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PORT} \ttindex{PORT} {\em G"ultigkeit: 8080/8085/8086, XA, Z80, 320xx, TLCS-47, AVR} \tty{PORT} arbeitet analog zu \tty{SFR}, nur wird das Symbol dem I/O-Adre"sbereich zugeordnet. Erlaubte Werte sind 0..7 beim 3201x, 0..15 beim 320C2x, 0..65535 beim 8086, 0..63 beim AVR und 0..255 beim Rest. \par Beispiel: eine PIO 8255 liege auf Adresse 20H: \begin{verbatim} PIO_Port_A PORT 20h PIO_Port_B PORT PIO_Port_A+1 PIO_Port_C PORT PIO_Port_A+2 PIO_Ctrl PORT PIO_Port_A+3 \end{verbatim} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{REG} \ttindex{REG} {\em G"ultigkeit: AVR, M*Core, ST9, 80C16x} Obwohl immer mit gleicher Syntax, hat diese Anweisung von Prozessor zu Prozessor eine leicht abweichende Bedeutung: Falls der Zielprozessor f"ur Register einen eigenen Adre"sraum verwendet, so hat \tty{REG} die Wirkung eines simplen \tty{EQU}s f"ur eben diesen Adre"sraum (z.B. beim ST9). F"ur alle anderen Prozessoren definiert \tty{REG} Registersymbole, deren Funktion in Abschnitt \ref{SectRegSyms} beschrieben sind. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{LIV und RIV} \ttindex{LIV}\ttindex{RIV} {\em G"ultigkeit: 8X30x} \tty{LIV} und \tty{RIV} dienen dazu, sogenannte IV-Bus-Objekte zu definieren. Bei diesen handelt es sich um Bitgruppen in peripheren Speicherzellen mit einer L"ange von 1..8 Bit, die fortan symbolisch angesprochen werden k"onnen, so da"s man bei den entsprechenden Befehlen nicht mehr Adresse, L"ange und Position separat angeben mu"s. Da die 8X30x-Prozessoren zwei periphere Adre"sr"aume besitzen (einen ,,linken'' und einen ,,rechten'', sind auch zwei separate Befehle definiert. Die Parameter dieser Befehle sind allerdings identisch: es m"ussen drei Parameter sein, die Adresse, Startposition und L"ange angeben. Weitere Hinweise zur Benutzung von Busobjekten finden sich in Abschnitt \ref{8X30xSpec}. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{CHARSET} \ttindex{CHARSET} {\em G"ultigkeit: alle Prozessoren} Einplatinensysteme, zumal wenn sie LCDs ansteuern, benutzen h"aufig einen anderen Zeichensatz als ASCII, und da"s die Umlautkodierung mit der im PC "ubereinstimmt, d"urfte wohl reiner Zufall sein. Um nun aber keine fehlertr"achtigen Handumkodierungen vornehmen zu m"ussen, enth"alt der Assembler eine Umsetzungstabelle f"ur Zeichen, die jedem Quellcode ein Zielzeichen zuordnet. Zur Modifikation dieser Tabelle (die initial 1:1 "ubersetzt), dient der Befehl \tty{CHARSET}. \tty{CHARSET} kann mit verschiedenen Parameterzahlen und -typen angewendet werden. Ist die Parameterzahl eins, so mu"s es sich um einen String-Ausdruck handeln, der von AS als Dateiname interpretiert wird. Aus dieser Datei liest AS dann die ersten 256 Bytes aus und kopiert sie in die "Ubersetzungstabelle. Hiermit lassen sich also komplexere, extern erzeugte Tabellen in einem Schlag aktivieren. In allen anderen Varianten mu"s der erste Parameter ein Integer im Bereich von 0 bis 255 sein, der den Startpunkt der in der "Ubersetzungstabelle zu modifizierenden Eintr"age angibt. Es folgen dann ein oder zwei weitere Parameter, die die Art der "Ubersetzung angeben: Ein einzelner, weiterer Integer ver"andert genau einen Eintrag. So bedeutet z.B. \begin{quote}{\tt CHARSET '"a',128} \end{quote} da"s das Zielsystem das "a mit der Zahl 128 kodiert. Sind jedoch zwei weitere Integers angegeben, so ist der erste von ihnen der letzte zu modifizierende Eintrag, der zweite der neue Wert des ersten Eintrags; alle weiteren Eintr"age bis zum Bereichsende werden sequentiell neu belegt. Falls z.B. das Zielsystem keine Kleinbuchstaben unterst"utzt, k"onnen mit \begin{verbatim} CHARSET 'a','z','A' \end{verbatim} alle Kleinbuchstaben auf die passenden Gro"sbuchstaben automatisch umgemappt werden. In der letzten Variante folgt nach dem Startindex ein String, der die ab dem Startindex abzulegenden Zeichen angibt. Das letzte Beispiel k"onnte man also auch so formulieren: \begin{verbatim} CHARSET 'a',"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \end{verbatim} \tty{CHARSET} kann auch ganz ohne Parameter aufgerufen werden, allerdings mit ziemlich gr"undlichen Folgen: Dies bewirkt eine Reinitialisierung der "Ubersetzungstabelle in ihren Urzustand, d.h. man bekommt wieder eine 1:1-"Ubersetzung. \bb{ACHTUNG!} \tty{CHARSET} beeinflu"st nicht nur im Speicher abgelegte Stringkonstanten, sondern auch als ,,ASCII'' formulierte Integerkonstanten. Dies bedeutet, da"s eine evtl. bereits modifizierte Umsetzungstabelle in den obigen Beispielen zu anderen Ergebnissen f"uhren kann! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{CODEPAGE} \ttindex{CODEPAGE} {\em G"ultigkeit: alle Prozessoren} Mit der \tty{CHARSET}-Anweisung hat man zwar beliebige Freiheiten in der Zeichenzuordnung zwischen Entwicklungs- und Zielplattform, wenn auf der Zielplattform jedoch verschiedene Zeichens"atze existieren, kann das Umschalten zwischen diesen jedoch zu einer umst"andlichen Orgie von \tty{CHARSET}-Kommandos werden. Mit der \tty{CODEPAGE}-Anweisung kann man jedoch mehrere Zeichentabellen vorhalten und zwischen diesen mit einem Befehl umschalten. Als Parameter erwartet \tty{CODEPAGE} ein oder zwei Namen: zum einen den Namen der fortan zu benutzenden Tabelle, zum anderen optional den Namen der Tabelle, die die initiale Belegung der Tabelle vorgibt (dieser Parameter hat somit auch nur eine Bedeutung beim ersten Umschalten auf eine Tabelle, bei der AS sie automatisch anlegt). Fehlt der zweite Parameter, so ist die initiale Belegung der neuen Tabelle gleich der vorher aktiven Tabelle. Alle folgenden \tty{CHARSET}-Anweisungen verändern {\em nur} die momentan aktive Tabelle. Zu Beginn eines Durchlaufes wird von AS automatisch eine einzelne Zeichentabelle mit dem Namen \tty{STANDARD} erzeugt und 1:1 vorbelegt. Verwendet man keine \tty{CODEPAGE}-Anweisungen, so beziehen sich alle mit \tty{CHARSET} gemachten Einstellungen auf diese Tabelle. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ENUM} \ttindex{ENUM} {\em G"ultigkeit: alle Prozessoren} \tty{ENUM} dient analog zu dem entsprechenden Befehl in C dazu, Aufz"ahlungstypen zu definieren, d.h. eine Reihe von Integer-Konstanten, denen fortlaufende Werte (von 0 an beginnend) zugewiesen werden. Als Parameter werden dabei die Namen der zu definierenden Symbole angegeben, wie in dem folgenden Beispiel: \begin{quote}{\tt ENUM SymA,SymB,SymC} \end{quote} Dieser Befehl weist den Symbolen \tty{SymA}, \tty{SymB} und \tty{SymC} die Werte 0, 1 und 2 zu. \par \tty{ENUM}-Befehle sind von Hause aus einzeilig, d.h. bei einem neuen \tty{ENUM}-Befehl beginnt die Numerierung wieder bei Null. Mehrzeilige Aufz"ahlungen kann man aber mit einem kleinen Trick erreichen, der die Tatsache ausnutzt, da"s man mit einer expliziten Zuweisung den internen Z"ahler neu setzen kann, wie in dem folgenden Fall: \begin{quote}{\tt ENUM Januar=1,Februar,M"arz,April,Mai,Juni} \end{quote} Hier werden den Monatsnamen die Zahlenwerte 1..6 zugewiesen. M"ochte man die Aufz"ahlung nun fortsetzen, geht das folgenderma"sen: \begin{quote}{\tt ENUM Juli=Juni+1,August,September,Oktober \\ ENUM November=Oktober+1,Dezember }\end{quote} Die Definition von Symbolen mit \tty{ENUM} gleicht einer Definition mit \tty{EQU}, d.h. es ist nicht m"oglich, einem Symbol einen neuen Wert zuzuweisen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{STRUCT und ENDSTRUCT} \ttindex{STRUCT}\ttindex{ENDSTRUCT} {\em G"ultigkeit: alle Prozessoren} Auch in Assemblerprogrammen ergibt sich dann und wann die Notwendigkeit, analog zu Hochsprachen zusammengesetzte Datenstrukturen zu definieren. AS unterst"utzt dies mit den Befehlen \tty{STRUCT} und \tty{ENDSTRUCT}, die die Definition einer solchen Struktur einleiten bzw. abschlie"sen. Das Verfahren ist simpel: Mit einem \tty{STRUCT} wird der momentane Programmz"ahler gesichert und auf Null zur"uckgesetzt. Alle Labels ergeben mithin die Offsets der einzelnen Datenfelder in der Struktur. Die Reservierung des Platzes f"ur die einzelnen Felder erfolgt mit den f"ur den jeweils aktiven Zielprozessor zul"assigen Befehlen zur Speicherplatzreservierung, also z.B. \tty{DS.x} f"ur die Motorolas oder \tty{DB} \& Co. f"ur Intels. Das dem \tty{STRUCT}-Befehl vorangestellte (nicht optionale) Label ist der Name des Records und kann optional beim \tty{ENDSTRUCT}-Befehl wiederholt werden. Weiterhin legt \tty{ENDSTRUCT} in \tty{$<$Name$>$\_len} die Gesamtl"ange der Struktur ab (man kann auch die Verwendung eines anderen Symbolnamens erzwingen, indem man dessen Name als Argument von \tty{ENDSTRUCT} angibt). In der Definition \begin{verbatim} Rec STRUCT Ident db ? Pad db ? Pointer dd ? Rec ENDSTRUCT \end{verbatim} w"urde also dem Symbol \tty{Rec\_len} der Wert 6 zugewiesen. \bb{ACHTUNG!} Innerhalb einer Strukturdefinition d"urfen keine Befehle verwendet werden, die Code erzeugen, da es sich hier um eine reine Anordnung von Elementen im Adre"sraum handelt! \tty{STRUCT}-Definitionen d"urfen auch geschachtelt werden; nach Beendigung der inneren \tty{STRUCT}-Definition wird dann der Adre"sz"ahler der "au"seren Struktur automatisch um die Gr"o"se der inneren Struktur inkrementiert (die Z"ahlung innerhalb der inneren Struktur l"auft nat"urlich ab 0). Um Mehrdeutigkeiten bei gleichnamigen Feldern in verschiedenen Strukturen zu vermeiden, stellt AS den Feldnamen defaultm"a"sig den Namen der Struktur, mit einem Unterstrich getrennt, voran. Im obigen Beispiel w"urden also die Symbole \tty{Rec\_Ident, Rec\_Pad} und \tty{Rec\_Pointer} erzeugt. Diese Verhalten l"a"st sich unterbinden, indem man als Parameter der \tty{STRUCT}-Anweisung ein \tty{NOEXTNAMES} anbringt. Bei geschachtelten Strukturdefinitionen funktioniert dies sinngem"a"s, d.h Feldnamen werden um die Namen aller sie umschlie"senden Strukturen erweitert, die keine \tty{NOEXTNAMES}-Direktive bekamen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PUSHV und POPV} \ttindex{PUSHV}\ttindex{POPV} {\em G"ultigkeit: alle Prozessoren} Mit \tty{PUSHV} und \tty{POPV} ist es m"oglich, den Wert von (nicht makrolokalen) Symbolen tempor"ar zu speichern und zu einem sp"ateren Zeitpunkt wiederherzustellen. Die Speicherung erfolgt auf {\em Stacks}, d.h. Last-In-First-Out-Speichern. Ein Stack hat einen Namen, der den allgemeinen Symbolkonventionen gen"ugen mu"s, und existiert so lange, wie er mindestens ein Element enth"alt: Ein bisher nicht existierender Stack wird bei \tty{PUSHV} automatisch angelegt, ein durch \tty{POPV} leer werdender Stack wird automatisch wieder aufgel"ost. Der Name des Stacks, auf den Symbole abgelegt und von dem sie wieder abgeholt werden sollen, ist der erste Parameter von \tty{PUSHV} bzw. \tty{POPV}, danach folgt eine beliebige Menge von Symbolen als weitere Parameter. Alle in der Liste aufgef"uhrten Symbole m"ussen bereits existieren, es ist also {\em nicht} m"oglich, mit einem \tty{POPV}-Befehl implizit neue Symbole zu definieren. \par Stacks stellen eine globale Ressource dar, d.h. ihre Namen sind nicht lokal zu Sektionen. \par Wichtig ist, da"s die Variablenliste {\em immer} von links nach rechts abgearbeitet wird. Wer also mehrere Variablen mit \tty{POPV} von einem Stack herunterholen will, mu"s diese in genau umgekehrter Reihenfolge zum entsprechenden \tty{PUSHV} angeben! \par Der Name des Stacks kann auch weggelassen werden, etwa so: \begin{verbatim} pushv ,var1,var2,var3 . . popv ,var3,var2,var1 \end{verbatim} AS verwendet dann einen internen, vordefinierten Default-Stack. \par Nach Ende eines Durchlaufes "uberpr"uft AS, ob noch Stacks existieren, die nicht leer sind, und gibt deren Namen sowie ,,F"ullstand'' aus. Mit diesen Warnungen kann man herausfinden, ob an irgendeiner Stelle die \tty{PUSHV}'s und \tty{POPV}'s nicht paarig sind. Es ist jedoch in keinem Fall m"oglich, Symbolwerte in einem Stack "uber mehrere Durchl"aufe hinwegzuretten: Zu Beginn eines Durchlaufes werden alle Stacks geleert! %%--------------------------------------------------------------------------- \section{Codebeeinflussung} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ORG} \label{SectORG}\ttindex{ORG} {\em G"ultigkeit: alle Prozessoren} \tty{ORG} erlaubt es, den assemblerinternen Adre"sz"ahler mit einem neuen Wert zu besetzen. Der Wertebereich ist vom momentan gew"ahlten Segment und vom Prozessortyp abh"angig (Tabellen \ref{TabORG1} bis \ref{TabORG4}). Die untere Grenze ist dabei immer 0; die obere Grenze der angegebene Wert minus eins. \par Falls in einer Familie verschiedene Varianten unterschiedlich gro"se Adre"sr"aume haben, ist jeweils der maximale Raum aufgef"uhrt. \par ORG wird in erster Linie ben"otigt, um dem Code eine neue Startadresse zu geben und damit verschiedene, nicht zusammenh"angende Codest"ucke in einer Quelldatei unterzubringen. Sofern nicht in einem Feld explizit anders angegeben, ist die vorgegebene Startadresse in einem Segment (d.h. die ohne {\tt ORG} angenommene) immer 0. \small \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|c|c|c|c|c|c|c|c|c|} \hline \tin{Prozessor} & \tin{CODE} & \tin{DATA} & \tin{IDATA} & \tin{XDATA} & \tin{YDATA} & \tin{BITDATA} & \tin{IO} & \tin{REG} & \tin{ROMDATA} \\ \hline \hline \input{taborg1.tex} \hline \end{tabular}\end{center} \caption{Adre"sbereiche f"ur \tty{ORG} --- Teil 1\label{TabORG1}} \end{table*} \clearpage \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|c|c|c|c|c|c|c|c|c|} \hline \tin{Prozessor} & \tin{CODE} & \tin{DATA} & \tin{IDATA} & \tin{XDATA} & \tin{YDATA} & \tin{BITDATA} & \tin{IO} & \tin{REG} & \tin{ROMDATA} \\ \hline \hline \input{taborg2.tex} \hline \multicolumn{10}{|l|}{* Da der 8051 kein RAM jenseits 80h hat, mu"s der Initialwert f"ur den 8051} \\ \multicolumn{10}{|l|}{ als Zielprozessor auf jeden Fall mit \tty{ORG} angepa"st werden!!} \\ \hline \multicolumn{10}{|l|}{+ Da der Z180 weiterhin logisch nur 64K ansprechen kann, ist der} \\ \multicolumn{10}{|l|}{ganze Adre"sraum nur mittels \tty{PHASE}-Anweisungen erreichbar!} \\ \hline \end{tabular}\end{center} \caption{Adre"sbereiche f"ur \tty{ORG} --- Teil 2\label{TabORG2}} \end{table*} \clearpage \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|c|c|c|c|c|c|c|c|c|} \hline \tin{Prozessor} & \tin{CODE} & \tin{DATA} & \tin{IDATA} & \tin{XDATA} & \tin{YDATA} & \tin{BITDATA} & \tin{IO} & \tin{REG} & \tin{ROMDATA} \\ \hline \hline \input{taborg3.tex} \hline \end{tabular}\end{center} \caption{Adre"sbereiche f"ur \tty{ORG} --- Teil 3\label{TabORG3}} \end{table*} \clearpage \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|c|c|c|c|c|c|c|c|c|} \hline \tin{Prozessor} & \tin{CODE} & \tin{DATA} & \tin{IDATA} & \tin{XDATA} & \tin{YDATA} & \tin{BITDATA} & \tin{IO} & \tin{REG} & \tin{ROMDATA} \\ \hline \hline \input{taborg4.tex} \hline \end{tabular}\end{center} \caption{Adre"sbereiche f"ur \tty{ORG} --- Teil 4\label{TabORG4}} \end{table*} \normalsize %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{CPU} \ttindex{CPU} {\em G"ultigkeit: alle Prozessoren} Mit diesem Befehl wird festgelegt, f"ur welchen Prozessor im weiteren Code erzeugt werden soll. Die Befehle der anderen Prozessorfamilien sind dann nicht greifbar und erzeugen eine Fehlermeldung! \par Die Prozessoren k"onnen grob in Familien unterschieden werden, in den Familien dienen unterschiedliche Typen noch einmal zur Feinunterscheidung: %%----------- \begin{quote} \begin{tabbing} \hspace{0.7cm} \= \kill a) \> 68008 $\rightarrow$ 68000 $\rightarrow$ 68010 $\rightarrow$ 68012 $\rightarrow$ \\ \> MCF5200 $\rightarrow$ 68332 $\rightarrow$ 68340 $\rightarrow$ 68360 $\rightarrow$ \\ \> 68020 $\rightarrow$ 68030 $\rightarrow$ 68040 \end{tabbing} \end{quote} In dieser Familie liegen die Unterschiede in hinzukommenden Befehlen und Adressierungsarten (ab 68020). Eine kleine Ausnahme stellt der Schritt zum 68030 dar, dem 2 Befehle fehlen: \tty{CALLM} und \tty{RTM}. Die drei Vertreter der 683xx-Famile haben den gleichen Prozessorkern (eine leicht abgemagerte 68020-CPU), jedoch v"ollig unterschiedliche Peripherie. MCF5200 repr"asentiert die ColdFire-Familie von Motorola, zum 680x0 bin"ar abw"artskompatible RISC-Prozesoren. Beim 68040 kommen die zus"atzlichen Steuerregister (via \tty{MOVEC} erreichbar) f"ur On-Chip-MMU und Caches sowie einige Systembefehle f"ur selbige hinzu. %%----------- \begin{quote} b) 56000 $\longrightarrow$ 56002 $\longrightarrow$ 56300 \end{quote} W"ahrend der 56002 nur Befehle zum Inkrementieren und Dekrementieren der Akkus erg"anzt, ist der 56300-Kern schon fast ein neuer Prozessor: Er vergr"o"sert alle Adre"sr"aume von 64K-W"ortern auf 16M und verdoppelt fast die Anzahl der Befehle. %%----------- \begin{quote} c) PPC403 $\rightarrow$ PPC403GC $\rightarrow$ MPC505 $\rightarrow$ MPC601 $\rightarrow$ RS6000 \end{quote} Der PCC403 ist eine abgespeckte Version der PowerPC-Linie ohne Gleitkommaeinheit, demzufolge sind s"amtliche Gleitkommabefehle bei ihm gesperrt; daf"ur sind einige mikrocontrollerspezifische Befehle enthalten, die er als einziges Mitglied in dieser Familie kennt. Die GC-Variante des PPC403 hat zus"atzlich eine MMU und deshalb einige Befehle zu deren Steuerung mehr. Der MPC505 (eine Mikrokontroller-Variante mit FPU) unterscheidet sich solange vom 601er nur in den Peripherieregistern, wie ich es nicht besser wei"s - \cite{Mot505} h"alt sich da noch etwas bedeckt... Die RS6000-Reihe kennt noch einige Befehle mehr (die auf vielen 601er-Systemen emuliert werden, um vollst"andige Kompatibilit"at herzustellen), au"serdem verwendet IBM z.T. andere Mnemonics f"ur diese reinen Workstation-Prozessoren, als Remineszenz an die 370er-Gro"srechner... %%----------- \begin{quote} d) MCORE \end{quote} %%----------- \begin{quote} e) 6800 $\rightarrow$ 6301 $\rightarrow$ 6811 \end{quote} W"ahrend der 6301 nur neue Befehle definiert, liefert der 6811 neben weiteren Befehlen ein zweites Indexregister Y zur Adressierung. %%----------- \begin{quote} f) 6809/6309 und 6805/68HC08 \end{quote} Diese Prozessoren sind zwar teilweise quellcodekompatibel zu den anderen 68xx-ern, haben aber ein anderes Bin"arcodeformat und einen deutlich eingeschr"ankteren (6805) bzw. erweiterten (6809) Befehlssatz. Der 6309 ist eine CMOS-Version des 6809, die zwar offiziell nur kompatibel zum 6809 ist, inoffiziell aber mehr Register und deutlich mehr Befehle besitzt (siehe \cite{Kaku}). %%----------- \begin{quote} g) 68HC12 \end{quote} %%----------- \begin{quote} h) 68HC16 \end{quote} %%----------- \begin{quote} i) HD6413308 $\longrightarrow$ HD6413309 \end{quote} Diese beiden Namen repr"asentieren die 300er und 300H-Varianten der H8-Familie; die H-Version besitzt dabei einen gr"o"seren Adre"sraum (16 Mbyte statt 64Kbyte), doppelt so breite Register (32 Bit) und kennt einige zus"atzliche Befehle und Adressierungsarten. Trotzdem ist sie bin"ar aufw"artskompatibel. %%----------- \begin{quote} j) HD6475328 $\longrightarrow$ HD6475348 $\longrightarrow$ HD6475368 $\longrightarrow$ HD6475388 \end{quote} Diese Prozessoren besitzen alle den gleichen CPU-Kern; Die unter- schiedlichen Typen dienen lediglich der Einbindung des korrekten Registersatzes in der Datei \tty{REG53X.INC}. %%----------- \begin{quote} k) SH7000 $\longrightarrow$ SH7600 $\longrightarrow$ SH7700 \end{quote} Der Prozessorkern des 7600ers bietet eine Handvoll Befehle mehr, die L"ucken im Befehlssatz des 7000ers schlie"sen (verz"ogerte, bedingte sowie relative und indirekte Spr"unge, Multiplikationen mit 32-Bit-Operanden sowie Multiplizier/Addier-Befehle). Die 7700er-Reihe (auch als SH3 gel"aufig) bietet weiterhin eine zweite Registerbank, bessere Schiebebefehle sowie Befehle zur Cache-Steuerung. %%----------- \begin{quote} l) 6502 $\rightarrow$ 65(S)C02 / MELPS740 \end{quote} Die CMOS-Version definiert einige zus"atzliche Befehle, au"serdem sind bei einigen Befehlen Adressierungsarten hinzugekommen, die beim 6502 nicht m"oglich waren. Die Mitsubishi-Mikrokontroller dagegen erweitern den 6502-Befehlssatz in erster Linie um Bitoperationen und Multiplikations-/Divisionsbefehle. Bis auf den unbedingten Sprung und Befehle zur Inkrementierung/Dekremetierung des Akkumulatos sind die Erweiterungen disjunkt. Dem 65SC02 fehlen die Bitmanipulationsbefehle des 65C02. Mit dem Prozessortyp 6502UNDOC sind die ,,undokumentierten'' 6502-Befehle erreichbar, d.h. die Operationen, die sich bei der Verwendung nicht als Befehle definierter Bitkombinationen im Opcode ergeben. Die von AS unterst"utzten Varianten sind im Kapitel mit den prozessorspezifischen Hinweisen beschrieben. %%----------- \begin{quote} m) MELPS7700, 65816 \end{quote} Neben einer ,,16-Bit-Version'' des 6502-Befehlssatzes bieten diese Prozessoren einige Befehlserweiterungen. Diese sind aber gr"o"serenteils disjunkt, da sie sich an ihren jeweiligen 8-bittigen Vorbildern (65C02 bzw. MELPS-740) orientieren. Z.T.~werden auch andere Mnemonics f"ur gleiche Befehle verwendet. %%----------- \begin{quote} n) MELPS4500 \end{quote} %%----------- \begin{quote} o) M16 \end{quote} %%----------- \begin{quote} p) M16 \end{quote} %%----------- \begin{quote} q) 4004 \end{quote} %%----------- \begin{quote} r) 8021, 8022, 8039, 80C39, 8048, 80C48, 8041, 8042 \end{quote} Bei den ROM-losen Versionen 8039 und 80C39 sind die Befehle verboten, die den BUS (Port 0) ansprechen. Der 8021 und 8022 sind Sonderversionen mit stark abgemagertem Befehlssatz, wof"ur der 8022 zwei A/D-Wandler und die dazugeh"origen Steuerbefehle enth"alt. Die CMOS-Versionen lassen sich mit dem \tty{IDL}-Befehl in einen Ruhezustand niedriger Stromaufnahme "uberf"uhren. Der 8041 und 8042 haben einige Zusatzbefehle zur Steuerung der Busschnittstelle, daf"ur fehlen aber einige andere Befehle. Dar"uber hinaus ist bei diesen Prozessoren der Programmadre"sraum nicht extern erweiterbar, weshalb AS das Codesegment bei diesen Prozessoren auf 1 bzw. 2 Kbyte begrenzt. %%----------- \begin{quote} \begin{tabbing} \hspace{0.7cm} \= \kill s) \> 87C750 $\rightarrow$ 8051, 8052, 80C320, 80C501, 80C502, \\ \> 80C504, 80515, and 80517 $\rightarrow$ 80C251 \end{tabbing} \end{quote} Der 87C750 kann nur max. 2 Kbyte Programmspeicher adressieren, weshalb die \tty{LCALL}- und \tty{LJMP}-Befehle bei ihm fehlen. Zwischen den acht mittleren Prozessoren nimmt AS selber "uberhaupt keine Unterscheidung vor, sondern verwaltet den Unterschied lediglich in der Variablen \tty{MOMCPU} (s.u.), die man mit \tty{IF}-Befehlen abfragen kann. Eine Ausnahme stellt lediglich der 80C504, der in seiner momentanen Form noch einen Maskenfehler zeigt, wenn eine \tty{AJMP}- oder \tty{ACALL}-Anweisung auf der vorletzten Adresse einer 2K-Seite steht. AS benutzt in einem solchen Fall automatisch lange Sprungbefehle bzw. gibt eine Fehlermeldung aus. Der 80C251 hingegen stellt einen drastischen Fortschritt in Richtung 16/32 Bit, gr"o"serer Adre"sr"aume und orthogonalerem Befehlssatz dar. %%----------- \begin{quote} t) 8096 $\rightarrow$ 80196 $\rightarrow$ 80196N $\rightarrow$ 80296 \end{quote} Neben einem anderen Satz von SFRs (die "ubrigens von Unterversion zu Unterversion stark differieren) kennt der 80196 eine Reihe von zus"atzlichen Befehlen und kennt einen ,,Windowing''-Mechanismus, um das gr"o"sere interne RAM anzusprechen. Die 80196N-Familie wiederum erweitert den Adre"sraum auf 16 Mbyte und f"uhrt eine Reihe von Befehlen ein, mit denen man auf Adressen jenseits 64 Kbyte zugreifen kann. Der 80296 erweitert den CPU-Kern um Befehle zur Signalverarbeitung und ein zweites Windowing-Register, verzichtet jedoch auf den {\em Peripheral Transaction Server} (PTS) und verliert damit wieder zwei Maschinenbefehle. %%----------- \begin{quote} u) 8080 und 8085 \end{quote} Der 8085 kennt zus"atzlich die Befehle \tty{RIM} und \tty{SIM} zum Steuern der Interruptmaske und der zwei I/O-Pins. %%----------- \begin{quote} v) 8086 $\rightarrow$ 80186 $\rightarrow$ V30 $\rightarrow$ V35 \end{quote} Hier kommen wieder nur neue Befehle dazu. Die entsprechenden 8-Bitter sind wegen ihrer Befehlskompatibilit"at nicht aufgef"uhrt, f"ur ein 8088-System ist also z.B. 8086 anzugeben. %%----------- \begin{quote} w) 80960 \end{quote} %%----------- \begin{quote} x) 8X300 $\rightarrow$ 8X305 \end{quote} Der 8X305 besitzt eine Reihe zus"atzlicher Arbeitsregister, die dem 8X300 fehlen und kann mit diesen auch zus"atzliche Operationen ausf"uhren, wie das direkte Schreiben von 8-Bit-Werten auf Peripherieadressen. %%----------- \begin{quote} y) XAG1, XAG2, XAG3 \end{quote} Diese Prozessoren unterscheiden sich nur in der Gr"o"se des eingebauten ROMs, die in \tty{STDDEFXA.INC} definiert ist. %%----------- \begin{quote} z) AT90S1200 $\rightarrow$ AT90S2313 $\rightarrow$ AT90S4414 $\rightarrow$ AT90S8515 \end{quote} Der erste Vertreter der AVR-Reihe stellt die Minimalkonfiguration dar, ohne RAM-Speicher und demzufolge auch ohne Load/Store-Befehle. Die beiden anderen Prozessoren unterscheiden sich nur im Speicherausbau und in der eingebauten Peripherie, was in \tty{REGAVR.INC} differenziert wird. %%----------- \begin{quote} aa) AM29245 $\rightarrow$ AM29243 $\rightarrow$ AM29240 $\rightarrow$ AM29000 \end{quote} Je weiter man sich in der Liste nach rechts bewegt, desto weniger Befehle m"ussen in Software emuliert werden. W"ahrend z.B. der 29245 noch nicht einmal einen Hardware-Multiplizierer besitzt, fehlen den beiden Vertretern in der Mitte nur die Gleitkommabefehle. Der 29000 dient dabei als ,,generischer'' Typ, der alle Befehle in Hardware versteht. %%----------- \begin{quote} ab) 80C166 $\longrightarrow$ 80C167,80C165,80C163 \end{quote} 80C167 und 80C165/163 haben anstelle 256 Kbyte max. 16 Mbyte Adre"sraum, au"serdem kennen sie einige zus"atzliche Befehle f"ur erweiterte Adressierungsmodi sowie atomare Befehlssequenzen. Untereinander unterscheiden sich diese Prozessoren der ,,zweiten Generation'' nur in der eingebauten Peripherie. %%----------- \begin{quote} ac) Z80 $\rightarrow$ Z80UNDOC $\rightarrow$ Z180 $\rightarrow$ Z380 \end{quote} W"ahrend f"ur den Z180 nur die zus"atzlichen Befehle definiert sind (d.h. die Z180-MMU findet noch keine Ber"ucksichtigung), besitzt der Z380 32-Bit-Register, einen linearen 4Gbyte-Adre"sraum sowie neben einer Reihe von Befehlserweiterungen, die den Befehlssatz deutlich orthogonaler machen, neue Adressierungsmodi (Ansprechen der Indexregisterh"alften, Stack-relativ). Zu einem kleinen Teil existieren diese Erweiterungen aber auch schon beim Z80 als undokumentierte Befehle, die mit der Variante \tty{Z80UNDOC} zugeschaltet werden k"onnen. Eine Liste mit den zus"atzlichen Befehlen findet sich im Kapitel mit den prozessorspezifischen Hinweisen. %%----------- \begin{quote} ad) Z8601, Z8604, Z8608, Z8630, Z8631 \end{quote} Diese Prozessoren unterscheiden sich wieder nur in Speicherausbau und Peripherie, d.h. die Wahl hat auf den unterst"utzten Befehlssatz keinen Effekt. %%----------- \begin{quote} ae) 96C141, 93C141 \end{quote} Diese beiden Prozessoren repr"asentieren die beiden Varianten der Prozessorfamilie: TLCS-900 und TLCS-900L. Die Unterschiede dieser beiden Varianten werden in Abschnitt \ref{TLCS900Spec} genauer beleuchtet. %%----------- \begin{quote} af) 90C141 \end{quote} %%----------- \begin{quote} ag) 87C00, 87C20, 87C40, 87C70 \end{quote} Die Prozessoren der TLCS-870-Reihe haben zwar den identischen CPU-Kern, je nach Variante aber eine unterschiedliche Peripherieausstattung. Zum Teil liegen Register gleichen Namens auf unterschiedlichen Adressen. Die Datei STDDEF87.INC benutzt analog zur MCS-51-Familie die hier m"ogliche Unterscheidung, um automatisch den korrekten Symbolsatz bereitzustellen. %%----------- \begin{quote} ah) 47C00 $\rightarrow$ 470C00 $\rightarrow$ 470AC00 \end{quote} Diese drei Varianten der TLCS-47-Familie haben unterschiedlich gro"se RAM-und ROM-Adre"sbereiche, wodurch jeweils einige Befehle zur Bankumschaltung hinzukommen oder wegfallen. %%----------- \begin{quote} ai) 97C241 \end{quote} %%----------- \begin{quote} aj) 16C54 $\rightarrow$ 16C55 $\rightarrow$ 16C56 $\rightarrow$ 16C57 \end{quote} Diese Prozessoren unterscheiden sich durch den verf"ugbaren Adre"sraum im Programmspeicher, d.h. durch die Adresse, ab der der AS "Uberl"aufe anmeckert. %%----------- \begin{quote} ak) 16C64, 16C84 \end{quote} Analog zur MCS-51-Familie findet hier keine Unterscheidung im Codegenerator statt, die unterschiedlichen Nummern dienen lediglich der Einblendung der korrekten SFRs in STDDEF18.INC. %%----------- \begin{quote} al) 17C42 \end{quote} %%----------- \begin{quote} am) ST6210/ST6215 $\rightarrow$ ST6220/ST6225 \end{quote} Die einzige Unterscheidung, die AS zwischen den beiden Paaren vornimmt, ist der bei den ersten beiden kleinere Adre"sraum (2K anstelle 4K). Die Feinunterscheidung dient zur automatischen Unterscheidung in der Quelldatei, welche Hardware jeweils vorhanden ist (analog zum 8051/52/515). %%----------- \begin{quote} an) ST7 \end{quote} %%----------- \begin{quote} ao) ST9020, ST9030, ST9040, ST9050 \end{quote} Diese 4 Namen vetreten die vier ,,Unterfamilien'' der ST9-Familie, die sich durch eine unterschiedliche Ausstattung mit On-Chip-Peripherie auszeichen. Im Prozessorkern sind sie identisch, so da"s diese Unterscheidung wieder nur im Includefile mit den Peripherieadressen zum Zuge kommt. %%----------- \begin{quote} ap) 6804 \end{quote} %%----------- \begin{quote} aq) 32010 $\rightarrow$ 32015 \end{quote} Der TMS32010 besitzt nur 144 Byte internes RAM, weshalb AS Adressen im Datensegment auf eben diesen Bereich begrenzt. F"ur den 32015 gilt diese Beschr"ankung nicht, es kann der volle Bereich von 0--255 angesprochen werden. %%----------- \begin{quote} ar) 320C25 $\rightarrow$ 320C26 $\rightarrow$ 320C28 \end{quote} Diese Prozessoren unterscheiden sich nur leicht in der On-Chip-Peripherie sowie den Konfigurationsbefehlen. %%----------- \begin{quote} as) 320C30, 320C31 \end{quote} Der 320C31 ist eine etwas ,,abgespeckte'' Version mit dem gleichen Befehlssatz, jedoch weniger Peripherie. In STDDEF3X.INC wird diese Unterscheidung ausgenutzt. %%----------- \begin{quote} at) 320C203 $\rightarrow$ 320C50, 320C51, 320C53 \end{quote} Ersterer ist der generelle Repr"asentant f"ur die C20x-Signalprozessorfamilie, die eine Untermenge des C5x-Befehlssatzes implementieren. Die Unterscheidung zwischen den verschiedenen C5x-Prozessoren wird von AS momentan nicht ausgenutzt. %%----------- \begin{quote} au) TMS9900 \end{quote} %%----------- \begin{quote} \begin{tabbing} \hspace{0.7cm} \= \kill av) \> TMS70C00, TMS70C20, TMS70C40, \\ \> TMS70CT20, TMS70CT40, \\ \> TMS70C02, TMS70C42, TMS70C82, \\ \> TMS70C08, TMS70C48 \\ \end{tabbing} \end{quote} Alle Mitglieder dieser Familie haben den gleichen CPU-Kern, unterscheiden sich im Befehlssatz also nicht. Die Unterschiede finden sich nur in der Datei REG7000.INC, in der Speicherbereiche und Peripherieadressen definiert werden. Die in einer Zeile stehenden Typen besitzen jeweils gleiche Peripherie und gleiche interne RAM-Menge, unterscheiden sich also nur in der Menge eingebauten ROMs. %%----------- \begin{quote} aw) 370C010, 370C020, 370C030, 370C040 und 370C050 \end{quote} Analog zur MCS-51-Familie werden die unterschiedlichen Typen nur zur Unterscheidung der Peripherie in STDDEF37.INC genutzt, der Befehlssatz ist identisch. %%----------- \begin{quote} ax) MSP430 \end{quote} %%----------- \begin{quote} ay) SC/MP \end{quote} %%----------- \begin{quote} az) COP87L84 \end{quote} Dies ist das momentan einzige unterst"utzte Mitglied der COP8-Familie von National Semiconductor. Mir ist bekannt, da"s die Familie wesentlich gr"o"ser ist und auch Vertreter mit unterschiedlich gro"sem Befehlssatz existieren, die nach Bedarf hinzukommen werden. Es ist eben ein Anfang, und die Dokumentation von National ist ziemlich umfangreich... %%----------- \begin{quote} \begin{tabbing} \hspace{0.7cm} \= \kill ba) \> SC14400, SC14401, SC14402, SC14404, SC14405, \\ \> SC14420, SC14421, SC14422, SC14424 \\ \end{tabbing} \end{quote} Diese Gruppe von DECT-Controller unterscheidet sich in ihrem Befehlsumfang, da jeweils unterschiedliche B-Feld Datenformate unterst"utzt werden und deren Architektur im Laufe der Zeit optimiert wurde. %%----------- \begin{quote} bb) 7810 $\rightarrow$ 78C10 \end{quote} Die NMOS-Version besitzt keinen STOP-Modus; der entspechende Befehl sowie das ZCM-Register fehlen demzufolge. \bb{VORSICHT!} NMOS- und CMOS-Version differieren zum Teil in den Reset-Werten einiger Register! %%----------- \begin{quote} \begin{tabbing} \hspace{0.7cm} \= \kill bc) \> 75402, \\ \> 75004, 75006, 75008, \\ \> 75268, \\ \> 75304, 75306, 75308, 75312, 75316, \\ \> 75328, \\ \> 75104, 75106, 75108, 75112, 75116, \\ \> 75206, 75208, 75212, 75216, \\ \> 75512, 75516 \\ \end{tabbing} \end{quote} Dieses ,,F"ullhorn'' an Prozessoren unterscheidet sich innerhalb einer Gruppe nur durch die RAM- und ROM-Gr"o"se; die Gruppen untereinander unterscheiden sich einmal durch ihre on-chip-Peripherie und zum anderen durch die M"achtigkeit des Befehlssatzes. %%----------- \begin{quote} bd) 78070 \end{quote} Dies ist das einzige, mir momentan vertraute Mitglied der 78K0-Familie von NEC. Es gelten "ahnliche Aussagen wie zur COP8-Familie! %%----------- \begin{quote} be) 7720 $\rightarrow$ 7725 \end{quote} Der $\mu$PD7725 bietet im Vergleich zu seinem Vorg"anger gr"o"sere Adre"sr"aume und einige zus"atzliche Befehle. {\bf VORSICHT!} Die Prozessoren sind nicht zueinander bin"arkompatibel! %%----------- \begin{quote} bf) 77230 \end{quote} %%----------- \begin{quote} \begin{tabbing} bg) \= SYM53C810, SYM53C860, SYM53C815, SYM53C825, \\ \> SYM53C875, SYM53C895 \end{tabbing} \end{quote} Die einfacheren Mitglieder dieser Familie von SCSI-Prozessoren besitzen einige Befehlsvarianten nicht, au"serdem unterscheiden sie sich in ihrem Satz interner Register. %%----------- \begin{quote} bh) MB89190 \end{quote} Dieser Prozessortyp repr"asentiert die F$^{2}$MC8L-Serie von Fujitsu. Beim CPU-Befehl mu"s der Prozessortyp als einfache Konstante angegeben werden, eine Berechnung \`a la \begin{verbatim} CPU 68010+10 \end{verbatim} ist also nicht zul"assig. G"ultige Aufrufe sind z.B. \begin{verbatim} CPU 8051 \end{verbatim} oder \begin{verbatim} CPU 6800 \end{verbatim} Egal, welcher Prozessortyp gerade eingestellt ist, in der Integervariablen MOMCPU wird der momentane Status als Hexadezimalzahl abgelegt. F"ur den 68010 ist z.B. \tty{MOMCPU=\$68010}, f"ur den 80C48 \tty{MOMCPU=80C48H}. Da man Buchstaben au"ser A..F nicht als Hexziffer interpretieren kann, mu"s man sich diese bei der Hex-Darstellung des Prozessors wegdenken. F"ur den Z80 ist z.B. \tty{MOMCPU=80H}. \par Dieses Feature kann man vorteilhaft einsetzen, um je nach Prozessortyp unterschiedlichen Code zu erzeugen. Der 68000 z.B. kennt noch keinen Befehl f"ur den Unterprogrammr"ucksprung mit Stapelkorrektur. Mit der Variablen \tty{MOMCPU} kann man ein Makro definieren, das je nach Prozessortyp den richtigen Befehl benutzt oder ihn emuliert: \begin{verbatim} myrtd MACRO disp IF MOMCPU$<$68010 ; auf 68008 und MOVE.L (sp),disp(sp) ; 68000 emulieren LEA disp(sp),sp RTS ELSEIF RTD #disp ; ab 68010 direkt ENDIF ; benutzen ENDM CPU 68010 MYRTD 12 ; ergibt RTD #12 CPU 68000 MYRTD 12 ; ergibt MOVE.. / ; LEA.. / RTS \end{verbatim} Da nicht alle Prozessornamen nur aus Ziffern und Buchstaben zwischen A und F bestehen, wird zus"atzlich der volle Name in der String-Variablen \tty{MOMCPUNAME} abgelegt. \par Implizit schaltet der Assembler mit dem \tty{CPU}-Befehl das aktuelle Segment wieder auf Code zur"uck, da dies das einzige Segment ist, das alle Prozessoren definieren. \par Default f"ur den Prozessortyp ist \tty{68008}, sofern dieser "uber die gleichnamige Kommandozeilenoption nicht ver"andert wurde. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SUPMODE, FPU, PMMU} \ttindex{SUPMODE}\ttindex{FPU}\ttindex{PMMU} {\em\begin{tabbing} G"ultigkeit: \= 680x0, FPU auch 80x86, i960, SUPMODE auch TLCS-900, \\ \> SH7000, i960, 29K, XA, PowerPC, M*CORE und TMS9900 \end{tabbing}} Mit diesen drei Schaltern kann bestimmt werden, auf welche Teile des Befehlssatzes verzichtet werden soll, weil die daf"ur n"otigen Vorbedingungen im folgenden Codest"uck nicht gegeben sind. Als Parameter f"ur diese Befehle darf entweder \tty{ON} oder \tty{OFF} gegeben werden, der momentan gesetzte Zustand kann aus einer Variablen ausgelesen werden, die entweder TRUE oder FALSE ist. \par Die Befehle bedeuten im einzelnen folgendes: \begin{itemize} \item{\tty{SUPMODE}: erlaubt bzw. sperrt Befehle, f"ur deren Ausf"uhrung der Prozessor im Supervisorstatus sein mu"s. Die Statusvariable hei"st \tty{INSUPMODE}.} \item{\tty{FPU}: erlaubt bzw. sperrt die Befehle des numerischen Koprozessors 8087 bzw. 68881/68882. Die Statusvariable hei"st \tty{FPUAVAIL}.} \item{\tty{PMMU}: erlaubt bzw. sperrt die Befehle der Speicherverwaltungseinheit 68851 bzw. der im 68030 eingebauten MMU. \bb{ACHTUNG!} Die 68030-MMU erlaubt nur eine rel. kleine Untermenge der 68851-Befehle. Der Assembler kann hier keine Pr"ufung vornehmen! Die Statusvariable hei"st \tty{PMMUAVAIL}.} \end{itemize} Benutzung von auf diese Weise gesperrten Befehlen erzeugt bei \tty{SUPMODE} eine Warnung, bei \tty{PMMU} und \tty{FPU} eine echte Fehlermeldung. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FULLPMMU} \ttindex{FULLPMMU} {\em G"ultigkeit: 680x0} Motorola hat zwar ab dem 68030 die PMMU in den Prozessor integriert, diese aber nur mit einer Funktionsuntermenge der externen PMMU 68851 ausgestattet. AS sperrt bei aktiviertem PMMU-Befehlssatz (s.o.) deshalb alle fehlenden Befehle, wenn als Zielprozessor 68030 oder h"oher eingestellt wurde. Nun kann es aber sein, da"s in einem System mit 68030-Prozessor die interne MMU abgeschaltet wurde und der Prozessor mit einer externen 68851 betrieben wird. Mit \tty{FULLPMMU ON} kann man AS dann mitteilen, da"s der vollst"andige MMU-Befehlssatz zugelassen ist. Umgekehrt kann man, wenn man portablen Code erzeugen will, alle zus"atzlichen Befehle trotz 68020-Zielplattform mit \tty{FULLPMMU OFF} abschalten. Die Umschaltung darf beliebig oft erfolgen, die momentane Einstellung kann aus einem gleichnamigen Symbol ausgelesen werden. \bb{ACHTUNG!} Der \tty{CPU}-Befehl besetzt f"ur 680x0-Argumente implizit diese Einstellung vor! \tty{FULLPMMU} mu"s also auf jeden Fall nach dem \tty{CPU}-Befehl kommen! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PADDING} \ttindex{PADDING} {\em G"ultigkeit: 680x0, M*Core, XA, H8, SH7000, TMS9900, MSP430, ST7} Prozessoren der 680x0-Familie stehen ungeraden Adressen ziemlich kritisch gegen"uber: Befehle d"urfen nicht auf einer ungeraden Adresse beginnen, und Datenzugriffe sind mit ungeraden Adressen bis zum 68010 nur byteorientiert erlaubt. Die H8-Familie setzt bei Zugriffen auf ungerade Adressen das unterste Adre"sbit einfach ganz auf Null, die 500er ,,bedanken'' sich wiederum mit einer Exception... AS bem"uht sich daher, mit \tty{DC} oder \tty{DS} angelegte Datenstrukturen immer mit einer geraden Bytezahl abzulegen. Das bedeutet bei den Befehlen \tty{DS.B} und \tty{DC.B} aber unter Umst"anden, da"s ein F"ullbyte eingef"ugt werden mu"s. Dieses Verhalten kann man mit dem \tty{PADDING}-Befehl ein- und ausschalten. Als Argument ist analog zu den vorherigen Befehlen \tty{ON} oder \tty{OFF} erlaubt, und die augenblickliche Einstellung kann aus dem gleichnamigen Symbol ausgelesen werden. Defaultm"a"sig ist \tty{PADDING} nur f"ur die 680x0-Familie eingeschaltet, f"ur alle anderen werden erst nach Umschaltung Padding-Bytes eingef"ugt! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{MAXMODE} \ttindex{MAXMODE} {\em G"ultigkeit: TLCS-900, H8} Die Prozessoren der TLCS-900-Reihe k"onnen in 2 Betriebsarten arbeiten, dem Minimum-und Maximum-Modus. Je nach momentaner Betriebsart gelten f"ur den Betrieb und den Assembler etwas andere Eckwerte. Mit diesem Befehl und den Parametern \tty{ON} oder \tty{OFF} teilt man AS mit, da"s der folgende Code im Maximum- oder Minimum-Modus abl"auft. Die momentane Einstellung kann aus der Variablen \tty{INMAXMODE} ausgelesen werden. Voreinstellung ist \tty{OFF}, d.h. Minimum-Modus. \par Analog dazu teilt man im H8-Modus AS mit diesem Befehl mit, ob mit einem 64K- oder 16Mbyte-Adre"sraum gearbeitet wird. F"ur den einfachen 300er ist diese Einstellung immer \tty{OFF} und kann nicht ver"andert werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{EXTMODE und LWORDMODE} \ttindex{EXTMODE}\ttindex{LWORDMODE} {\em G"ultigkeit: Z380} Der Z380 kann in insgesamt 4 Betriebsarten arbeiten, die sich durch die Einstellung von 2 Flags ergeben: Das XM-Flag bestimmt, ob der Prozessor mit einem 64 Kbyte oder 4 Gbyte gro"sen Adre"sraum arbeiten soll und kann nur gesetzt werden (nach einem Reset steht es Z80-kompatibel auf 0). Demgegen"uber legt das LW-Flag fest, ob Wort-Befehle mit einer Wortl"ange von 16 oder 32 Bit arbeiten sollen. Die Stellung dieser beiden Flags beeinflu"st Wertebereichseinschr"ankungen von Konstanten oder Adressen, weshalb man AS "uber diese beiden Befehle deren Stellung mitteilen mu"s. Als Default nimmt AS an, da"s beide Flags auf 0 stehen, die momentane Einstellung (\tty{ON} oder \tty{OFF}) kann aus den vordefinierten Variablen \tty{INEXTMODE} bzw. \tty{INLWORDMODE} ausgelesen werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SRCMODE} \ttindex{SRCMODE} {\em G"ultigkeit: MCS-251} Intel hat den Befehlssatz der 8051er beim 80C251 deutlich erweitert, hatte aber leider nur noch einen einzigen freien Opcode f"ur diese Befehle frei. Damit der Prozessor nicht auf alle Ewigkeit durch einen Pr"afix behindert bleibt, hat Intel zwei Betriebsarten vorgesehen: Den Bin"ar- und den Quellmodus. Im Bin"armodus ist der Prozessor voll 8051-kompatibel, alle erweiterten Befehle ben"otigen den noch freien Opcode als Pr"afix. Im Quellmodus tauschen diese neuen Befehle ihre Position in der Code-Tabelle mit den entsprechenden 8051-Instruktionen, welche dann wiederum mit einem Pr"afix versehen werden m"ussen. Damit AS wei"s, wann er Pr"afixe setzen mu"s und wann nicht, mu"s man ihm mit diesem Befehl mitteilen, ob der Prozessor im Quellmodus (\tty{ON}) oder Bin"armodus (\tty{OFF}) betrieben wird. Die momentane Einstellung kann man aus der Variablen \tty{INSRCMODE} auslesen. Der Default ist \tty{OFF}. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BIGENDIAN} \ttindex{BIGENDIAN} {\em G"ultigkeit: MCS-51/251, PowerPC} Bei den Prozessoren der 8051-Serie ist Intel seinen eigenen Prinzipien untreu geworden: Der Prozessor verwendet entgegen jeglicher Tradition eine Big-Endian-Orientierung von Mehrbytewerten! W"ahrend dies bei den MCS-51-Prozessoren noch nicht gro"sartig auffiel, da der Prozessor ohnehin nur 8-bittig auf Speicherzellen zugreifen konnte, man sich die Byte-Anordnung bei eigenen Datenstrukturen also aussuchen konnte, ist dies beim MCS-251 nicht mehr so, er kann auch ganze (Lang-)Worte aus dem Speicher lesen und erwartet dabei das MSB zuerst. Da dies nicht der bisherigen Arbeitsweise von AS bei der Konstantenablage entspricht, kann man nun mit diesem Befehl umschalten, ob die Befehle \tty{DB, DW, DD, DQ} und \tty{DT} mit Big- oder Little-Endian-Orientierung arbeiten sollen. Mit \tty{BIGENDIAN OFF} (Voreinstellung) wird wie bei "alteren AS-Versionen zuerst das niederwertigste Byte abgelegt, mit \tty{BIGENDIAN ON} wird die MCS-251-kompatible Variante benutzt. Nat"urlich kann man diese Einstellung beliebig oft im Code "andern; die momentane Einstellung kann aus dem gleichnamigen Symbol ausgelesen werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{WRAPMODE} \ttindex{WRAPMODE} {\em G"ultigkeit: Atmel AVR} Ist dieser Schalter auf {\tt ON} gesetzt, so veranla"st man AS dazu, anzunehmen, der Programmz"ahler des Prozessors habe nicht die volle, durch die Architektur gegebene L"ange von 16 Bits, sondern nur eine L"ange, die es gerade eben erlaubt, das interne ROM zu adressieren. Im Falle des AT90S8515 sind dies z.B. 12 Bit, entsprechend 4 KWorten oder 8 KBytes. Damit werden relative Spr"unge vom Anfang des ROMs zum Ende und umgekehrt m"oglich, die bei strenger Arithmetik einen out-of-branch ergeben w"urden, hier jedoch funktionieren, weil die "Ubertragsbits bei der Zieladressenberechnung 'unter den Tisch' fallen. Vergewissern Sie sich genau, ob die von Ihnen eingesetzte Prozessorvariante so arbeitet, bevor Sie diese Option einschalten! Im Falle des oben erw"ahnten AT90S8515 ist diese Option sogar zwingend n"otig, um überhaupt quer durch den ganzen Adre"sraum springen zu k"onnen... Defaultm"a"sig steht dieser Schalter auf {\tt OFF}, der momentane Stand l"a"st sich aus einem gleichnamigen Symbol auslesen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SEGMENT} \ttindex{SEGMENT} {\em G"ultigkeit: alle Prozessoren} Bestimmte Mikrokontroller und Signalprozessoren kennen mehrere Adre"sbereiche, die nicht miteinander mischbar sind und jeweils auch verschiedene Befehle zur Ansprache ben"otigen. Um auch diese verwalten zu k"onnen, stellt der Assembler mehrere Programmz"ahler zur Verf"ugung, zwischen denen mit dem \tty{SEGMENT}-Befehl hin-und hergeschaltet werden kann. Dies erlaubt es, sowohl in mit \tty{INCLUDE} eingebundenen Unterprogrammen als auch im Hauptprogramm ben"otigte Daten an der Stelle zu definieren, an denen sie benutzt werden. Im einzelnen werden folgende Segmente mit folgenden Namen verwaltet: \begin{itemize} \item{\tty{CODE}: Programcode;} \item{\tty{DATA}: direkt adressierbare Daten (dazu rechnen auch SFRs);} \item{\tty{XDATA}: im extern angeschlossenen RAM liegende Daten oder X-Adre"sraum beim DSP56xxx oder ROM-Daten beim $\mu$PD772x;} \item{\tty{YDATA}: Y-Adre"sraum beim DSP56xxx;} \item{\tty{IDATA}: indirekt adressierbare (interne) Daten;} \item{\tty{BITDATA}: der Teil des 8051-internen RAMs, der bitweise adressierbar ist;} \item{\tty{IO}: I/O-Adre"sbereich;} \item{\tty{REG}: Registerbank des ST9;} \item{\tty{ROMDATA}: Konstanten-ROM der NEC-Signalprozessoren.} \end{itemize} Zu Adre"sbereich und Initialwerten der Segmente siehe Abschnitt \ref{SectORG}. (\tty{ORG}). Je nach Prozessorfamilie sind auch nicht alle Segmenttypen erlaubt. \par Das Bitsegment wird so verwaltet, als ob es ein Bytesegment w"are, d.h. die Adressen inkrementieren um 1 pro Bit. \par Labels, die in einem Segment eines bestimmten Typs definiert werden, erhalten diesen Typ als Attribut. Damit hat der Assembler eine begrenzte Pr"ufm"oglichkeit, ob mit den falschen Befehlen auf Symbole in einem Segment zugegriffen wird. In solchen F"allen wird der Assembler eine Warnung ausgeben. \par Beispiel: \begin{verbatim} CPU 8051 ; MCS-51-Code SEGMENT code ; Testcodeblock SETB flag ; keine Warnung SETB var ; Warnung : falsches Segment SEGMENT data var DB ? SEGMENT bitdata flag DB ? \end{verbatim} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PHASE und DEPHASE} \ttindex{PHASE}\ttindex{DEPHASE} {\em G"ultigkeit: alle Prozessoren} In manchen Anwendungen (speziell Z80-Systeme) mu"s Code vor der Benutzung in einen anderen Adre"sbereich verschoben werden. Da der Assembler davon aber nichts wei"s, w"urde er alle Labels in dem zu verschiebenden Teil auf die Ladeadressen ausrichten. Der Programmierer m"u"ste Spr"unge innerhalb dieses Bereiches entweder lageunabh"angig kodieren oder die Verschiebung bei jedem Symbol ,,zu Fu"s'' addieren. Ersteres ist bei manchen Prozessoren gar nicht m"oglich, letzteres sehr fehleranf"allig. \par Mit dem Befehlen \tty{PHASE} und \tty{DEPHASE} ist es m"oglich, dem Assembler mitzuteilen, auf welcher Adresse der Code im Zielsystem effektiv ablaufen wird: \begin{verbatim} PHASE \end{verbatim} informiert den Assembler davon, da"s der folgende Code auf der spezifizierten Adresse ablaufen soll. Der Assembler berechnet daraufhin die Differenz zum echten Programmz"ahler und addiert diese Differenz bei folgenden Operationen dazu: \begin{itemize} \item{Adre"sangabe im Listing} \item{Ablage von Labelwerten} \item{Programmz"ahlerreferenzen in relativen Spr"ungen und Adre"sausdr"ucken} \item{Abfrage des Programmz"ahlers mit den Symbolen \verb!*! bzw. \verb!$!} \end{itemize} Diese ,,Verschiebung'' wird mit dem Befehl \begin{verbatim} DEPHASE \end{verbatim} wieder aufgehoben. \par Obwohl dieses Befehlspaar vornehmlich in Codesegmenten Sinn macht, verwaltet der Assembler f"ur alle definierten Segmente Phasenwerte. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SAVE und RESTORE} \ttindex{SAVE}\ttindex{RESTORE} {\em G"ultigkeit: alle Prozessoren} Mit dem Befehl \tty{SAVE} legt der Assembler den Inhalt folgender Variablen auf einen internen Stapel: \begin{itemize} \item{momentan gew"ahlter Prozessortyp (mit \tty{CPU} gesetzt);} \item{momentan aktiver Speicherbereich (mit \tty{SEGMENT} gesetzt);} \item{Flag, ob Listing ein- oder ausgeschaltet ist (mit \tty{LISTING} gesetzt);} \item{Flag, ob Expansionen folgender Makos im Listing ausgegeben werden sollen (mit \tty{MACEXP} gesetzt).} \item{momentan aktive Zeichen"ubersetzungstabelle (mit \tty{CODEPAGE} gesetzt).} \end{itemize} Mit dem Gegenst"uck \tty{RESTORE} wird entsprechend der zuletzt gesicherte Zustand von diesem Stapel wieder heruntergeladen. Diese beiden Befehle sind in erster Linie f"ur Includefiles definiert worden, um in diesen Dateien die obigen Variablen beliebig ver"andern zu k"onnen, ohne ihren originalen Inhalt zu verlieren. So kann es z.B. sinnvoll sein, in Includefiles mit eigenen, ausgetesteten Unterprogrammen die Listingerzeugung auszuschalten: \begin{verbatim} SAVE ; alten Zustand retten LISTING OFF ; Papier sparen .. ; der eigentliche Code RESTORE ; wiederherstellen \end{verbatim} Gegen"uber einem einfachen \tty{LISTING OFF..ON}-P"archen wird hier auch dann der korrekte Zustand wieder hergestellt, wenn die Listingerzeugung bereits vorher ausgeschaltet war. \par Der Assembler "uberpr"uft, ob die Zahl von \tty{SAVE}-und \tty{RESTORE}-Befehlen "ubereinstimmt und liefert in folgenden F"allen Fehlermeldungen: \begin{itemize} \item{\tty{RESTORE} und der interne Stapel ist leer;} \item{nach Ende eines Passes ist der Stapel nicht leer.} \end{itemize} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ASSUME} \ttindex{ASSUME} {\em G"ultigkeit: diverse} Mit diesem Befehl kann man AS den aktuellen Stand bestimmter Register mitteilen, deren Inhalt sich nicht mit einem einfachen \tty{ON} oder \tty{OFF} beschreiben l"a"st. Typischerweise sind dies Register, die die Adressierungseinheiten beeinflussen und deren Werte AS wissen mu"s, um korrekte Adressierungen zu erzeugen. Wichtig ist, da"s man AS mit ASSUME diese Werte nur mitteilt, es wird {\em kein} Maschinencode erzeugt, der diese Werte in die entsprechenden Register l"adt! \subsubsection{6809} Im Gegensatz zu seinen ,,Vorg"angern'' wie 6800 und 6502 kann beim 6809 die Lage der direct page, d.h. des Adressbereiches, der mit ein Byte langen Adressen erreichbar ist, frei bestimmt werden. Dazu dient das sog. ,,Direct Page Register'' (\tty{DPR}), das die Seitennummer festlegt. Ihm mu"s man mittels \tty{ASSUME} einen passenden Wert zuweisen, wenn man einen anderen Wert als die Vorgabe von 0 in DPR schreibt, sonst werden Adressen falscher L"ange erzeugt... \subsubsection{68HC16} Um mit seinen nur 16 Bit breiten Adre"soperanden einen 1 Mbyte gro"sen Adre"sraum ansprechen zu k"onnen, bedient sich der 68HC16 einer Reihe von Bank-Registern, die die fehlenden oberen vier Adre"sbits nachliefern. Davon ist das \tty{EK}-Register f"ur absolute Datenzugriffe (nicht Spr"unge!) zust"andig. AS "uberpr"uft bei jeder absoluten Adressierung, ob die oberen vier Bits der Adresse mit dem "uber \tty{ASSUME} spezifizierten Wert "ubereinstimmen. Differieren die Werte, gibt AS eine Warnung aus. Der Vorgabewert f"ur \tty{EK} ist 0. \subsubsection{H8/500} Im Maximum-Modus wird der erweiterte Adre"sraum dieser Prozessorreihe durch eine Reihe von Bank-Registern adressiert. Diese tragen die Namen DP (Register 0..3, absolute Adressen), EP (Register 4/5) und TP (Stack). Den momentanen Wert von DP ben"otigt AS, um zu "uberpr"ufen, ob absolute Adressen in der momentan adressierbaren Bank liegen; die beiden anderen Register werden nur f"ur indirekte Adressierungen benutzt und entziehen sich daher der Kontrolle; ob man ihre Werte angibt oder nicht, ist daher Geschmackssache. Wichtig ist dagegen wieder das BR-Register, das angibt, auf welchen 256-Byte-Bereich mit kurzen Adressen zugegriffen werden kann. Allen Registern ist gemeinsam, da"s AS {\em keine} Initialwerte f"ur sie annimmt, da sie nach einem Prozessor-Reset undefiniert sind; wer absolut adressieren will, mu"s daher auf jeden Fall DR und DP belegen! \subsubsection{MELPS740} Die Mikrokontroller dieser Reihe kennen f"ur den \tty{JSR}-Befehl eine besondere Adressierungsart ,,special page'', mit deren Hilfe man Spr"unge in die oberste Seite des internen ROMs k"urzer kodieren kann. Diese ist nat"urlich vom jeweiligen Chip abh"angig, und es gibt mehr Chips, als es mit dem \tty{CPU}-Befehl sinnvoll w"are, zu kodieren...also mu"s \tty{ASSUME} herhalten, um die Lage dieser Seite vorzugeben, z.B. \begin{verbatim} ASSUME SP:$1f , \end{verbatim} falls das interne ROM 8K gro"s ist. \subsubsection{MELPS7700/65816} Diese Prozessoren beinhalten eine Reihe von Registern, deren Inhalt AS kennen mu"s, um den korrekten Code zu erzeugen. Es handelt sich um folgende Register: \begin{center}\begin{tabular}{|l|l|l|l|} \hline Name & Bedeutung & Wertebereich & Default\\ \hline \hline DT & Datenbank & 0-\$ff & 0 \\ PG & Code-Bank & 0-\$ff & 0 \\ DPR & direkt adr. Seite & 0-\$ffff & 0 \\ X & Indexregisterbreite & 0 oder 1 & 0 \\ M & Akkumulatorbreite & 0 oder 1 & 0 \\ \hline \end{tabular}\end{center} \par Um mich nicht in endlose Wiederholungen zu ergehen, verweise ich f"ur die Benutzung dieser Werte auf Kapitel \ref{MELPS7700Spec}. Die Handhabung erfolgt ansonsten genauso wie beim 8086, d.h. es k"onnen auch hier mehrere Werte auf einmal gesetzt werden und es wird \bb{kein} Code erzeugt, der die Register mit den Werten besetzt. Dies bleibt wieder einzig und allein dem Programmierer "uberlassen! \subsubsection{MCS-196/296} Alle Prozessoren der MCS-96-Familie besitzen ab dem 80196 ein Register \tty{WSR}, mit dessen Hilfe Speicherbereiche aus dem erweiterten internen RAM oder dem SFR-Bereich in Bereiche des Registerfiles eingeblendet werden und so mit kurzen Adressen angesprochen werden k"onnen. Teilt man AS mit Hilfe des \tty{ASSUME}-Befehls mit, welchen Wert das WSR-Register hat, so stellt er bei absoluten Adressen automatisch fest, ob sie durch das Windowing mit 1-Byte-Adressen erreicht werden k"onnen; umgekehrt werden auch f"ur durch das Windowing "uberdeckte Register automatisch lange Adressen erzeugt. Der 80296 besitzt ein zus"atzliches, zweites Register \tty{WSR1}, um zwei unterschiedliche Speicherbereiche gleichzeitig in das Registerfile einblenden zu k"onnen. Sollte es m"oglich sein, eine Speicherzelle "uber beide Bereiche zu adressieren, so w"ahlt AS immer den Weg "uber \tty{WSR}! \subsubsection{8086} Der 8086 kann Daten aus allen Segmenten in einem Befehl adressieren, ben"otigt jedoch sog. ,,Segment-Pr"afixe'', wenn ein anderes Segmentregister als DS verwendet werden soll. Zus"atzlich kann es sein, da"s das DS-Register auf ein anderes Segment verstellt ist, um z.B. "uber l"angere Strecken nur Daten im Codesegment zu adressieren. Da AS aber keine Sinnanalyse des Codes vornimmt, mu"s ihm "uber diesen Befehl mitgeteilt werden, auf welche Segmente die Segmentregister momentan zeigen, z.B. \begin{verbatim} ASSUME CS:CODE, DS:DATA . \end{verbatim} Allen vier Segmenten des 8086 (SS,DS,CS,ES) k"onnen auf diese Weise Annahmen zugewiesen werden. Dieser Befehl erzeugt jedoch \bb{keinen} Code, um die Werte auch wirklich in die Segmentregister zu laden, dies mu"s vom Programm getan werden. \par Die Benutzung diese Befehls hat zum einen die Folge, da"s AS bei sporadischen Zugriffen ins Codesegment automatisch Pr"afixe voranstellen kann, andererseits da"s man AS mitteilen kann, da"s das DS-Register verstellt wurde und man sich im folgenden explizite \tty{CS:}-Anweisungen sparen kann. \par G"ultige Argumente hinter dem Doppelpunkt sind \tty{CODE, DATA} und \tty{NOTHING}. Letzterer Wert dient dazu, AS mitzuteilen, da"s das Segmentregister keinen f"ur AS verwendbaren Wert enth"alt. Vorinitialisiert sind folgende \tty{ASSUME}s : \begin{verbatim} CS:CODE, DS:DATA, ES:NOTHING, SS:NOTHING \end{verbatim} \subsubsection{XA} Die XA-Familie besitzt einen Datenadre"sraum von 16 Mbyte, ein Proze"s kann jedoch nur immer innerhalb einer 64K-Seite adressieren, die durch das DS-Register vorgegeben wird. AS mu"s man den momentanen Wert dieses Registers vorgeben, damit er Zugriffe auf absolute Adressen "uberpr"ufen kann. \subsubsection{29K} Die Prozessoren der 29K-Familie besitzen ein Register \tty{RBP}, mit dessen Hilfe B"anke von 16 Registern vor der Benutzung im User-Modus gesch"utzt werden k"onnen. Dazu kann man ein entsprechendes Bit in diesem Register setzen. Mit \tty{ASSUME} kann man AS nun mitteilen, welchen Wert RBP gerade hat. Auf diese Weise kann AS warnen, falls versucht wird, im User-Modus auf gesch"utzte Register zuzugreifen. \subsubsection{80C166/167} Obwohl keines der Register im 80C166/167 breiter als 16 Bit ist, besitzt dieser Prozessor 18/24 Adre"sleitungen, kann also bis zu 256 Kbyte/16 Mbyte adressieren. Um diesen Widerspruch unter einen Hut zu bekommen, verwendet er nicht die von Intel her bekannte (...und ber"uchtigte) Segmentierung oder hat unflexible Bankregister...nein, er macht Paging! Dazu wird der ,,logische'' Adre"sraum von 64 Kbyte in 4 Seiten zu 16 Kbyte eingeteilt, und f"ur jede Seite existiert ein Seitenregister (bezeichnet als \tty{DPP0...DPP3}), das bestimmt, welche der physikalischen 16/1024 Seiten dort eingeblendet wird. AS versucht nun, den Adre"sraum grunds"atzlich mit 256 Kbyte/16 Mbyte aus der Sicht des Programmierers zu verwalten, d.h. bei absoluten Zugriffen ermittelt AS die physikalische Seite und schaut in der mit \tty{ASSUME} eingestellten Seitenverteilung nach, wie die Bits 14 und 15 der logischen Adresse gesetzt werden m"ussen. Pa"st kein Seitenregister, so wird eine Warnung ausgegeben. Defaultm"a"sig nimmt AS an, da"s die vier Register linear die ersten 64 Kbyte abbilden, etwa in der folgenden Form: \begin{verbatim} ASSUME DPP0:0,DPP1:1,DPP2:2,DPP3:3 \end{verbatim} Der 80C167 kennt noch einige Befehle, die die Seitenregister in ihrer Funktion "ubersteuern k"onnen. Wie diese Befehle die Adre"sgenerierung beeinflussen, ist im Kapitel mit den prozessorspezifischen Hinweisen beschrieben. \subsubsection{TLCS-47} Der von der Architektur her vorgegebene Datenadre"sraum dieser Prozessoren (egal ob man direkt oder "uber das HL-Register adressiert) betr"agt lediglich 256 Nibbles. Da die ,,besseren'' Familienmitglieder aber bis zu 1024 Nibbles RAM on chip haben, war Toshiba gezwungen, einen Bankingmechanismus "uber das DMB-Register einzuf"uhren. AS verwaltet das Datensegment als einen durchgehenden Adre"sraum und pr"uft bei jeder direkten Adressierung, ob die Adresse in der momentan aktiven Bank liegt. Die von AS momentan angenommene Bank kann mittels \begin{verbatim} ASSUME DMB:<0..3> \end{verbatim} festgelegt werden. Der Default ist 0. \subsubsection{ST6} \label{ST6Assume} Die Mikrokontroller der ST62-Reihe sind in der Lage, einen Teil (64 Byte) des Codebereiches in den Datenbereich einzublenden, z.B. um Konstanten aus dem ROM zu laden. Dies bedeutet aber auch, da"s zu einem Zeitpunkt immer nur ein Teil des ROMs adressiert werden kann. Welcher Teil dies ist, wird durch ein bestimmtes Register bestimmt. Dem Inhalt dieses Registers kann AS zwar nicht direkt kontrollieren, man kann ihm aber mit diesem Befehl mitteilen, wenn man dem Register einen neuen Wert zugewiesen hat. AS kann dann pr"ufen und ggfs. warnen, falls auf Adressen im Codesegment zugegriffen wird, die nicht im ,,angek"undigten'' Fenster liegt. Hat die Variable \tty{VARI} z.B. den Wert 456h, so setzt \begin{verbatim} ASSUME ROMBASE:VARI>>6 \end{verbatim} die AS-interne Variable auf 11h, und ein Zugriff auf \tty{VARI} erzeugt einen Zugriff auf die Adresse 56h im Datensegment. Anstelle eines Symbols kann auch schlicht \tty{NOTHING} angegeben werden, z.B. wenn das Bank-Register tempor"ar als Speicherzelle benutzt wird. Dieser Wert ist auch die Voreinstellung. \subsubsection{ST9} Die ST9-Familie verwendet zur Adressierung von Code- und Datenbereich exakt die gleichen Befehle. Welcher Adre"sraum dabei jeweils angesprochen wird, h"angt vom Stand des DP-Flags im Flag-Register ab. Damit AS bei absoluten Zugriffen "uberpr"ufen kann, ob man mit Symbolen aus dem korrekten Adre"sraum arbeitet (das funktioniert nat"urlich {\em nur} bei absoluten Zugriffen!), mu"s man ihm per \tty{ASSUME} mitteilen, ob das DP-Flag momentan auf 0 (Code) oder 1 (Daten) steht. Der Initialwert dieser Annahme ist 0. \subsubsection{$\mu$PD78(C)10} Diese Prozessoren besitzen ein Register (V), mit dessen Hilfe die ,,Zeropage'', d.h. die Lage der mit nur einem Byte adressierbaren Speicherzellen sich in Seitengrenzen im Speicher frei verschieben l"a"st. Da man aber aus Bequemlichkeitsgr"unden nicht mit Ausdr"ucken wie \begin{verbatim} inrw Lo(Zaehler) \end{verbatim} arbeiten will, "ubernimmt AS diese Arbeit, allerdings nur unter der Voraussetzung, da"s man ihm "uber einen \tty{ASSUME}-Befehl den Inhalt des V-Registers mitteilt. Wird ein Befehl mit Kurzadressierung benutzt, so wird "uberpr"uft, ob die obere H"alfte des Adre"sausdrucks mit dem angenommenen Inhalt "ubereinstimmt. Stimmt sie nicht, so erfolgt eine Warnung. \subsubsection{320C3x} Da alle Instruktionsworte dieser Prozessorfamilie nur 32 Bit lang sind, und von diesen 32 Bit nur 16 Bit f"ur absolute Adressen vorgesehen wurden, m"ussen die fehlenden oberen 8 Bit aus dem DP-Register erg"anzt werden. Bei Adressierungen kann man aber trotzdem die volle 24-Bit-Adresse angeben, AS pr"uft dann, ob die oberen 8 Bit mit dem angenommenen Inhalt von DP "ubereinstimmen. Gegen"uber dem \tty{LDP}-Befehl weicht \tty{ASSUME} darin ab, da"s man hier nicht eine beliebige Adresse aus der Speicherbank angeben kann, das Herausziehen der oberen Bits mu"s man also ,,zu Fu"s'' machen, z.B. so: \begin{verbatim} ldp @adr assume dp:adr>>16 . . . ldi @adr,r2 \end{verbatim} \subsubsection{75K0} Da selbst mit Hilfe von Doppelregistern (8 Bit) nicht der komplette Adre"sraum von 12 Bit zu erreichen ist, mu"ste NEC (wie andere auch...) auf Banking zur"uckgreifen: Die oberen 4 Adre"sbits werden aus dem \tty{MBS}-Register geholt (welchem demzufolge mit \tty{ASSUME} Werte zwischen 0 und 15 zugeordnet werden k"onnen), das aber nur beachtet wird, falls das \tty{MBE}-Flag auf 1 gesetzt wurde. Steht es (wie die Vorgabe ist) auf 0, so kann man die obersten und untersten 128 Nibbles des Adre"sraumes ohne Bankumschaltung erreichen. Da der 75402 weder \tty{MBE}-Flag noch \tty{MBS}-Register kennt, ist f"ur ihn der \tty{ASSUME}-Befehl nicht definiert; Die Initialwerte von \tty{MBE} und \tty{MBS} lassen sich daher nicht "andern. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{EMULATED} \ttindex{EMULATED} {\em G"ultigkeit: 29K} AMD hat die Ausnahmebehandlung f"ur undefinierte Befehle bei der 29000-Serie so definiert, da"s f"ur jeden einzelnen Befehl ein Exceptionvektor zur Verf"ugung steht. Dies legt es nahe, durch gezielte Software-Emulationen den Befehlssatz eines kleineren Mitgliedes dieser Familie zu erweitern. Damit nun aber AS diese zus"atzlichen Befehle nicht als Fehler anmeckert, erlaubt es der \tty{EMULATED}-Befehl, AS mitzuteilen, da"s bestimmte Befehle doch erlaubt sind. Die Pr"ufung, ob der momentan gesetzte Prozessor diesen Befehl beherrscht, wird dann "ubergangen. Hat man z.B. f"ur einen Prozessor ohne Gleitkommaeinheit ein Modul geschrieben, das aber nur mit 32-Bit-IEEE-Zahlen umgehen kann, so schreibt man \begin{verbatim} EMULATED FADD,FSUB,FMUL,FDIV EMULATED FEQ,FGE,FGT,SQRT,CLASS \end{verbatim} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BRANCHEXT} \ttindex{BRANCHEXT} {\em G"ultigkeit: XA} {\tt BRANCHEXT} mit \tty{ON} oder \tty{OFF} als Argument legt fest, ob AS kurze, nur mit einem 8-Bit-Displacement verf"ugbare Spr"unge automatisch ,,verl"angern'' soll, indem z.B. aus einem einfachen \begin{verbatim} bne target \end{verbatim} automatisch eine l"angere Sequenz mit gleicher Funktion wird, falls das Sprungziel zu weit von momentanen Programmz"ahler entfernt ist. F"ur {\tt bne} w"are dies z.B. die Sequenz \begin{verbatim} beq skip jmp target skip: \end{verbatim} Falls f"ur eine Anweisung aber kein passendes ,,Gegenteil'' existiert, kann die Sequenz auch l"anger werden, z.B. f"ur {\tt jbc}: \begin{verbatim} jbc dobr bra skip dobr: jmp target skip: \end{verbatim} Durch dieses Feature gibt es bei Spr"ungen keine eineindeutige Zuordnung von Maschinen- und Assemblercode mehr, und bei Vorw"artsreferenzen handelt man sich m"oglicherweise zus"atzliche Passes ein. Man sollte dieses Feature daher mit Vorsicht einsetzen! %%--------------------------------------------------------------------------- \section{Datendefinitionen} Die hier beschriebenen Befehle "uberschneiden sich teilweise in ihrer Funktionalit"at, jedoch definiert jede Prozessorfamilie andere Namen f"ur die gleiche Funktion. Um mit den Standardassemblern konform zu bleiben, wurde diese Form der Implementierung gew"ahlt. Sofern nicht ausdr"ucklich anders erw"ahnt, kann bei allen Befehlen zur Datenablage (nicht bei denen zur Speicherreservierung!) eine beliebige Zahl von Parametern angegeben werden, die der Reihe nach abgearbeitet werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DC[.size]} \ttindex{DC} {\em G"ultigkeit: 680x0, M*Core, 68xx, H8, SH7000, DSP56xxx, XA, ST7} Dieser Befehl legt eine oder mehrere Konstanten des beim durch das Attribut bestimmten Typs im Speicher ab. Die Attribute entsprechen den in Abschnitt \ref{AttrTypes} definierten, zus"atzlich ist f"ur Byte-Konstanten die M"oglichkeit vorhanden, Stringausdr"ucke im Speicher abzulegen, wie z.B. \begin{verbatim} String dc.b "Hello world!\0" \end{verbatim} Die Parameterzahl darf zwischen 1 und 20 liegen, zus"atzlich darf jedem Parameter ein in eckigen Klammern eingeschlossener Wiederholungsfaktor vorausgehen, z.B. kann man mit \begin{verbatim} dc.b [(*+255)&$ffffff00-*]0 \end{verbatim} den Bereich bis zur n"achsten Seitengrenze mit Nullen f"ullen. \bb{Vorsicht!} Mit dieser Funktion kann man sehr leicht die Grenze von 1 Kbyte erzeugten Codes pro Zeile Quellcode "uberschreiten! \par Sollte die Byte-Summe ungerade sein, so kann vom Assembler automatisch ein weiteres Byte angef"ugt werden, um die Wortausrichtung von Daten zu erhalten. Dieses Verhalten kann mit dem \tty{PADDING}-Befehl ein- und ausgeschaltet werden. \par Mit diesem Befehl abgelegte Dezimalgleitkommazahlen (\tty{DC.P} ...) k"onnen zwar den ganzen Bereich der extended precision "uberstreichen, zu beachten ist dabei allerdings, da"s die von Motorola verf"ugbaren Koprozessoren 68881/68882 beim Einlesen solcher Konstanten die Tausenderstelle des Exponenten ignorieren! \par Default-Attribut ist \tty{W}, also 16-Bit-Integerzahlen. \par Beim DSP56xxx ist der Datentyp auf Integerzahlen festgelegt (ein Attribut ist deshalb weder n"otig noch erlaubt), die im Bereich -8M..16M-1 liegen d"urfen. Stringkonstanten sind ebenfalls erlaubt, wobei jeweils drei Zeichen in ein Wort gepackt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DS[.size]} \ttindex{DS} {\em G"ultigkeit: 680x0, M*Core, 68xx, H8, SH7x00, DSP56xxx, XA, ST7} Mit diesem Befehl l"a"st sich zum einen Speicherplatz f"ur die angegebene Zahl im Attribut beschriebener Zahlen reservieren. So reserviert \begin{verbatim} DS.B 20 \end{verbatim} z.B. 20 Bytes Speicher, \begin{verbatim} DS.X 20 \end{verbatim} aber 240 Byte ! \par Die andere Bedeutung ist die Ausrichtung des Programmz"ahlers, die mit der Wertangabe 0 erreicht wird. So wird mit \begin{verbatim} DS.W 0 \end{verbatim} der Programmz"ahler auf die n"achste gerade Adresse aufgerundet, mit \begin{verbatim} DS.D 0 \end{verbatim} dagegen auf die n"achste Langwortgrenze. Eventuell dabei freibleibende Speicherzellen sind nicht etwa mit Nullen oder NOPs gef"ullt, sondern undefiniert. \par Vorgabe f"ur die Operandengr"o"se ist --- wie "ublich --- W, also 16 Bit. \par Beim 56xxx ist die Operandengr"o"se auf Worte (a 24 Bit) festgelegt, Attribute gibt es deswegen wie bei \tty{DC} auch hier nicht. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DB,DW,DD,DQ \& DT} \ttindex{DB}\ttindex{DW}\ttindex{DD}\ttindex{DQ}\ttindex{DT} {\em\begin{tabbing} G"ultigkeit: \= Intel, Zilog, Toshiba, NEC, TMS370, Siemens, AMD, M16(C),\\ \> MELPS7700/65816, National, ST9, TMS7000, $\mu$PD77230, \\ \> Fairchild \end{tabbing}} Diese Befehle stellen sozusagen das Intel-Gegenst"uck zu \tty{DS} und \tty{DC} dar, und wie nicht anders zu erwarten, ist die Logik etwas anders: \par Zum einen wird die Kennung der Operandengr"o"se in das Mnemonic verlegt: \begin{itemize} \item{\tty{DB}: Byte oder ASCII-String wie bei \tty{DC.B}} \item{\tty{DW}: 16-Bit-Integer} \item{\tty{DD}: 32-Bit-Integer oder single precision} \item{\tty{DQ}: double precision (64 Bit)} \item{\tty{DT}: extended precision (80 Bit)} \end{itemize} Zum anderen erfolgt die Unterscheidung, ob Konstantendefinition oder Speicherreservierung, im Operanden. Eine Reservierung von Speicher wird durch ein \tty{?} gekennzeichnet: \begin{verbatim} db ? ; reserviert ein Byte dw ?,? ; reserviert Speicher fuer 2 Worte (=4 Byte) dd -1 ; legt die Konstante -1 (FFFFFFFFH) ab ! \end{verbatim} Speicherreservierung und Konstantendefinition d"urfen \bb{nicht in einer Anweisung} gemischt werden: \begin{verbatim} db "Hallo",? ; -->Fehlermeldung \end{verbatim} \ttindex{DUP} Zus"atzlich ist noch der \tty{DUP}-Operator erlaubt, der die mehrfache Ablage von Konstantenfolgen oder die Reservierung ganzer Speicherbl"ocke erlaubt: \begin{verbatim} db 3 dup (1,2) ; --> 1 2 1 2 1 2 dw 20 dup (?) ; reserviert 40 Byte Speicher. \end{verbatim} Wie man sehen kann, mu"s das \tty{DUP}-Argument geklammert werden, darf daf"ur aber auch wieder aus mehreren Teilen bestehen, die selber auch wieder \tty{DUP}s sein k"onnen...das ganze funktioniert also rekursiv. \par \tty{DUP} ist aber auch eine Stelle, an der man mit einer anderen Grenze des Assemblers in Ber"uhrung kommen kann: maximal k"onnen 1024 Byte Code oder Daten in einer Zeile erzeugt werden. Dies bezieht sich \bb{nicht} auf die Reservierung von Speicher, nur auf die Definition von Konstantenfeldern! \par \ttindex{DEFB}\ttindex{DEFW} Um mit dem M80 vertr"aglich zu sein, darf im Z80-Modus anstelle von \tty{DB}/\tty{DW} auch \tty{DEFB}/\tty{DEFW} geschrieben werden. \par \ttindex{BYTE}\ttindex{WORD}\ttindex{ADDR}\ttindex{ADDRW} Analog stellen \tty{BYTE/ADDR} bzw. \tty{WORD/ADDRW} beim COP8 einen Alias f"ur \tty{DB} bzw. \tty{DW} dar, wobei die beiden Paare sich jedoch in der Byte-Order unterscheiden: Die Befehle, die von National zur Adre"sablage vorgesehen waren, benutzen Big-Endian, \tty{BYTE} bzw. \tty{WORD} jedoch Little-Endian. Der NEC 77230 nimmt mit seiner \tty{DW}-Anweisung eine Sonderstellung ein: Sie funktioniert eher wie \tty{DATA} bei seinen kleineren Br"udern, akzeptiert aber neben String- und Integerargumenten auch Gleitkommawerte (und legt sie prozessorspezifischen 32-Bit-Format ab). \tty{DUP} gibt es {\em nicht}! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DS, DS8} \ttindex{DS} \ttindex{DS8} {\em\begin{tabbing} G"ultigkeit: \= Intel, Zilog, Toshiba, NEC, TMS370, Siemens, AMD, M16(C),\\ \> National, ST9, TMS7000 \end{tabbing}} Dieser Befehl stellt eine Kurzschreibweise dar, um Speicherbereiche zu reservieren: \begin{quote}{\tt DS $$ }\end{quote} ist eine Kurzschreibweise f"ur \begin{quote}{\tt DB $$ DUP (?) }\end{quote} dar, lie"se sich also prinzipiell auch einfach "uber ein Makro realisieren, nur scheint dieser Befehl in den K"opfen einiger mit Motorola-CPUs gro"s gewordener Leute (gell, Michael?) so fest verdrahtet zu sein, da"s sie ihn als eingebauten Befehl erwarten...hoffentlich sind selbige jetzt zufrieden {\tt ;-)} {\tt DS8} ist beim National SC14xxx als Alias f"ur {\tt DS} definiert. Achten Sie aber darauf, da"s der Speicher dieser Prozessoren in Worten zu 16 Bit organisiert ist, d.h. es ist unm"oglich, einzelne Bytes zu reservieren. Falls das Argument von {\tt DS} ungerade ist, wird es auf die n"achstgr"o"sere gerade Zahl aufgerundet. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BYT oder FCB} \ttindex{BYT}\ttindex{FCB} {\em G"ultigkeit: 6502, 68xx} Mit diesem Befehl werden im 65xx/68xx-Modus Byte-Konstanten oder ASCII-Strings abgelegt, er entspricht also \tty{DC.B} beim 68000 oder \tty{DB} bei Intel. Ein Wiederholungsfaktor darf analog zu \tty{DC} jedem einzelnen Parameter in eckigen Klammern vorangestellt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BYTE} \ttindex{BYTE} {\em G"ultigkeit: ST6, 320C2(0)x, 320C5x, MSP, TMS9900} Dito. Ein im 320C2(0)x/5x-Modus vor dem Befehl stehendes Label wird als untypisiert gespeichert, d.h. keinem Adre"sraum zugeordnet. Der Sinn dieses Verhaltens wird bei den prozessorspezifischen Hinweisen erl"autert. Ob beim MSP bzw. TMS9900 ungerade Mengen von Bytes automatisch um ein Null-Byte erg"anzt werden sollen, kann mit dem PADDING-Befehl eingestellt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DC8} \ttindex{DC8} {\em G"ultigkeit: SC144xx} Dieser Befehl ist ein Alias f"ur {\tt DB}, d.h. mit ihm k"onnen Byte-Konstanten oder Strings im Speicher abgelegt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ADR oder FDB} \ttindex{ADR}\ttindex{FDB} {\em G"ultigkeit: 6502, 68xx} Mit diesem Befehl werden im 65xx/68xx-Modus Wortkonstanten abgelegt, er entspricht also \tty{DC.W} beim 68000 oder \tty{DW} bei Intel. Ein Wiederholungsfaktor darf analog zu \tty{DC} jedem einzelnen Parameter in eckigen Klammern vorangestellt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{WORD} \ttindex{WORD} {\em G"ultigkeit: ST6, i960, 320C2(0)x, 320C3x, 320C5x, MSP} F"ur den 320C3x und i960 werden hiermit 32-Bit-Worte abgelegt, f"ur die alle anderen Familien 16-Bit-Worte. Ein im 320C2(0)x/5x-Modus vor dem Befehl stehendes Label wird als untypisiert gespeichert, d.h. keinem Adre"sraum zugeordnet. Der Sinn dieses Verhaltens wird bei den prozessorspezifischen Hinweisen erl"autert. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DW16} \ttindex{DW16} {\em G"ultigkeit: SC144xx} Diser Befehl ist beim SC144xx der Weg, Konstanten mit Wortl"ange (16 Bit) im Speicher abzulegen und damit ein ALIAS f"ur DW. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{LONG} \ttindex{LONG} {\em G"ultigkeit: 320C2(0)x, 320C5x} Hiermit werden 32-Bit-Integer im Speicher abgelegt, und zwar in der Reihenfolge LoWord-HiWord. Ein eventuell vor dem Befehl stehendes Label wird dabei wieder als untypisiert abgelegt (der Sinn dieser Ma"snahme ist in den prozessorspezifischen Hinweisen erl"autert). %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SINGLE und EXTENDED} \ttindex{SINGLE}\ttindex{EXTENDED} {\em G"ultigkeit: 320C3x} Mit diesen Befehlen werden Gleitkomma-Konstanten im Speicher abgelegt, jedoch nicht im IEEE-Format, sondern in den vom Prozessor verwendeten 32- und 40-Bit-Formaten. Da 40 Bit nicht mehr in eine Speicherzelle hineinpassen, werden im Falle von \tty{EXTENDED} immer derer 2 pro Wert belegt. Im ersten Wort finden sich die oberen 8 Bit (der Exponent), der Rest (Vorzeichen und Mantisse) in zweiten Wort. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FLOAT und DOUBLE} \ttindex{FLOAT}\ttindex{DOUBLE} {\em G"ultigkeit: 320C2(0)x, 320C5x} Mit diesen Befehlen k"onnen 32- bzw. 64-Bit-Gleitkommazahlen im IEEE-Format im Speicher abgelegt werden. Dabei wird das niederwertigste Byte jeweils auf der ersten Speicherstelle abgelegt. Ein eventuell vor dem Befehl stehendes Label wird wieder als untypisiert gespeichert (der Sinn dieser Ma"snahme ist in den prozessorspezifischen Hinweisen erl"autert). %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{EFLOAT, BFLOAT, TFLOAT} \ttindex{EFLOAT}\ttindex{BFLOAT}\ttindex{TFLOAT} {\em G"ultigkeit: 320C2(0)x, 320C5x} Auch diese Befehle legen Gleitkommazahlen im Speicher ab, jedoch in einem nicht-IEEE-Format, das evtl. leichter von Signalprozessoren zu verarbeiten ist: \begin{itemize} \item{\tty{EFLOAT}: Mantisse mit 16 Bit, Exponent mit 16 Bit} \item{\tty{BFLOAT}: Mantisse mit 32 Bit, Exponent mit 16 Bit} \item{\tty{DFLOAT}: Mantisse mit 64 Bit, Exponent mit 32 Bit} \end{itemize} Gemeinsam ist den Befehlen, da"s die Mantisse vor dem Exponenten abgelegt wird (Lo-Word jeweils zuerst) und beide im Zweierkomplement dargestellt werden. Ein eventuell vor dem Befehl stehendes Label wird wieder als untypisiert gespeichert (der Sinn dieser Ma"snahme ist in den prozessorspezifischen Hinweisen erl"autert). %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{Qxx und LQxx} \ttindex{Qxx}\ttindex{LQxx} {\em G"ultigkeit: 320C2(0)x, 320C5x} Mit diesen Befehlen k"onnen Gleitkommazahlen in einem Festkommaformat abgelegt werden. \tty{xx} ist dabei eine zweistellige Zahl, mit deren Zweierpotenz der Gleitkommawert vor der Umwandlung in eine ganze Zahl multipliziert werden soll. Er bestimmt also praktisch, wieviele Bits f"ur die Nachkommastellen reserviert werden sollen. W"ahrend aber \tty{Qxx} nur ein Wort (16 Bit) ablegt, wird das Ergebnis bei \tty{LQxx} in 2 Worten (LoWord zuerst) abgelegt. Das sieht dann z.B. so aus: \begin{verbatim} q05 2.5 ; --> 0050h lq20 ConstPI ; --> 43F7h 0032h \end{verbatim} Mich m"oge niemand steinigen, wenn ich mich auf meinem HP28 verrechnet haben sollte... %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DATA} \ttindex{DATA} {\em G"ultigkeit: PIC, 320xx, AVR, MELPS-4500, 4004, $\mu$PD772x} Mit diesem Befehl werden Daten im aktuellen Segment abgelegt, wobei sowohl Integer- als auch Stringwerte zul"assig sind. Bei Strings belegt beim 16C5x/16C8x, 17C4x im Datensegment und 4500er ein Zeichen ein Wort, bei AVR, 17C4x im Codesegment, $\mu$PD772x in den Datensegmenten und 3201x/3202x passen zwei Zeichen in ein Wort (LSB zuerst), beim $\mu$PD7725 drei und beim 320C3x sogar derer 4 (MSB zuerst). Im Gegensatz dazu mu"s im Datensegment des 4500ers ein Zeichen auf zwei Speicherstellen verteilt werden, ebenso wie beim 4004. Der Wertebereich f"ur Integers entspricht der Wortbreite des jeweiligen Prozessors im jeweiligen Segment. Das bedeutet, da"s \tty{DATA} beim 320C3x die Funktion von \tty{WORD} mit einschlie"st (die von \tty{SINGLE} "ubrigens auch, wenn AS das Argument als Gleitkommazahl erkennt). %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ZERO} \ttindex{ZERO} {\em G"ultigkeit: PIC} Dieser Befehl legt einen durch den Parameter spezifizierte Zahl von Nullworten (=NOPs) im Speicher ab. Es k"onnen maximal 512 Nullen mit einem Befehl abgelegt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FB und FW} \ttindex{FB}\ttindex{FW} {\em G"ultigkeit: COP8} Mit diesen Befehlen kann ein gr"o"serer Block von Speicher (dessen L"ange in Bytes bzw. Worten der erste Parameter angibt) mit einer Byte- bzw. Wortkonstanten gef"ullt werden, die durch den zweiten Parameter angegeben wird. Die Maximalgr"o"se des Blocks betr"agt 1024 Elemente f"ur \tty{FB} bzw. 512 Elemente f"ur \tty{FW}. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ASCII und ASCIZ} \ttindex{ASCII}\ttindex{ASCIZ} {\em G"ultigkeit: ST6} Mit diesen beiden Befehlen k"onnen Stringkonstanten im Speicher abgelegt werden. W"ahrend ASCII nur die reinen Daten im Speicher ablegt, versieht \tty{ASCIZ} automatisch \ii{jeden} angegebenen String mit einem NUL-Zeichen am Ende. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{STRING und RSTRING} \ttindex{STRING}\ttindex{RSTRING} {\em G"ultigkeit: 320C2(0)x, 320C5x} Diese Anweisungen funktionieren analog zu {\tt DATA}, jedoch werden hier Integer-Ausdr"ucke grunds"atzlich als {\it Bytes} mit einem entsprechend eingeschr"ankten Wertebereich betrachtet, wodurch es m"ogliich wird, die Zahlen zusammen mit anderen Zahlen oder Zeichen paarweise in Worte zu verpacken. Die beiden Befehle unterscheiden sich lediglich in der Reihenfolge der Bytes in einem Wort: Bei {\tt STRING} wird zuerst das obere und danach das untere gef"ullt, bei {\tt RSTRING} ist es genau umgekehrt. Ein eventuell vor dem Befehl stehendes Label wird wieder als untypisiert gespeichert. Der Sinn dieser Ma"snahme ist im entsprechenden Kapitel mit den prozessorspezifischen Befehlen erl"autert. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FCC} \ttindex{FCC} {\em G"ultigkeit: 6502, 68xx} Mit diesem Befehl werden im 65xx/68xx-Modus String-Konstanten abgelegt. Beachten Sie jedoch, da"s im Gegensatz zum Originalassembler AS11 von Motorola (dessentwegen dieser Befehl existiert, bei AS ist diese Funktion im \tty{BYT}-Befehl enthalten), String-Argumente nur in G"ansef"u"schen und nicht in Hochkommas oder Schr"agstrichen eingeschlossen werden d"urfen! Ein Wiederholungsfaktor darf analog zu \tty{DC} jedem einzelnen Parameter in eckigen Klammern vorangestellt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DFS oder RMB} \ttindex{DFS}\ttindex{RMB} {\em G"ultigkeit: 6502, 68xx} Dieser Befehl dient im 65xx/68xx-Modus zur Reservierung von Speicher, er entspricht \tty{DS.B} beim 68000 oder \tty{DB ?} bei Intel. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BLOCK} \ttindex{BLOCK} {\em G"ultigkeit: ST6} Dito. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SPACE} \ttindex{SPACE} {\em G"ultigkeit: i960} Dito. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{RES} \ttindex{RES} {\em G"ultigkeit: PIC, MELPS-4500, 3201x, 320C2(0)x, 320C5x, AVR, $\mu$PD772x} Dieser Befehl dient zur Reservierung von Speicher. Er reserviert im Codesegment immer W"orter (10/12/14/16 Bit), im Datensegment bei den PICs Bytes, beim 4500er Nibbles sowie bei Texas ebenfalls W"orter. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BSS} \ttindex{BSS} {\em G"ultigkeit: 320C2(0)x, 320C3x, 320C5x, MSP} \tty{BSS} arbeitet analog zu \tty{RES}, lediglich ein eventuell vor dem Befehl stehendes Symbol wird beim 320C2(0)x/5x als untypisiert gespeichert. Der Sinn dieser Ma"snahme kann im Kapitel mit den prozessorspezifischen Hinweisen nachgelesen werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DSB und DSW} \ttindex{DSB}\ttindex{DSW} {\em G"ultigkeit: COP8} Diese beiden Befehle stellen im COP8-Modus die zum ASMCOP von National kompatible Methode dar, Speicher zu reservieren. W"ahrend \tty{DSB} nur einzelne Bytes freih"alt, reserviert \tty{DSW} W"orter und damit effektiv doppelt soviel Bytes wie \tty{DSB}. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{DS16} \ttindex{DS16} {\em G"ultigkeit: SC144xx} Dieser Befehl reserviert Speicher in Schritten von vollst"andigen Worten, d.h. 16 Bit. Er stellt einen Alias zu {\tt DW} dar. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{ALIGN} \ttindex{ALIGN} {\em G"ultigkeit: alle Prozessoren} \tty{ALIGN} mit einem Integerausdruck als Argument erlaubt es, den Programmz"ahler auf eine bestimmte Adresse auszurichten. Die Ausrichtung erfolgt dergestalt, da"s der Programmz"ahler so weit erh"oht wird, da"s er ein ganzzahliges mehrfaches des Argumentes wird. In seiner Funktion entspricht \tty{ALIGN} also \tty{DS.x 0} beim den 680x0ern, nur ist die Ausrichtung noch flexibler. \par Beispiel: \begin{verbatim} align 2 \end{verbatim} macht den Programmz"ahler gerade. Wie auch bei \tty{DS.x 0} ist der freibleibende Speicherraum undefiniert. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{LTORG} \ttindex{LTORG} {\em G"ultigkeit: SH7x00} Da der SH7000-Prozessor seine Register immediate nur mit 8-Bit-Werten laden kann, AS dem Programmierer jedoch vorgaukelt, da"s es eine solche Einschr"ankung nicht g"abe, mu"s er die dabei entstehenden Konstanten irgendwo im Speicher ablegen. Da es nicht sinnvoll w"are, dies einzeln zu tun (wobei jedes Mal Sprungbefehle anfallen w"urden...), werden die Literale gesammelt und k"onnen vom Programmierer mit diesem Befehl gezielt blockweise (z.B. am Ende eines Unterprogrammes) abgelegt werden. Zu den zu beachtenden Details und Fallen sei auf das Kapitel mit den SH7000-spezifischen Dingen hingewiesen. %%--------------------------------------------------------------------------- \section{Makrobefehle} {\em G"ultigkeit: alle Prozessoren} Kommen wir nun zu dem, was einen Makroassembler vom normalen Assembler unterscheidet: der M"oglichkeit, Makros zu definieren (ach was ?!). \par Unter Makros verstehe ich hier erst einmal eine Menge von Anweisungen (normal oder Pseudo), die mit bestimmten Befehlen zu einem Block zusammengefa"st werden und dann auf bestimmte Weise bearbeitet werden k"onnen. Zur Bearbeitung solcher Bl"ocke kennt der Assembler folgende Befehle: %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{MACRO} \ttindex{MACRO}\ttindex{ENDM} ist der wohl wichtigste Befehl zur Makroprogrammierung. Mit der Befehlsfolge \begin{verbatim} MACRO [Parameterliste] ENDM \end{verbatim} wird das Makro \tty{$<$Name$>$} als die eingeschlossene Befehlsfolge definiert. Diese Definition alleine erzeugt noch keinen Code! Daf"ur kann fortan die Befehlsfolge einfach durch den Namen abgerufen werden, das Ganze stellt also eine Schreiberleichterung dar. Um die ganze Sache etwas n"utzlicher zu machen, kann man der Makrodefinition eine Parameterliste mitgeben. Die Parameternamen werden wie "ublich durch Kommas getrennt und m"ussen --- wie der Makroname selber --- den Konventionen f"ur Symbolnamen (\ref{SectSymConv}) gen"ugen. \par Sowohl Makronamen als auch -parameter sind von einer Umschaltung von AS in den case-sensitiven Modus betroffen. \par Makros sind "ahnlich wie Symbole lokal, d.h. bei Definition in einer Sektion sind sie nur in dieser Sektion und ihren Untersektionen bekannt. Dieses Verhalten l"a"st sich aber durch die weiter unten beschriebenen Optionen \tty{PUBLIC} und \tty{GLOBAL} in weiten Grenzen steuern. \par Neben den eigentlichen Makroparametern k"onnen in der Parameterliste auch Steuerparameter enthalten sein, die die Abarbeitung des betroffenen Makros beeinflussen; diese Parameter werden von normalen Parametern dadurch unterschieden, da"s sie in geschweifte Klammern eingeschlossen sind. Es sind folgende Steuerparameter definiert: \begin{itemize} \item{\tty{EXPAND/NOEXPAND} : legen fest, ob bei der sp"ateren Verwendung diese Makros der expandierte Code mit angezeigt werden soll. Default ist der durch den Pseudobefehl \tty{MACEXP} festgelegte Wert.} \item{\tty{PUBLIC[:Sektionsname]} : ordnet das Makro nicht der aktuellen, sondern einer ihr "ubergeordneten Sektion zu. Auf diese Weise kann eine Sektion Makros f"ur die ,,Au"senwelt'' zur Verf"ugung stellen. Fehlt eine Sektionsangabe, so wird das Makro v"ollig global, d.h. ist "uberall benutzbar.} \item{\tty{GLOBAL[:Sektionsname]} : legt fest, da"s neben diesem Makro noch ein weiteres Makro abgelegt werden soll, das zwar den gleichen Inhalt hat, dessen Name aber zus"atzlich mit dem Namen der Sektion versehen ist, in der es definiert wurde und das der spezifizierten Sektion zugeordnet werden soll. Bei dieser mu"s es sich um eine Obersektion zu der aktuellen Sektion handeln; fehlt die Angabe, so wird das zus"atzliche Makro global sichtbar. Wird z.B. ein Makro \tty{A} in der Sektion \tty{B} definiert, die wiederum eine Untersektion der Sektion \tty{C} ist, so w"urde neben z.B. dem Makro A ein weiteres globales mit dem Namen \tty{C\_B\_A} erzeugt. W"urde dagegen \tty{C} als Zielsektion angegeben, so w"urde das Makro \tty{B\_A} hei"sen und der Sektion \tty{C} zugeordnet. Diese Option ist defaultm"a"sig ausgeschaltet und hat auch nur einen Effekt, falls sie innerhalb einer Sektion benutzt wird. Das lokal bekannte Originalmakro wird von ihr nicht beeinflu"st.} \item{\tty{EXPORT/NOEXPORT} : legen fest, ob die Definition dieses Makros in einer getrennten Datei abgelegt werden soll, falls die Kommandozeilenoption \tty{-M} gegeben wurde. Auf diese Weise k"onnen einzelne Definitionen ,,privater'' Makros selektiv ausgeblendet werden. Der Default ist FALSE, d.h. die Definition wird nicht in der Datei abgelegt. Ist zus"atzlich die \tty{GLOBAL}-Option gegeben worden, so wird das Makro mit dem modifizierten Namen abgelegt.} \end{itemize} Diese eben beschriebenen Steuerparameter werden von AS aus der Parameterliste ausgefiltert, haben also keine weitere Wirkung in der folgenden Verarbeitung und Benutzung. \par Beim Aufruf eines Makros werden die beim Aufruf angegebenen Parameternamen "uberall textuell im Befehlsblock eingesetzt und der sich so ergebene Assemblercode wird normal assembliert. Sollten beim Aufruf zu wenige Parameter angegeben werden, werden Nullstrings eingef"ugt. Wichtig ist zu wissen, da"s bei der Makroexpansion keine R"ucksicht auf eventuell in der Zeile enthaltene Stringkonstanten genommen wird. Zu diesem Detail gilt die alte IBM-Regel: \begin{quote} \ii{It's not a bug, it's a feature!} \end {quote} Diese L"ucke kann man bewu"st ausnutzen, um Parameter mittels Stringvergleichen abzupr"ufen. So kann man auf folgende Weise z.B. pr"ufen, wie ein Makroparameter aussieht: \begin{verbatim} mul MACRO para,parb IF UpString("PARA")<>"A" MOV a,para ENDIF IF UpString("PARB")<>"B" MOV b,parb ENDIF mul ab ENDM \end{verbatim} Wichtig ist bei obigem Beispiel, da"s der Assembler alle Parameternamen im case-sensitiven Modus in Gro"sbuchstaben umsetzt, in Strings aber nie eine Umwandlung in Gro"sbuchstaben erfolgt. Die Makroparameternamen m"ussen in den Stringkonstanten daher gro"s geschrieben werden. \par F"ur die Makroparameter gelten die gleichen Konventionen wie bei normalen Symbolen, mit der Ausnahme, da"s hier nur Buchstaben und Ziffern zugelassen sind, also weder Punkte noch Unterstriche. Diese Einschr"ankung hat ihren Grund in einem verstecktem Feature: Der Unterstrich erlaubt es, einzelne Makroparameternamen zu einem Symbol zusammenzuketten, z.B. in folgendem Beispiel: \begin{verbatim} concat MACRO part1,part2 CALL part1_part2 ENDM \end{verbatim} Der Aufruf \begin{verbatim} concat Modul,Funktion \end{verbatim} ergibt also \begin{verbatim} CALL Modul_Funktion \end{verbatim} \par Um alle Klarheiten auszur"aumen, ein einfaches Beispiel: Ein intelverbl"odeter Programmierer m"ochte die Befehle \tty{PUSH/POP} unbedingt auch auf dem 68000 haben. Er l"ost das ,,Problem'' folgenderma"sen: \begin{verbatim} push MACRO op MOVE op,-(sp) ENDM pop MACRO op MOVE (sp)+,op ENDM \end{verbatim} Schreibt man nun im Code \begin{verbatim} push d0 pop a2 , \end{verbatim} so wird daraus \begin{verbatim} MOVE d0,-(sp) MOVE (sp)+,a2 \end{verbatim} Eine Makrodefinition darf nicht "uber Includefilegrenzen hinausgehen. \par In Makror"umpfen definierte Labels werden immer als lokal betrachtet, ein expliziter \tty{LOCAL}-Befehl ist also nicht erforderlich (und ist auch nicht definiert). Ist es aus irgendwelchen Gr"unden erforderlich, so kann man es mit \tty{LABEL} definieren, dessen Anwendung (wie bei \tty{BIT,SFR}...) immer globale Symbole ergibt : \begin{verbatim} LABEL * \end{verbatim} Da der Assembler beim Parsing einer Zeile zuerst die Makroliste und danach die Prozessorbefehle abklappert, lassen sich auch Prozessorbefehle neu definieren. Die Definition sollte dann aber vor der ersten Benutzung des Befehles durchgef"uhrt werden, um Phasenfehler wie im folgenden Beispiel zu vermeiden: \begin{verbatim} BSR ziel bsr MACRO target JSR ziel ENDM BSR ziel \end{verbatim} Im ersten Pass ist bei der Assemblierung des \tty{BSR}-Befehles das Makro noch nicht bekannt, es wird ein 4 Byte langer Befehl erzeugt. Im zweiten Pass jedoch steht die Makrodefinition sofort (aus dem ersten Pass) zur Verf"ugung, es wird also ein 6 Byte langer \tty{JSR} kodiert. Infolgedessen sind alle darauffolgenden Labels um zwei zu niedrig, bei allen weiteren Labels sind Phasenfehler die Folge, und ein weiterer Pass ist erforderlich. \par Da durch die Definition eines Makros ein gleichnamiger Maschinen- oder Pseudobefehl nicht mehr zugreifbar ist, gibt es eine Hintert"ur, die Originalbedeutung zu erreichen: Stellt man dem Mnemonic ein \tty{!} voran, so wird das Durchsuchen der Makroliste unterdr"uckt. Das kann beispielsweise n"utzlich sein, um Befehle in ihrer M"achtigkeit zu erweitern, z.B. die Schiebebefehle beim TLCS-90: \begin{verbatim} srl macro op,n ; Schieben um n Stellen rept n ; n einfache Befehle !srl op endm endm \end{verbatim} Fortan hat der \tty{SRL}-Befehl einen weiteren Parameter... %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{IRP} \ttindex{IRP} ist die eine vereinfachte Form von Makrodefinitionen f"ur den Fall, da"s eine Befehlsfolge einmal auf mehrere Operanden angewendet werden soll und danach nicht mehr gebraucht wird. \tty{IRP} ben"otigt als ersten Parameter ein Symbol f"ur den Operanden, und danach eine (fast) beliebige Menge von Parametern, die nacheinander in den Befehlsblock eingesetzt werden. Um eine Menge von Registern auf den Stack zu schieben, kann man z.B. schreiben \begin{verbatim} IRP op, acc,b,dpl,dph PUSH op ENDM \end{verbatim} was in folgendem resultiert: \begin{verbatim} PUSH acc PUSH b PUSH dpl PUSH dph \end{verbatim} Benutzte Labels sind wieder f"ur jeden Durchgang automatisch lokal. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{IRPC} \ttindex{IRPC} \tty{IRPC} ist eine Variante von \tty{IRP}, bei der das erste Argument in den bis \tty{ENDM} folgenden Zeilen nicht sukzessiv durch die weiteren Parameter, sondern durch die Zeichen eines Strings ersetzt wird. Einen String kann man z.B. also auch ganz umst"andlich so im Speicher ablegen: \begin{verbatim} irpc char,"Hello World" db 'CHAR' endm \end{verbatim} \bb{ACHTUNG!} Wie das Beispiel schon zeigt, setzt \tty{IRPC} nur das Zeichen selber ein, da"s daraus ein g"ultiger Ausdruck entsteht (also hier durch die Hochkommas, inklusive des Details, da"s hier keine automatische Umwandlung in Gro"sbuchstaben vorgenommen wird), mu"s man selber sicherstellen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{REPT} \ttindex{REPT} ist die einfachste Form der Makrobenutzung. Der im Rumpf angegebene Code wird einfach sooft assembliert, wie der Integerparameter von \tty{REPT} angibt. Dieser Befehl wird h"aufig in kleinen Schleifen anstelle einer programmierten Schleife verwendet, um den Schleifenoverhead zu sparen. \par Der Vollst"andigkeit halber ein Beispiel: \begin{verbatim} REPT 3 RR a ENDM \end{verbatim} rotiert den Akku um 3 Stellen nach rechts. \par Symbole sind wiederum f"ur jede einzelne Repetition lokal. Ist das Argument von \tty{REPT} kleiner oder gleich Null, so wird "uberhaupt keine Expansion durchgef"uhrt. Dies ist ein Unterschied zu fr"uheren Versionen von AS, die hier etwas ,,schlampig'' waren und immer mindestens eine Expansion ausf"uhrten. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{WHILE} \ttindex{WHILE} \tty{WHILE} arbeitet analog zu \tty{REPT}, allerdings tritt an die Stelle einer festen Anzahl als Argument ein boolescher Ausdruck, und der zwischen \tty{WHILE} und \tty{ENDM} eingeschlossene Code wird sooft assenbliert, bis der Ausdruck logisch falsch wird. Im Extremfall kann dies bedeuten, da"s der Code "uberhaupt nicht assembliert wird, falls die Bedingung bereits beim Eintritt in das Konstrukt falsch ist. Andererseits kann es nat"urlich auch passieren, da"s die Bedingung immer wahr bleibt, und AS l"auft bis an das Ende aller Tage...hier sollte man also etwas Umsicht walten lassen, d.h. im Rumpf mu"s eine Anweisung stehen, die die Bedingung auch beeinflu"st, z.B. so: \begin{verbatim} cnt set 1 sq set cnt*cnt while sq<=1000 dc.l sq cnt set cnt+1 sq set cnt*cnt endm \end{verbatim} Dieses Beispiel legt alle Quadratzahlen bis 1000 im Speicher ab. \par Ein unsch"ones Detail bei \tty{WHILE} ist im Augenblick leider noch, da"s am Ende der Expansion eine zus"atzliche Leerzeile, die im Quellrumpf nicht vorhanden war, eingef"ugt wird. Dies ist ein ,,Dreckeffekt'', der auf einer Schw"ache des Makroprozessors beruht und leider nicht so einfach zu beheben ist. Hoffentlich st"ort es nicht allzusehr.... %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{EXITM} \ttindex{EXITM} \tty{EXITM} stellt einen Weg dar, um eine Makroexpansion oder einen der Befehle \tty{REPT}, \tty{IRP} oder \tty{WHILE} vorzeitig abzubrechen. Eine solche M"oglichkeit hilft zum Beispiel, umfangreichere Klammerungen mit \tty{IF-ENDIF}-Sequenzen in Makros "ubersichtlicher zu gestalten. Sinnvollerweise ist ein \tty{EXITM} aber selber auch immer bedingt, was zu einem wichtigen Detail f"uhrt: Der Stack, der "uber momentan offene \tty{IF}- oder \tty{SWITCH}-Konstrukte Buch f"uhrt, wird auf den Stand vor Beginn der Makroexpansion zur"uckgesetzt. Dies ist f"ur bedingte \tty{EXITM}'s zwingend notwendig, da das den \tty{EXITM}-Befehl in irgendeiner Form einschlie"sende \tty{ENDIF} oder \tty{ENDCASE} nicht mehr erreicht wird und AS ohne einen solchen Trick eine Fehlermeldung erzeugen w"urde. Weiterhin ist es f"ur verschachtelte Makrokonstruktionen wichtig, zu beachten, da"s \tty{EXITM} immer nur das momentan innerste Konstrukt abbricht! Wer aus seiner geschachtelten Konstruktion vollst"andig ,,ausbrechen'' will, mu"s auf den h"oheren Ebenen ebenfalls \tty{EXITM}'s vorsehen! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FUNCTION} \ttindex{FUNCTION} \label{SectFUNCTION} \tty{FUNCTION} ist zwar kein Makrobefehl im engeren Sinne, da hierbei aber "ahnliche Mechanismen wie bei Makroersetzungen angewendet werden, soll er hier beschrieben werden. \par Dieser Befehl dient dazu, neue Funktionen zu definieren, die in Formel\-ausdr"ucken wie die vordefinierten Funktionen verwendet werden k"onnen. Die Definition mu"s in folgender Form erfolgen: \begin{verbatim} FUNCTION ,..,, \end{verbatim} Die Argumente sind die Werte, die sozusagen in die Funktion ,,hineingesteckt'' werden. In der Definition werden f"ur die Argumente symbolische Namen gebraucht, damit der Assembler bei der Benutzung der Funktion wei"s, an welchen Stellen die aktuellen Werte einzusetzen sind. Dies kann man an folgendem Beispiel sehen: \begin{verbatim} isgit FUNCTION ch,(ch>='0')&&(ch<='9') \end{verbatim} Diese Funktion "uberpr"uft, ob es sich bei dem Argument (wenn man es als Zeichen interpretiert) um eine Ziffer im momentan g"ultigen Zeichencode handelt (der momentane Zeichencode ist mittels \tty{CHARSET} ver"anderbar, daher die vorsichtige Formulierung). \par Die Argumentnamen (in diesem Falle \tty{CH}) m"ussen den gleichen h"arteren Symbolkonventionen gen"ugen wie Parameter bei einer Makrodefinition, d.h. die Sonderzeichen . und \_ sind nicht erlaubt. \par Selbstdefinierte Funktionen werden genauso benutzt wie eingebaute, d.h. mit einer durch Kommas getrennten, geklammerten Argumentliste: \begin{verbatim} IF isdigit(Zeichen) message "\{Zeichen} ist eine Ziffer" ELSEIF message "\{Zeichen} ist keine Ziffer" ENDIF \end{verbatim} \par Bei dem Aufruf der Funktion werden die Argumente nur einmal berechnet und danach an allen Stellen der Formel eingesetzt, um den Rechenaufwand zu reduzieren und Seiteneffekte zu vermeiden. Bei Funktionen mit mehreren Argumenten m"ussen die einzelnen Argumente bei der Benutzung durch Kommata getrennt werden. \par \bb{ACHTUNG!} Analog wie bei Makros kann man mit der Definition von Funktionen bestehende Funktionen umdefinieren. Damit lassen sich auch wieder Phasenfehler provozieren. Solche Definitionen sollten daher auf jeden Fall vor der ersten Benutzung erfolgen! \par Da die Berechnung des Funktionsergebnisses anhand des Formelausdruckes auf textueller Ebene erfolgt, kann der Ergebnistyp von dem Typ des Eingangsargumentes abh"angen. So kann bei folgender Funktion \begin{verbatim} double function x,x+x \end{verbatim} das Ergebnis ein Integer, eine Gleitkommazahl oder sogar ein String sein, je nach Typ des Arguments! \par Bei der Definition und Ansprache von Funktionen wird im case-sensitiven Modus zwischen Gro"s- und Kleinschreibung unterschieden, im Gegensatz zu eingebauten Funktionen! %%--------------------------------------------------------------------------- \section{bedingte Assemblierung} {\em G"ultigkeit: alle Prozessoren} Der Assembler unterst"utzt die bedingte Assemblierung mit Hilfe der Konstrukte \tty{IF}... sowie \tty{SWITCH}... . Diese Befehle wirken zur Assemblierzeit, indem entsprechend der Bedingung Teile "ubersetzt oder "ubersprungen werden. Diese Befehle sind also \ii{nicht} mit den IF-Statements h"oherer Programmiersprachen zu vergleichen (obwohl es sehr verlockend w"are, den Assembler um die Strukturierungsbefehle h"oherer Sprachen zu erweitern...). \par Die folgenden Konstrukte d"urfen beliebig (bis zum Speicher"uberlauf) geschachtelt werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{IF / ELSEIF / ENDIF} \ttindex{IF} \ttindex{ELSEIF}\ttindex{ELSE} \ttindex{ENDIF} \tty{IF} ist das gebr"auchlichere und allgemeiner verwendbare Konstrukt. Die allgemeine Form eines \tty{IF}-Befehles lautet folgenderma"sen: \begin{verbatim} IF ELSEIF (evtl. weitere ELSEIFs) ELSEIF ENDIF \end{verbatim} \tty{IF} dient als Einleitung und wertet den ersten Ausdruck aus und assembliert Block 1, falls der Ausdruck wahr (d.h. ungleich 0) ist. Alle weiteren \tty{ELSEIF}-Teile werden dann ignoriert. Falls der Ausdruck aber nicht wahr ist, wird Block 1 "ubersprungen und Ausdruck 2 ausgewertet. Sollte dieser nun wahr sein, wird Block 2 assembliert. Die Zahl der \tty{ELSEIF}-Teile ist variabel und ergibt eine \tty{IF-THEN-ELSE}-Leiter beliebiger L"ange. Der dem letzten \tty{ELSEIF} (ohne Parameter) zugeordnete Block wird nur assembliert, falls alle vorigen Ausdr"ucke falsch ergaben und bildet sozusagen einen ,,Default-Zweig''. Wichtig ist, da"s von den Bl"ocken immer nur \ii{einer} assembliert wird, und zwar der erste, dessen zugeordnetes \tty{IF/ELSEIF} einen wahren Ausdruck hatte. \par Die \tty{ELSEIF}-Teile sind optional, d.h. auf \tty{IF} darf auch direkt \tty{ENDIF} folgen, ein parameterloses \tty{ELSEIF} bildet aber immer den letzten Zweig. Ein \tty{ELSEIF} bezieht sich immer auf das letzte, noch nicht abgeschlossene \tty{IF}. \par Neben \tty{IF} sind noch folgende weitere bedingte Befehle definiert: \ttindex{IFDEF}\ttindex{IFNDEF} \ttindex{IFUSED}\ttindex{IFNUSED} \ttindex{IFEXIST}\ttindex{IFNEXIST} \ttindex{IFB}\ttindex{IFNB} \begin{itemize} \item{\tty{IFDEF} $<$Symbol$>$ : wahr, falls das Symbol definiert wurde. Die Definition mu"s vor \tty{IFDEF} erfolgt sein.} \item{\tty{IFNDEF} $<$Symbol$>$ : Umkehrung zu \tty{IFDEF}} \item{\tty{IFUSED} $<$Symbol$>$ : wahr, falls das Symbol bisher mindestens einmal benutzt wurde.} \item{\tty{IFNUSED} $<$Symbol$>$ : Umkehrung zu \tty{IFUSED}} \item{\tty{IFEXIST} $<$Name$>$ : wahr, falls die angegebene Datei existiert. F"ur Schreibweise und Suchpfade gelten gleiche Regeln wie beim \tty{INCLUDE}-Befehl (siehe Abschnitt \ref{SectInclude}).} \item{\tty{IFNEXIST} $<$Name$>$ : Umkehrung zu \tty{IFEXIST}} \item{\tty{IFB} $<$Arg-Liste$>$ : wahr, falls alle Argumente der Parameterliste leer sind.} \item{\tty{IFNB} $<$Arg-Liste$>$ : Umkehrung zu IFB.} \end{itemize} Anstelle von {\tt ELSEIF} darf auch {\tt ELSE} geschrieben werden, weil das wohl alle so gewohnt sind.... %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SWITCH / CASE / ELSECASE / ENDCASE} \ttindex{SWITCH}\ttindex{CASE}\ttindex{ELSECASE}\ttindex{ENDCASE} \tty{SWITCH} ist ein Spezialfall von \tty{IF} und f"ur den Fall gedacht, da"s ein Ausdruck mit einer Reihe von Werten verglichen werden soll. Dies ist nat"urlich auch mit \tty{IF} und einer Reihe von \tty{ELSEIF}s machbar, die folgende Form \begin{verbatim} SWITCH ... CASE ... ... CASE ... ... (weitere CASE-Konstrukte) ... CASE ... ... ELSECASE ... ... ENDCASE \end{verbatim} bietet aber den Vorteil, da"s der zu pr"ufende Ausdruck nur einmal hingeschrieben und berechnet werden mu"s, er ist also weniger fehleranf"allig und etwas schneller als eine \tty{IF}-Kette, daf"ur nat"urlich auch nicht so flexibel. \par Es ist m"oglich, bei den \tty{CASE}-Anweisungen mehrere, durch Kommata getrennte Werte anzugeben, um den entsprechenden Block in mehreren F"allen assemblieren zu lassen. Der \tty{ELSECASE}-Zweig dient wiederum als ,,Auffangstelle'' f"ur den Fall, da"s keine der \tty{CASE}-Bedingungen greift. Fehlt er und fallen alle Pr"ufungen negativ aus, so gibt AS eine Warnung aus. \par Auch wenn die Wertelisten der \tty{CASE}-Teile sich "uberlappen, so wird immer nur \ii{ein} Zweig ausgef"uhrt, und zwar bei Mehrdeutigkeiten der erste. \par \tty{SWITCH} dient nur der Einleitung des ganzen Konstruktes; zwischen ihm und dem ersten \tty{CASE} darf beliebiger Code stehen (andere \tty{IF}s d"urfen aber nicht offen bleiben!), im Sinne eines durchschaubaren Codes sollte davon aber kein Gebrauch gemacht werden. %%--------------------------------------------------------------------------- \section{Listing-Steuerung} {\em G"ultigkeit: alle Prozessoren} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PAGE} \ttindex{PAGE} Mit \tty{PAGE} kann man AS die Dimensionen des Papiers, auf dem das Listing ausgedruckt werden soll, mitteilen. Als erster Parameter wird dabei die Anzahl von Zeilen angegeben, nach der AS automatisch einen Zeilenvorschub ausgeben soll. Zu ber"ucksichtigen ist allerdings, da"s bei dieser Angabe die Kopfzeilen inklusive einer evtl. mit \tty{TITLE} spezifizierten Zeile nicht mitgerechnet werden. Der Minimalwert f"ur die Zeilenzahl ist 5, der Maximalwert 255. Eine Angabe von 0 f"uhrt dazu, da"s AS "uberhaupt keine automatischen Seitenvorsch"ube ausf"uhrt, sondern nur noch solche, die explizit durch \tty{NEWPAGE}-Befehle oder implizit am Ende des Listings (z.B. vor der Symboltabelle) von AS ausgel"ost wurden. \par Die Angabe der Breite des Listings in Zeichen kann als optionaler zweiter Parameter erfolgen und erf"ullt zwei Zwecke: Zum einen l"auft der Zeilenz"ahler von AS korrekt weiter, wenn eine Quell-Zeile "uber mehrere Listing-Zeilen geht, zum anderen gibt es Drucker (wie z.B. Laserdrucker), die beim "Uberschreiten des rechten Randes nicht automatisch in eine neue Zeile umbrechen, sondern den Rest einfach ,,verschlucken''. Aus diesem Grund f"uhrt AS auch den Zeilenumbruch selbstst"andig durch, d.h. zu lange Zeilen werden in Bruchst"ucke zerlegt, die eine L"ange kleiner oder gleich der eingestellten L"ange haben. In Zusammenhang mit Druckern, die einen automatischen Zeilenumbruch besitzen, kann das aber zu doppelten Zeilenvorsch"uben f"uhren, wenn man als Breite exakt die Zeilenbreite des Druckers angibt. Die L"osung in einem solchen Fall ist, als Zeilenbreite ein Zeichen weniger anzugeben. Die eingestellte Zeilenbreite darf zwischen 5 und 255 Zeichen liegen; analog zur Seitenl"ange bedeutet ein Wert von 0, da"s AS keine Splittung der Listing-Zeilen vornehmen soll; eine Ber"ucksichtigung von zu langen Zeilen im Listing beim Seitenumbruch kann dann nat"urlich auch nicht mehr erfolgen. \par Die Defaulteinstellung f"ur die Seitenl"ange ist 60 Zeilen, f"ur die Zeilenbreite 0; letztere Wert wird auch angenommen, wenn \tty{PAGE} nur mit einem Argument aufgerufen wird. \par \bb{ACHTUNG!} AS hat keine M"oglichkeit, zu "uberpr"ufen, ob die eingestellte Listing-L"ange und Breite mit der Wirklichkeit "ubereinstimmen! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{NEWPAGE} \ttindex{NEWPAGE} \tty{NEWPAGE} kann dazu benutzt werden, einen Seitenvorschub zu erzwingen, obwohl die Seite noch gar nicht voll ist. Dies kann z.B. sinnvoll sein, um logisch voneinander getrennte Teile im Assemblerprogramm auch seitenm"a"sig zu trennen. Der programminterne Zeilenz"ahler wird zur"uckgesetzt, der Seitenz"ahler um Eins heraufgez"ahlt. Der optionale Parameter steht in Zusammenhang mit einer hierarchischen Seitennumerierung, die AS bis zu einer Kapiteltiefe von 4 unterst"utzt. 0 bedeutet dabei immer die tiefste Kapitelebene, der Maximalwert kann sich w"ahrend des Laufes ver"andern, wenn das auch verwirrend wirken kann, wie folgendes Beispiel zeigt: \begin{quote}\begin{tabbing} \hspace{2.5cm} \= \hspace{4.5cm} \= \kill Seite 1, \> Angabe \tty{NEWPAGE 0} \> $\rightarrow$ Seite 2 \\ Seite 2, \> Angabe \tty{NEWPAGE 1} \> $\rightarrow$ Seite 2.1 \\ Seite 2.1, \> Angabe \tty{NEWPAGE 1} \> $\rightarrow$ Seite 3.1 \\ Seite 3.1, \> Angabe \tty{NEWPAGE 0} \> $\rightarrow$ Seite 3.2 \\ Seite 3.2, \> Angabe \tty{NEWPAGE 2} \> $\rightarrow$ Seite 4.1.1 \\ \end{tabbing}\end{quote} Je nach momentan vorhandener Kapiteltiefe kann \tty{NEWPAGE $<$Nummer$>$} also an verschiedenen Stellen eine Erh"ohung bedeuten. Ein automatischer Seitenvorschub wegen Zeilen"uberlauf oder ein fehlender Parameter ist gleichbedeutend mit \tty{NEWPAGE 0}. Am Ende des Listings wird vor Ausgabe der Symboltabelle ein implizites \tty{NEWPAGE $<$bish. Maximum$>$} durchgef"uhrt, um sozusagen ein neues Hauptkapitel zu beginnen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{MACEXP} \ttindex{MACEXP} Mit dem Befehl \begin{verbatim} MACEXP off \end{verbatim} kann man erreichen, da"s bei Makroexpansionen nur noch der Makroaufruf und nicht der expandierte Text ausgegeben wird. Die ist bei makrointensivem Code sinnvoll, um das Listing nicht ins Uferlose wachsen zu lassen. Mit \begin{verbatim} MACEXP on \end{verbatim} wird die vollst"andige Listingform wieder eingeschaltet, dies ist auch die Default-Vorgabe. \par Zwischen der Bedeutung von \tty{MACEXP} f"ur Makros und der f"ur alle anderen makroartigen Konstrukte (z.B. \tty{REPT}) besteht ein subtiler Unterschied: W"ahrend Makros intern ein Flag besitzen, das anzeigt, ob Expansionen dieses Makros ausgegeben werden sollen oder nicht, wirkt \tty{MACEXP} direkt auf alle anderen Konstrukte, die ,,vor Ort'' aufgel"ost werden. Der Sinn dieser Differenzierung besteht darin, da"s es Makros geben kann, die ausgetestet sind und die man nicht mehr sehen will, andere aber sehr wohl noch. \tty{MACEXP} dient hier als Default f"ur das bei der Definition des Makros zu setzende Flag, der mit den Steuerparametern \tty{NOEXPAND/EXPAND} "ubersteuert werden kann. Die momentane Einstellung l"a"st sich aus dem Symbol \tty{MACEXP} auslesen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{LISTING} \ttindex{LISTING} funktioniert wie \tty{MACEXP} und akzeptiert die gleichen Parameter, arbeitet aber wesentlich radikaler: Mit \begin{verbatim} LISTING off \end{verbatim} wird \ii{"uberhaupt} nichts mehr im Listing ausgegeben. Diese Anweisung macht Sinn f"ur erprobte Codeteile oder Includefiles, um den Papierverbrauch nicht ins Unerme"sliche zu steigern. \bb{ACHTUNG!} Wer sp"ater das Gegenst"uck vergi"st, bekommt auch keine Symboltabelle mehr zu sehen! Zus"atzlich zu \tty{ON} und \tty{OFF} akzeptiert \tty{LISTING} auch \tty{NOSKIPPED} und \tty{PURECODE} als Argument. Mit der \tty{NOSKIPPED}-Einstellung werden aufgrund bedingter Assemblierung nicht assemblierte Teile nicht im Listing aufgef"uhrt, w"ahrend \tty{PURECODE} - wie der Name schon erahnen l"a"st - auch die \tty{IF}-Konstrukte selber nicht mehr im Listing auff"uhrt. Diese Einstellungen sind n"utzlich, wenn man Makros, die anhand von Parametern verschiedene Aktionen ausf"uhren, benutzt, und im Listing nur noch die jeweils benutzten Teile sehen m"ochte. \par Die momentane Einstellung l"a"st sich aus dem Symbol \tty{LISTING} (0=\tty{OFF}, 1=\tty{ON}, 2=\tty{NOSKIPPED}, 3=\tty{PURECODE}) auslesen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PRTINIT und PRTEXIT} \ttindex{PRTINIT}\ttindex{PRTEXIT} Bei der Listingausgabe auf Druckern ist es oftmals sinnvoll, den Drucker in eine andere Betriebsart (z.B. Schmalschrift) umzuschalten und am Ende des Listings diese Betriebsart wieder zu deaktivieren. Mit diesen Befehlen kann die Ausgabe dieser Steuerfolgen automatisiert werden, indem man mit \begin{verbatim} PRTINIT \end{verbatim} die Zeichenfolge angibt, die vor Listingbeginn an das Ausgabeger"at geschickt werden soll und mit \begin{verbatim} PRTEXIT \end{verbatim} analog den Deinitialisierungsstring. In beiden F"allen mu"s \tty{$<$String$>$} ein Stringausdruck sein. Die Syntaxregeln f"ur Stringkonstanten erm"oglichen es, ohne Verrenkungen Steuerzeichen in den String einzubauen. \par Bei der Ausgabe dieser Strings unterscheidet der Assembler \bb{nicht}, wohin das Listing geschickt wird, d.h. Druckersteuerzeichen werden r"ucksichtslos auch auf den Bildschirm geschickt! \par Beispiel : \par Bei Epson-Druckern ist es sinnvoll, f"ur die breiten Listings in den Kompre"sdruck zu schalten. Die beiden Zeilen \begin{verbatim} PRTINIT "\15" PRTEXIT "\18" \end{verbatim} sorgen daf"ur, da"s der Kompre"sdruck ein- und nach dem Druck wieder ausgeschaltet wird. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{TITLE} \ttindex{TITLE} Normalerweise versieht der Assembler bereits jede Listingseite mit einer Titelzeile, die Quelldatei, Datum und Uhrzeit enth"alt. Mit diesem Befehl kann man den Seitenkopf um eine beliebige zus"atzliche Zeile erweitern. Der anzugebende String ist dabei ein beliebiger Stringausdruck. \par Beispiel: \par Bei dem bereits oben angesprochenenen Epson-Drucker soll eine Titelzeile im Breitdruck ausgegeben werden, wozu vorher der Kompre"smodus abgeschaltet werden mu"s: \begin{verbatim} TITLE "\18\14Breiter Titel\15" \end{verbatim} (Epson-Drucker schalten den Breitdruck automatisch am Zeilenende aus.) %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{RADIX} \ttindex{RADIX} \tty{RADIX} mit einem numerischen Argument zwischen 2 und 36 legt das Default-Zahlensystem f"ur Integer-Konstanten fest, d.h. das Zahlensystem, das angenommen wird, wenn man nichts ausdr"ucklich anderes angegeben hat. Defaultm"a"sig ist dies 10, und bei der Ver"anderung dieses Wertes sind einige Fallstricke zu beachten, die in Abschnitt \ref{SectIntConsts} beschrieben sind. Unabh"angig von der momentanen Einstellung ist das Argument von {\tt RADIX} {\em immer dezimal}; weiterhin d"urfen keine symbolischen oder Formelausdr"ucke verwendet werden, sondern nur einfache Zahlenkonstanten! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{OUTRADIX} \ttindex{OUTRADIX} \tty{OUTRADIX} is gewisserma"sen das Gegenst"uck zu \tty{RADIX}: Mit ihm kann man festlegen, in welchem Zahlensystem berechnete Integer-Ausdr"ucke in Strings eingesetzt werden sollen, wenn man \verb!\{...}!-Konstrukte in Stringkonstanten verwendet (siehe Abschnitt \ref{SectStringConsts}). Als Argument sind wieder Werte zwischen 2 und 36 erlaubt; der Default ist 16. %%--------------------------------------------------------------------------- \section{lokale Symbole} \label{ChapLocSyms} {\em G"ultigkeit: alle Prozessoren} Bei den lokalen Labels und den dazu eingef"uhrten Sektionen handelt es sich um eine grundlegend neue Funktion, die mit Version 1.39 eingef"uhrt wird. Da dieser Teil sozusagen ,,1.0'' ist, ist er sicherlich noch nicht der Weisheit letzter Schlu"s. Anregungen und (konstruktive) Kritik sind daher besonders erw"unscht. Insbesondere habe ich die Verwendung von Sektionen hier so dargestellt, wie ich sie mir vorstelle. Es kann dadurch passiert sein, da"s die Realit"at nicht ganz meinem Modell im Kopf entspricht. F"ur den Fall von Diskrepanzen verspreche ich, da"s die Realit"at der Dokumentation angepa"st wird, und nicht umgekehrt, wie es bei gr"o"seren Firmen schon einmal vorgekommen sein soll... \par AS erzeugt keinen linkf"ahigen Code (und wird es wohl auch nicht in n"aherer Zukunft tun \tty{:-(} ). Diese Tatsache zwingt dazu, ein Programm immer im ganzen zu "ubersetzen. Dieser Technik gegen"uber h"atte eine Aufteilung in Linker-Module einige Vorteile: \begin{itemize} \item{k"urzere "Ubersetzungszeiten, da lediglich die ge"anderten Module neu "ubersetzt werden m"ussen;} \item{die M"oglichkeit, durch Definition "offentlicher und privater Symbole definierte Schnittstellen zwischen den Modulen festzulegen;} \item{Durch die geringere L"ange der einzelnen Module reduziert sich die Anzahl der Symbole im einzelnen Modul, so da"s k"urzere und trotzdem eindeutige Symbolnamen benutzt werden k"onnen.} \end{itemize} Insbesondere der letzte Punkt hat mich pers"onlich immer etwas gest"ort: War ein Label-Name einmal am Anfang eines 2000 Zeilen langen Programmes benutzt, so durfte er nirgendwo wieder verwendet werden --- auch nicht am anderen Ende des Quelltextes, wo Routinen mit ganz anderem Kontext standen. Ich war dadurch gezwungen, zusammengesetzte Namen der Form \begin{verbatim} _ \end{verbatim} zu verwenden, die dann L"angen zwischen 15 und 25 Zeichen hatten und das Programm un"ubersichlich machten. Das im folgenden eingehender beschriebene Sektionen-Konzept sollte zumindest den beiden letzten genannten Punkten abhelfen. Es ist vollst"andig optional: Wollen Sie keine Sektionen verwenden, so lassen Sie es einfach bleiben und arbeiten weiter wie unter den "alteren AS-Versionen. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{Grunddefinition (SECTION/ENDSECTION)} Eine \ii{Sektion} stellt einen durch spezielle Befehle eingerahmten Teil des Assembler-Programmes dar und hat einen vom Programmierer festlegbaren, eindeutigen Namen: \begin{verbatim} ... ... SECTION ... ... ENDSECTION [Sektionsname] ... ... \end{verbatim} Der Name f"ur eine Sektion mu"s den Konventionen f"ur einen Symbolnamen entsprechen; da AS Sektions-und Symbolnamen in getrennten Tabellen speichert, darf ein Name sowohl f"ur ein Symbol als auch eine Sektion verwendet werden. Sektionsnamen m"ussen in dem Sinne eindeutig sein, da"s auf einer Ebene nicht zwei Sektionen den gleichen Namen haben d"urfen (was es mit den ,,Ebenen'' auf sich hat, erl"autere ich im n"achsten Abschnitt). Das Argument zu \tty{ENDSECTION} ist optional, es darf auch weggelassen werden; Falls es weggelassen wird, zeigt AS den Namen der Sektion an, der er das \tty{ENDSECTION} zugeordnet hat. Code in einer Sektion wird von AS genauso behandelt wie au"serhalb, lediglich mit drei entscheidenden Unterschieden: \begin{itemize} \item{Innerhalb der Sektion definierte Symbole (z.B. Labels, \tty{EQU}s...) werden mit einer von AS intern vergebenen, der Sektion zugeordneten Nummer versehen. Diese Symbole sind von Code au"serhalb der Sektion nicht ansprechbar (das l"a"st sich nat"urlich durch Pseudobefehle variieren, aber dazu sp"ater mehr).} \item{Durch das zus"atzliche Attribut kann ein Symbolname sowohl au"serhalb der Sektion als auch innerhalb definiert werden, das Attribut erlaubt also, Symbolnamen mehrfach zu benutzen, ohne da"s AS Protest anmeldet.} \item{Falls ein Symbol sowohl au"serhalb als auch innerhalb definiert ist, wird innerhalb der Sektion das ,,lokale'' verwendet, d.h. AS sucht in der Symboltabelle zuerst nach einem Symbol des gew"unschten Namens, das auch gleichzeitig der Sektion zugeordnet wurde. Erst danach wird nach einem globalen Symbol dieses Namens gefahndet.} \end{itemize} Mit diesem Mechanismus kann man z.B. den Code in Module aufteilen, wie man es mit einem Linker getan h"atte. Eine feinere Aufteilung w"are dagegen, alle Routinen in getrennte Sektionen zu verpacken. Je nach L"ange der Routinen k"onnen die nur intern ben"otigten Symbole dann sehr kurze Namen haben. \par Defaultm"a"sig unterscheidet AS Gro"s-und Kleinschreibung in Sektions- namen nicht; schaltet man jedoch in den case-sensitiven Modus um, so wird die Schreibweise genauso wie bei Symbolnamen ber"ucksichtigt. \par Die bisher beschriebene Aufteilung w"urde in etwa der Sprache C entsprechen, in der alle Funktionen auf gleicher Ebene nebeneinander stehen. Da mein ,,hochsprachliches'' Vorbild aber Pascal ist, bin ich noch einen Schritt weiter gegangen: %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{Verschachtelung und Sichtbarkeitsregeln} Es ist erlaubt, in einer Sektion weitere Sektionen zu definieren, analog zu der M"oglichkeit in Pascal, in einer Prozedur/Funktion weitere Prozeduren zu definieren. Dies zeigt folgendes Beispiel: \begin{verbatim} sym EQU 0 SECTION ModulA SECTION ProcA1 sym EQU 5 ENDSECTION ProcA1 SECTION ProcA2 sym EQU 10 ENDSECTION ProcA2 ENDSECTION ModulA SECTION ModulB sym EQU 15 SECTION ProcB ENDSECTION ProcB ENDSECTION ModulB \end{verbatim} Bei der Suche nach einem Symbol sucht AS zuerst ein Symbol, das der aktuellen Sektion zugeordnet ist, und geht danach die ganze ,,Liste'' der Vatersektionen durch, bis er bei den globalen Symbolen angekommen ist. Im Beispiel sehen die Sektionen die in Tabelle \ref{TabSymErg} angegebenen Werte f"ur das Symbol \tty{sym}. \begin{table*}[htb] \begin{center}\begin{tabular}{|l|l|l|} \hline Sektion & Wert & aus Sektion... \\ \hline \hline Global & 0 & Global \\ \hline \tty{ModulA} & 0 & Global \\ \hline \tty{ProcA1} & 5 & \tty{ProcA1} \\ \hline \tty{ProcA2} & 10 & \tty{ProcA2} \\ \hline \tty{ModulB} & 15 & \tty{ModulB} \\ \hline \tty{ProcB} & 15 & \tty{ModulB} \\ \hline \end{tabular}\end{center} \caption{F"ur die einzelnen Sektionen g"ultigen Werte\label{TabSymErg}} \end{table*} Diese Regel kann man durchbrechen, indem man explizit an den Symbolnamen die Sektion anh"angt, aus der man das Symbol holen will, und zwar in eckigen Klammern am Ende des Symbolnamens: \begin{verbatim} move.l #sym[ModulB],d0 \end{verbatim} Es d"urfen dabei nur Sektionsnamen verwendet werden, die eine Obersektion zur aktuellen Sektion darstellen. Als Sonderwert sind die Namen \tty{PARENT0..PARENT9} erlaubt, mit denen man die n-ten ,,Vatersektionen'' relativ zur momentanen Sektion ansprechen kann; \tty{PARENT0} entspricht also der momentanen Sektion selber, \tty{PARENT1} der direkt "ubergeordneten usw. Anstelle \tty{PARENT1} kann man auch kurz nur \tty{PARENT} schreiben. L"a"st man dagegen den Platz zwischen den Klammern komplett frei, also etwa so \begin{verbatim} move.l #sym[],d0 , \end{verbatim} so erreicht man das globale Symbol. \bb{ACHTUNG!} Wenn man explizit ein Symbol aus einer Sektion anspricht, so wird auch nur noch bei den Symbolen dieser Sektion gesucht, der Sektionsbaum wird nicht mehr bis nach oben durchgegangen! \par Analog zu Pascal ist es erlaubt, da"s verschiedene Sektionen Untersektionen gleichen Namens haben d"urfen, das Prinzip der Lokalit"at verhindert hier Irritationen. M.E. sollte man davon aber trotzdem sparsamen Gebrauch machen, da in Symbol-und Querverweisliste Symbole zwar mit der Sektion, in der sie definiert wurden, gekennzeichnet werden, aber nicht mit der "uber dieser Sektion evtl. liegenden ,,Sektionshierarchie'' (das h"atte einfach den Platz in der Zeile gesprengt); Unterscheidungen sind dadurch nicht erkennbar. \par Da ein \tty{SECTION}-Befehl von selber kein Label definiert, besteht hier ein wichtiger Unterschied zu Pascal: Eine Pascal-Prozedur kann ihre Unterprozeduren/funktionen automatisch ,,sehen'', unter AS mu"s man noch einen Einsprungpunkt extra definieren. Das kann man z.B. mit folgendem Makro-P"archen tun: \begin{verbatim} proc MACRO name SECTION name name LABEL $ ENDM endp MACRO name ENDSECTION name ENDM \end{verbatim} Diese Beispiel zeigt gleichzeitig, da"s die Lokalit"at von Labels in Makros nicht von den Sektionen beeinflu"st wird, deshalb der Trick mit dem \tty{LABEL}-Befehl. \par Nat"urlich ist mit dieser Definition das Problen noch nicht ganz gel"ost, bisher ist das Einsprung-Label ja noch lokal und von au"sen nicht zu erreichen. Wer nun meint, man h"atte das Label einfach nur vor der SECTION-Anweisung plazieren m"ussen, sei jetzt bitte ruhig, denn er verdirbt mir den "Ubergang auf das n"achste Thema: %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{PUBLIC und GLOBAL} Die \tty{PUBLIC}-Anweisung erlaubt es, die Zugeh"origkeit eines Symbols zu einer bestimmten Sektion zu ver"andern. Es ist m"oglich, mit einem \tty{PUBLIC}-Befehl mehrere Symbole zu bearbeiten, ohne Beschr"ankung der Allgemeinheit will ich aber ein Beispiel mit nur einer Variable verwenden: Im einfachsten Falle erkl"art man ein Symbol als vollst"andig global, d.h. es ist von allen Stellen des Programmes ansprechbar: \begin{verbatim} PUBLIC \end{verbatim} Da ein Symbol bei seiner Definition endg"ultig in der Symboltabelle einsortiert wird, mu"s diese Anweisung \bb{vor} der Definition des Symbols erfolgen. Alle \tty{PUBLIC}s werden von AS in einer Liste vermerkt und bei ihrer Definition aus dieser Liste wieder entfernt. Bei Beendigung einer Sektion gibt AS Fehlermeldungen f"ur alle nicht aufgel"osten ,,Vorw"artsreferenzen'' aus. \par Angesichts des hierarchischen Sektionenkonzepts erscheint die Methode, ein Symbol als vollst"andig global zu definieren, reichlich brachial. Es geht aber auch etwas differenzierter, indem man zus"atzlich einen Sektionsnamen angibt: \begin{verbatim} PUBLIC : \end{verbatim} Damit wird das Symbol der genannten Sektion zugeordnet und damit auch allen ihren Untersektionen zug"anglich (es sei denn, diese definieren wiederum ein Symbol gleichen Namens, das dann das ,,globalere'' "ubersteuert). Naturgem"a"s protestiert AS, falls mehrere Untersektionen ein Symbol gleichen Namens auf die gleiche Ebene exportieren wollen. Als Spezialwert f"ur \tty{$<$Sektion$>$} sind die im vorigen Abschnitt genannten \tty{PARENTx}-Namen zugelassen, um das Symbol genau n Ebenen hinaufzuexportieren. Es sind als Sektionen nur der momentanen Sektion "ubergeordnete Sektionen zugelassen, also keine, die im Baum aller Sektionen in einem anderen Zweig stehen. Sollten dabei mehrere Sektionen den gleichen Namen haben (dies ist legal), so wird die tiefste gew"ahlt. \par Mit diesem Werkzeug kann das obige Prozedurmakro nun Sinn ergeben: \begin{verbatim} proc MACRO name SECTION name PUBLIC name:PARENT name LABEL $ ENDM \end{verbatim} Diese Einstellung entspricht dem Modell von Pascal, in der eine Unterprozedur auch nur von ihrem ,,Vater'' gesehen werden kann, jedoch nicht vom ,,Gro"svater''. \par Falls mehrere Untersektionen versuchen, ein Symbol gleichen Namens in die gleiche Obersektion zu exportieren, meckert AS "uber doppelt definierte Symbole, was an sich ja korrekt ist. War das gewollt, so mu"s man die Symbole in irgendeiner Weise ,,qualifizieren'', damit sie voneinander unterschieden werden k"onnen. Dies ist mit der \tty{GLOBAL}-Anweisung m"oglich. Die Syntax von \tty{GLOBAL} ist der von \tty{PUBLIC} identisch, das Symbol bleibt aber lokal, anstatt einer h"oheren Sektion zugeordnet zu werden. Stattdessen wird ein weiteres Symbol gleichen Werts erzeugt, dem jedoch der Untersektionsname mit einem Unterstrich vorangestellt wird, und nur dieses Symbol wird der Sektionsangabe entsprechend "offentlich gemacht. Definieren z.B. zwei Sektionen \tty{A} und \tty{B} ein Symbol \tty{SYM} und exportieren es mit \tty{GLOBAL} zu ihrer Vatersektion, so werden dort die Symbole unter den Namen \tty{A\_SYM} und \tty{B\_SYM} eingeordnet. \par Falls zwischen Quell- und Zielsektion mehrere Stufen stehen sollten, so wird entsprechend der komplette Namenszweig von der Ziel- bis zur Quellsektion dem Symbolnamen vorangestellt. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{FORWARD} So sch"on das bisher besprochene Modell ist, ein bei Pascal nicht auftauchendes Detail macht "Arger: die bei Assembler m"oglichen Vorw"artsreferenzen. Bei Vorw"artsreferenzen kann es sein, da"s AS im ersten Pass auf ein Symbol einer h"oheren Sektion zugreift. Dies ist an sich nicht weiter tragisch, solange im zweiten Pass das richtige Symbol genommen wird, es k"onnen aber Unf"alle der folgenden Art passieren: \begin{verbatim} loop: . .. SECTION sub .. ; *** bra.s loop .. loop: .. ENDSECTION .. jmp loop ; Hauptschleife \end{verbatim} AS wird im ersten Pass das globale Label \tty{loop} verwenden, sofern das Programmst"uck bei \tty{$<$Code$>$} hinreichend lang ist, wird er sich "uber eine zu gro"se Sprungdistanz beklagen und den zweiten Pass erst gar nicht versuchen. Um die Uneindeutigkeit zu vermeiden, kann man den Symbolnamen mit einem expliziten Bezug versehen: \begin{verbatim} bra.s loop[sub] \end{verbatim} Falls ein lokales Symbol h"aufig referenziert wird, k"onnen die vielen Klammern mit dem \tty{FORWARD}-Befehl eingespart werden. Das Symbol wird damit explizit als lokal angek"undigt. AS wird dann bei Zugriffen auf dieses Symbol automatisch nur im lokalen Symbolbereich suchen. In diesem Falle m"u"ste an der mit \tty{***} gekennzeichneten Stelle daf"ur der Befehl \begin{verbatim} FORWARD loop \end{verbatim} stehen. Damit \tty{FORWARD} Sinn macht, mu"s es nicht nur vor der Definition des Symbols, sondern vor seiner ersten Benutzung in der Sektion gegeben werden. Ein Symbol gleichzeitig privat und "offentlich zu definieren, ergibt keinen Sinn und wird von AS auch angemahnt. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{Geschwindigkeitsaspekte} Die mehrstufige Suche in der Symboltabelle und die Entscheidung, mit welchem Attribut ein Symbol eingetragen werden soll, kosten naturgem"a"s etwas Rechenzeit. Ein 1800 Zeilen langes 8086-Programm z.B. wurde nach der Umstellung auf Sektionen statt in 33 in 34,5 Sekunden assembliert (80386 SX, 16MHz, 3 Durchg"ange). Der Overhead h"alt sich also in Grenzen: Ob man ihn in Kauf nehmen will, ist (wie am Anfang erw"ahnt) eine Frage des Geschmacks; man kann AS genauso gut ohne Sektionen verwenden. %%--------------------------------------------------------------------------- \section{Diverses} %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{SHARED} \label{ChapShareOrder} \ttindex{SHARED} {\em G"ultigkeit: alle Prozessoren} Mit diesem Befehl weist man den AS an, die in der Parameterliste angegebenen Symbole (egal ob Integer, Gleitkomma oder String) im Sharefile mit ihren Werten abzulegen. Ob eine solche Datei "uberhaupt und in welchem Format erzeugt wird, h"angt von den in \ref{SectCallConvention} beschriebenen Kommandozeilenschaltern ab. Findet AS diesen Befehl und es wird keine Datei erzeugt, f"uhrt das zu einer Warnung. \par \bb{VORSICHT!} Ein eventuell der Befehlszeile anh"angender Kommentar wird in die erste, ausgegebene Zeile mit "ubertragen (sofern die Argumentliste von \tty{SHARED} leer ist, wird nur der Kommentar ausgegeben). Falls die Share-Datei f"ur C oder Pascal erzeugt wird, sind einen C/Pascal-Kommentar schlie"sende Zeichenfolgen (\verb!*/! bzw. \verb!*)!) im Kommentar zu vermeiden. AS pr"uft dies \ii{nicht}! %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{INCLUDE} \ttindex{INCLUDE}\label{SectInclude} {\em G"ultigkeit: alle Prozessoren} Dieser Befehl f"ugt die im Parameter angegebene Datei (die optional in G"an\-se\-f"u"s\-chen eingeschlossen sein darf) so im Text ein, als ob sie dort stehen w"urde. Dieser Befehl ist sinnvoll, um Quelldateien aufzuspalten, die alleine nicht in den Speicher passen w"urden oder um sich ''Toolboxen'' zu erzeugen. \par Falls der angegebene Dateiname keine Endung hat, wird er automatisch um die Endung \tty{INC} erweitert. \par Mit der Kommandozeilenoption \begin{verbatim} -i \end{verbatim} l"a"st sich eine Liste von Verzeichnissen angeben, in denen automatisch zus"atzlich nach der Includedatei gesucht werden soll. Wird die Datei nicht gefunden, so ist dies ein \ii{fataler} Fehler, d.h. der Assembler bricht sofort ab. \par Aus Kompatibilit"atsgr"unden ist es erlaubt, den Namen in G"ansef"u"schen zu schreiben, \begin{verbatim} INCLUDE stddef51 \end{verbatim} und \begin{verbatim} INCLUDE "stddef51.inc" \end{verbatim} sind also "aquivalent. \bb{ACHTUNG!} Wegen dieser Wahlfreiheit ist hier nur eine Stringkonstante, aber kein Stringausdruck zul"assig! \par Sollte der Dateiname eine Pfadangabe enthalten, so wird die Suchliste ignoriert. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{BINCLUDE} \ttindex{BINCLUDE} {\em G"ultigkeit: alle Prozessoren} \tty{BINCLUDE} dient dazu, in den von AS erzeugten Code Bin"ardaten einzubetten, die von einem anderen Programm erzeugt wurden (das kann nat"urlich theoretisch auch von AS selber erzeugter Code sein...). \tty{BINCLUDE} hat drei Formen: \begin{verbatim} BINCLUDE \end{verbatim} In dieser Form wird die Datei komplett eingebunden. \begin{verbatim} BINCLUDE , \end{verbatim} In dieser Form wird der Inhalt der Datei ab \verb!! bis zum Ende der Datei eingebunden. \begin{verbatim} BINCLUDE ,, \end{verbatim} In dieser Form werden \verb!! Bytes ab Offset \verb!! eingebunden. \par Es gelten die gleichen Regeln bez"uglich Suchpfaden wie bei \tty{INCLUDE}. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{MESSAGE, WARNING, ERROR und FATAL} \ttindex{MESSAGE}\ttindex{WARNING}\ttindex{ERROR}\ttindex{FATAL} {\em G"ultigkeit: alle Prozessoren} Der Assembler pr"uft zwar die Quelltexte so streng wie m"oglich und liefert diffenzierte Fehlermeldungen, je nach Anwendung kann es aber sinnvoll sein, unter bestimmten Bedingungen zus"atzliche Fehlermeldungen auszul"osen, mit denen sich logische Fehler automatisch pr"ufen lassen. Der Assembler unterscheidet drei Typen von Fehlermeldungen, die "uber die drei Befehle auch dem Programmierer zug"anglich sind: \begin{itemize} \item{\tty{WARNING}: Fehler, die auf m"oglicherweise falschen oder ineffizienten Code hinweisen. Die Assemblierung l"auft weiter, eine Codedatei wird erzeugt.} \item{\tty{ERROR}: echte Fehler im Programm. Die Assemblierung l"auft weiter, um m"ogliche weitere Fehler in einem Durchgang entdecken und korrigieren zu k"onnen. Eine Codedatei wird nicht erzeugt.} \item{\tty{FATAL}: schwerwiegende Fehler, die einen sofortigen Abbruch des Assemblers bedingen. Eine Codedatei kann m"oglicherweise entstehen, ist aber unvollst"andig.} \end{itemize} Allen drei Befehlen ist das Format gemeinsam, in dem die Fehlermeldung angegeben werden mu"s: Ein beliebig (berechneter?!) Stringausdruck, der damit sowohl eine Konstante als auch variabel sein darf. \par Diese Anweisungen ergeben nur in Zusammenhang mit bedingter Assemblierung Sinn. Ist f"ur ein Programm z.B. nur ein begrenzter Adre"sraum vorhanden, so kann man den "Uberlauf folgenderma"sen testen: \begin{verbatim} ROMSize equ 8000h ; 27256-EPROM ProgStart: .. .. ProgEnd: if ProgEnd-ProgStart>ROMSize error "\aDas Programm ist zu lang!" endif \end{verbatim} Neben diesen fehlererzeugenden Befehlen gibt es noch den Befehl \tty{MESSAGE}, der einfach nur eine Meldung auf der Konsole bzw. im Listing erzeugt. Seine Benutzung ist den anderen drei Befehlen gleich. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{READ} \ttindex{READ} {\em G"ultigkeit: alle Prozessoren} \tty{READ} ist sozusagen das Gegenst"uck zu der vorigen Befehlsgruppe: mit ihm ist es m"oglich, \ii{w"ahrend} der Assemblierung Werte von der Tastatur einzulesen. Wozu das gut sein soll? Um das darzulegen, soll hier ausnahmsweise einmal das Beispiel vor die genauere Erl"auterung gezogen werden: \par Ein Programm ben"otigt zum Datentransfer einen Puffer mit einer zur "Ubersetzungszeit festzulegenden Gr"o"se. Um die Gr"o"se des Puffers festzulegen, k"onnte man sie einmal mit \tty{EQU} in einem Symbol ablegen, es geht aber auch interaktiv mit \tty{READ} : \begin{verbatim} IF MomPass=1 READ "Puffer (Bytes)",BufferSize ENDIF \end{verbatim} Auf diese Weise k"onnen Programme sich w"ahrend der "Ubersetzung interaktiv konfigurieren, man kann sein Programm z.B. jemandem geben, der es mit seinen Parametern "ubersetzen kann, ohne im Quellcode ,,herumstochern'' zu m"ussen. Die im Beispiel gezeigte \tty{IF-} Abfrage sollte "ubrigens immer verwendet werden, damit der Anwender nur einmal mit der Abfrage bel"astigt wird. \par \tty{READ} "ahnelt sehr stark dem \tty{SET-} Befehl, nur da"s der dem Symbol zuzuweisende Wert nicht rechts vom Schl"usselwort steht, sondern von der Tastatur eingelesen wird. Dies bedeutet z.B. auch, da"s AS anhand der Eingabe automatisch festlegt, ob es sich um eine Integer- oder Gleitkommazahl oder einen String handelt und anstelle einzelner Konstanten auch ganze Formelausdr"ucke eingegeben werden k"onnen. \par \tty{READ} darf entweder nur einen Parameter oder zwei Parameter haben, denn die Meldung zur Eingabeaufforderung ist optional. Fehlt sie, so gibt AS eine aus dem Symbolnamen konstruierte Meldung aus. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{RELAXED} \label{SectRELAXED} \ttindex{RELAXED} {\em G"ultigkeit: alle Prozessoren} Defaultm"a"sig ist einer Prozessorfamilie eine bestimmte Schreibweise von Integer-Konstanten zugeordnet (die i.a. der Herstellervorgabe entspricht, solange der nicht eine allzu abgefahrene Syntax benutzt...). Nun hat aber jeder seine pers"onlichen Vorlieben f"ur die eine oder andere Schreibweise und kann gut damit leben, da"s sich seine Programme nicht mehr mit dem Standard-Assembler "ubersetzen lassen. Setzt man ein \begin{verbatim} RELAXED ON \end{verbatim} an den Programmanfang, so kann man fortan alle Schreibweisen beliebig gemischt und durcheinander verwenden; bei jedem Ausdruck versucht AS automatisch zu ermitteln, welche Schreibweise verwendet wurde. Da"s diese Automatik nicht immer das Ergebnis liefert, das man sich vorgestellt hat, ist auch der Grund, weshalb diese Option explizit eingeschaltet werden mu"s (und man sich davor h"uten sollte, sie einfach in einem existierenden Programm dazuzusetzen): Ist nicht durch vor- oder nachgestellte Zeichen zu erkennen, da"s es sich um Intel- oder Motorola-Konstanten handelt, wird im C-Modus gearbeitet. Eventuell vorangestellte, eigentlich "uberfl"ussige Nullen haben in diesem Modus durchaus eine Bedeutung: \begin{verbatim} move.b #08,d0 \end{verbatim} Diese Konstante w"urde als Oktalkonstante verstanden werden, und weil Oktalzahlen nur Ziffern von 0..7 enthalten k"onnen, f"uhrt das zu einem Fehler. Dabei h"atte man in diesem Fall noch Gl"uck gehabt, bei der Zahl \tty{077} z.B. h"atte man ohne Meldung Probleme bekommen. Ohne \tty{RELAXED}-Modus w"are in beiden F"allen klar gewesen, da"s es sich um dezimale Konstanten handelt. \par Die momentane Einstellung kann aus dem gleichnamigen Symbol ausgelesen werden. %%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \subsection{END} \ttindex{END} {\em G"ultigkeit: alle Prozessoren} \tty{END} kennzeichnet das Ende des Assemblerprogrammes. Danach noch in der Quelldatei stehende Zeilen werden ignoriert. \bb{WICHTIG:} \tty{END} darf zwar aus einem Makro heraus aufgerufen werden, der Stapel der bedingten Assemblierung wird aber nicht automatisch abger"aumt. Das folgende Konstrukt f"uhrt daher zu einer Fehlermeldung: \begin{verbatim} IF KeineLustMehr END ENDIF \end{verbatim} Optional darf \tty{END} auch einen Integer-Ausdruck als Argument haben, der den Startpunkt des Programmes vermerkt. Dieser wird von AS in einem speziellen Record der Datei vermerkt und kann z.B. von P2HEX weiterverarbeitet werden. \par \tty{END} war eigentlich schon immer in AS definiert, nur war es bei fr"uheren Versionen von AS aus Kompatibilit"at zu anderen Assemblern vorhanden und hatte keine Wirkung. %%=========================================================================== \cleardoublepage \chapter{Prozessorspezifische Hinweise} Ich habe mich bem"uht, die einzelnen Codegeneratoren m"oglichst kompatibel zu den Originalassemblern zu halten, jedoch nur soweit, wie es keinen unvertretbaren Mehraufwand bedeutete. Wichtige Unterschiede, Details und Fallstricke habe ich im folgenden aufgelistet. %%--------------------------------------------------------------------------- \section{6811} ,,Wo gibt es denn das zu kaufen, den HC11 in NMOS?'', fragt jetzt vielleicht der eine oder andere. Gibt es nat"urlich nicht, aber ein H l"a"st sich nun einmal nicht in einer Hexzahl darstellen ("altere Versionen von AS h"atten solche Namen deswegen nicht akzeptiert), und dann habe ich die Buchstaben gleich ganz weggelassen... \par \begin{quote}{\it ,,Jemand, der sagt, etwas sei unm"oglich,sollte wenigstens so kooperativ sein, denjenigen, der es gerade tut, nicht am Arbeiten zu hindern.'' }\end{quote} Ab und zu ist man gezwungen, seine Meinung zu revidieren. Vor einigen Versionen hatte ich an dieser Stelle noch behauptet, ich k"onne es im Parser von AS nicht realisieren, da"s man die Argumente von \tty{BSET/BCLR} bzw. \tty{BRSET/BRCLR} auch mit Leerzeichen trennen kann. Offensichtlich kann selbiger aber mehr, als ich vermutet habe...nach der soundsovielten Anfrage habe ich mich noch einmal drangesetzt, und jetzt scheint es zu laufen. Man darf sowohl Leerzeichen als auch Kommas verwenden, aber nicht in allen Varianten, um es nicht uneindeutig zu machen: Es gibt zu jeder Befehlsvariante zwei M"oglichkeiten; eine, die nur Kommas verwendet, sowie eine, wie sie von Motorola wohl definiert wurde (leider sind die Datenb"ucher nicht immer so gut wie die zugeh"orige Hardware...): \begin{verbatim} Bxxx abs8 #mask entspricht Bxxx abs8,#mask Bxxx disp8,X #mask entspricht Bxxx disp8,X,#mask BRxxx abs8 #mask adr entspricht BRxxx abs8,#mask,adr BRxxx disp8,X #mask adr entspricht BRxxx disp8,X,#mask,adr \end{verbatim} Dabei steht \tty{xxx} entweder f"ur \tty{SET} oder \tty{CLR} und \tty{\#mask} f"ur die zu verwendende Bitmaske; der Lattenzaun ist dabei optional. Anstelle des X-Registers darf nat"urlich auch Y verwendet werden. %%--------------------------------------------------------------------------- \section{PowerPC} Sicher hat es ein bi"schen den Anflug einer Schnapsidee, einen Prozessor, der eher f"ur den Einsatz in Workstations konzipiert wurde, in AS einzubauen, der sich ja eher an Programmierer von Einplatinencomputern wendet. Aber was heute noch das Hei"seste vom Hei"sen ist, ist es morgen schon nicht mehr, und sowohl der Z80 als auch der 8088 haben ja inzwischen die Mutation von der Personal Computer-CPU zum sog. ,,Mikrocontroller'' vollzogen. Mit dem Erscheinen von MPC505 und PPC403 hat sich die Vermutung dann auch best"atigt, da"s IBM und Motorola diese Prozessorserie auf allen Ebenen durchdr"ucken wollen. \par Die Unterst"utzung ist momentan noch nicht vollst"andig: Als Pseudobefehle zur Datenablage werden momentan provisorisch die Intel-Mnemonics unterst"utzt und es fehlen die etwas ungew"ohnlicheren, in \cite{Mot601} genannten RS6000-Befehle (die aber hoffentlich keiner vermi"st...). Das wird aber nachgeholt, sobald Informationen verf"ugbar sind! %%--------------------------------------------------------------------------- \section{DSP56xxx} Motorola, was ist nur in Dich gefahren! Wer bei Dir ist nur auf das schmale Brett gekommen, die einzelnen parallelen Datentransfers ausgerechnet durch Leerzeichen zu trennen! Wer immer nun seine Codes etwas "ubersichtlicher formatieren will, z.B. so: \begin{verbatim} move x:var9 ,r0 move y:var10,r3 , \end{verbatim} der ist gekniffen, weil das Leerzeichen als Trennung paralleler Datentransfers erkannt wird! \par Sei's drum; Motorola hat es so definiert, und ich kann es nicht "andern. Als Trennung der Operationen sind statt Leerzeichen auch Tabulatoren zugelassen, und die einzelnen Teile sind ja wieder ganz normal mit Kommas getrennt. \par In \cite{Mot56} steht, da"s bei den Befehlen \tty{MOVEC, MOVEM, ANDI} und \tty{ORI} auch die allgemeineren Mnemonics \tty{MOVE, AND} und \tty{OR} verwendet werden k"onnen. Bei AS geht das (noch) nicht. %%--------------------------------------------------------------------------- \section{H8/300} Bei der Assemblersyntax dieser Prozessoren hat Hitachi reichlich bei Motorola abgekupfert (was so verkehrt ja nun auch nicht war...), nur leider wollte die Firma unbedingt ihr eigenes Format f"ur Hexadezimalzahlen einf"uhren, und dazu noch eines, das "ahnlich wie bei Microchip Hochkommas verwendet. Das konnte (und wollte) ich bei AS nicht nachvollziehen, bei dem Hochkommas zur Einrahmung von ASCII-Sequenzen benutzt werden. Anstelledessen werden Zahlen in der "ublichen Motorola-Syntax geschrieben, d.h. mit einem Dollarzeichen. %%--------------------------------------------------------------------------- \section{SH7000/7600/7700} Leider hat Hitachi auch hier wieder das Extrawurst-Format f"ur Hexadezimalzahlen verwendet, und wieder habe ich in AS das nicht nachvollzogen...bitte Motorola-Syntax benutzen! \par Bei der Verwendung von Literalen und dem \tty{LTORG}-Befehl sind einige Details zu beachten, wenn man nicht auf einmal mit eigenartigen Fehlermeldungen konfrontiert werden will: \par Literale existieren, weil der Prozessor nicht in der Lage ist, Konstanten au"serhalb des Bereiches von -128 bis 127 mit immediate-Adressierung zu laden. AS (und der Hitachi-Assembler) verstecken diese Unzul"anglichkeit, indem sie automatisch entsprechende Konstanten im Speicher ablegen, die dann mittels PC-relativer Adressierung angesprochen werden. Die Frage, die sich nun erhebt, ist die, wo diese Konstanten im Speicher abgelegt werden sollen. AS legt sie nicht sofort ab, sondern sammelt sie so lange auf, bis im Programm eine \tty{LTORG}-Anweisung auftritt. Dort werden alle Konstanten abgelegt, wobei deren Adressen mit ganz normalen Labels versehen werden, die man auch in der Symboltabelle sehen kann. Ein Label hat die Form \begin{verbatim} LITERAL_s_xxxx_n . \end{verbatim} Dabei repr"asentiert \tty{s} den Typ des Literals. Unterschieden werden Literale, die 16-Bit-Konstanten (\tty{s=W}), 32-Bit-Konstanten (\tty{s=L}) oder Vorw"artsreferenzen, bei denen AS die Operandengr"o"se nicht im voraus erkennen kann (\tty{s=F}), enthalten. F"ur \tty{W} oder \tty{L} bedeutet \tty{xxxx} den hexadezimal geschriebenen Wert der Konstante, bei Vorw"artsreferenzen, bei denen man den Literalwert ja noch nicht kennt, bezeichnet \tty{xxxx} eine einfache Durchnumerierung. \tty{n} kennzeichnet das wievielte Auftreten dieses Literals in dieser Sektion. Literale machen ganz normal die Lokalisierung durch Sektionen mit, es ist daher zwingend erforderlich, in einer Sektion entstandene Literale mit \tty{LTORG} auch dort abzulegen! \par Die Durchnumerierung mit \tty{n} ist erforderlich, weil ein Literal in einer Sektion mehrfach auftreten kann. Dies ist einmal bedingt dadurch, da"s die PC-relative Adressierung nur positive Displacements erlaubt, einmal mit \tty{LTORG} abgelegte Literale also im folgenden Code nicht mitbenutzt werden k"onnen, andererseits auch, weil die Reichweite der Displacements beschr"ankt ist (512 bzw. 1024 Byte). Ein automatisches \tty{LTORG} am Ende des Programmes oder beim Umschalten zu einer anderen CPU erfolgt nicht; findet AS in einer solchen Situation noch abzulegende Literale, so wird eine Fehlermeldung ausgegeben. \par Da bei der PC-relativen Adressierung der zur Adressierung herangezogene PC-Wert der Instruktionsadresse+4 entspricht, ist es nicht m"oglich, ein Literal zu benutzen, welches direkt hinter dem betroffenen Befehl abgelegt wird, also z.B. so: \begin{verbatim} mov #$1234,r6 ltorg \end{verbatim} Da der Prozessor dann aber sowieso versuchen w"urde, Daten als Code auszuf"uhren, sollte diese Situation in realen Programmen nicht auftreten. Wesentlich realer ist aber ein anderer Fallstrick: Wird hinter einem verz"ogerten Sprung PC-relativ zugegriffen, so ist der Programmz"ahler bereits auf die Sprungzieladresse gesetzt, und das Displacement wird relativ zum Sprungziel+2 berechnet. Im folgenden Beispiel kann daher das Literal nicht erreicht werden: \begin{verbatim} bra Target mov #$12345678,r4 ; wird noch ausgefuehrt . . ltorg ; hier liegt das Literal . . Target: mov r4,r7 ; hier geht es weiter \end{verbatim} Da Target+2 hinter dem Literal liegt, w"urde sich ein negatives Displacement ergeben. Besonders haarig wird es, wenn mit den Befehlen \tty{JMP, JSR, BRAF} oder \tty{BSRF} verzweigt wird: Da AS die Zieladresse hier nicht ermitteln kann (sie ergibt sich erst zur Laufzeit aus dem Registerinhalt), nimmt AS hier eine Adresse an, die nach M"oglichkeit nie pa"st, so da"s PC-relative Adressierung g"anzlich unm"oglich wird. \par Es ist nicht direkt m"oglich, aus der Zahl und Gr"o"se der Literale auf den belegten Speicher zu schlie"sen. U.u. mu"s AS ein F"ullwort einbauen, um einen Langwort-Wert auf eine durch 4 teilbare Adresse auszurichten, andererseits kann er m"oglicherweise Teile eines 32-bittigen Literals f"ur 16-Bit-Literale mitbenutzten. Mehrfach auftretende Literale erzeugen nat"urlich nur einen Eintrag. Solche Optimierungen werden f"ur Vorw"artsreferenzen allerdings ganz unterdr"uckt, da AS den Wert dieser Literale noch nicht kennt. \par Da Literale die PC-relative Adressierung ausnutzen, die nur beim \tty{MOV}-Befehl erlaubt sind, beschr"anken sich Literale ebenfalls auf die Verwendung in \tty{MOV}. Etwas trickreich ist hier die Art und Weise, in der AS die Operandengr"o"se auswertet. Eine Angabe von Byte oder Wort bedeutet, da"s AS einen m"oglichst kurzen \tty{MOV}-Befehl erzeugt, der den angegebenen Wert in den unteren 8 oder 16 Bit erzeugt, d.h. die oberen 24 oder 16 Bit werden als don't care behandelt. Gibt man dagegen Langwort oder gar nichts an, so sagt dies aus, da"s das komplette 32-Bit-Register den angegebenen Wert enthalten soll. Das hat z.B. den Effekt, da"s in folgendem Beispiel \begin{verbatim} mov.b #$c0,r0 mov.w #$c0,r0 mov.l #$c0,r0 \end{verbatim} der erste Befehl echte immediate-Adressierung erzeugt, der zweite und dritte jedoch ein Wort-Literal benutzen: Da das Bit 7 in der Zahl gesetzt ist, erzeugt der Byte-Befehl effektiv \$FFFFFFC0 im Register, was nach der Konvention nicht das w"are, was man im zweiten und dritten Fall haben m"ochte. Im dritten Fall reicht auch ein Wort-Literal, weil das gel"oschte Bit 15 des Operanden vom Prozessor in Bit 16..31 fortgesetzt wird. \par Wie man sieht, ist dieses ganze Literal-Konzept reichlich kompliziert; einfacher ging's aber wirklich nicht. Es liegt leider in der Natur der Sache, da"s man manchmal Fehlermeldungen "uber nicht gefundene Literale bekommt, die eigentlich logisch nicht auftreten k"onnten, weil AS die Literale ja komplett in eigener Regie verwaltet. Treten aber bei der Assemblierung Fehler erst im zweiten Pass auf, so verschieben sich z.B. hinter der Fehlerstelle liegende Labels gegen"uber dem ersten Pass, weil AS f"ur die jetzt als fehlerhaft erkannten Befehle keinen Code mehr erzeugt. Da aber Literalnamen u.a. aus den Werten von Symbolen erzeugt werden, werden als Folgefehler davon eventuell andere Literalnamen nachgefragt, als im ersten Pass abgelegt wurden und AS beschwert sich "uber nicht gefundene Symbole...sollten also neben anderen Fehlern solche Literal-Fehler auftreten, beseitigen Sie erst die anderen Fehler, bevor Sie mich und alle Literale verfluchen... \par Wer aus der Motorola-Ecke kommt und PC-relative Adressierung explizit benutzen will (z.B. um Variablen lageunabh"angig zu erreichen), sollte wissen, da"s beim Ausschreiben der Adressierung nach Programmierhandbuch, also z.B. so: \begin{verbatim} mov.l @(Var,PC),r8 \end{verbatim} {\it keine} implizite Umrechnung der Adresse auf ein Displacement erfolgt, d.h. der Operand wird so eingesetzt, wie er ist (und w"urde in diesen Beispiel wohl mit hoher Wahrscheinlichkeit eine Fehlermeldung hervorrufen...). Will man beim SH7x00 PC-relativ adressieren, so tut man das einfach mit ,,absoluter'' Adressierung, die auf Maschinenebene ja gar nicht existiert: \begin{verbatim} mov.l Var,r8 \end{verbatim} Hier wird das Displacement korrekt berechnet (es gelten nat"urlich die gleichen Einschr"ankungen f"ur das Displacement wie bei Literalen). %%--------------------------------------------------------------------------- \section{MELPS-4500} Der Programmspeicher dieser Mikrokontroller ist in Seiten zu 128 Worten eingeteilt. Diese Einteilung existiert eigentlich nur deswegen, weil es Sprungbefehle gibt, deren Ziel innerhalb der gleichen Seite liegen darf, und andererseits ,,lange'' Exemplare, die den ganzen Adre"sbereich erreichen k"onnen. Die Standard-Syntax von Mitsubishi verlangt eigentlich, da"s Seite und Offset als getrennte Argument geschrieben werden m"ussen. Da das aber reichlich unpraktisch ist (ansonsten hat man als Programmierer keine Veranlassung, sich um Seiten zu k"ummern, mit der Ausnahme von indirekten Spr"ungen), erlaubt es AS auch wahlweise, die Zieladresse linear zu schreiben, also z.B. \begin{verbatim} bl $1234 \end{verbatim} anstelle \begin{verbatim} bl $24,$34 . \end{verbatim} %%--------------------------------------------------------------------------- \section{6502UNDOC} Da die undokumentierten Befehle des 6502 sich naturgem"a"s in keinem Datenbuch finden, sollen sie an dieser Stelle kurz aufgelistet werden. Die Verwendung erfolgt naturgem"a"s auf eigene Gefahr, da es keine Gew"ahr gibt, da"s alle Maskenversionen alle Varianten unterst"utzen! Bei den CMOS-Nachfolgern des 6502 funktionieren sie sowieso nicht mehr, da diese die ensprechenden Bitkombinationen mit offiziellen Befehlen belegen... %%TEMP \clearpage Es bedeuten: \begin{tabbing} \hspace{2cm} \= \kill \\ \& \> bin"ares UND \\ | \> bin"ares ODER \\ \verb!^! \> bin"ares EXOR \\ $<<$ \> logischer Linksshift \\ $>>$ \> logischer Rechtsshift \\ $<<<$ \> Linksrotation \\ $>>>$ \> Rechtsrotation \\ $\leftarrow$ \> Zuweisung \\ (..) \> Inhalt von .. \\ {..} \> Bits .. \\ A \> Akkumulator \\ X,Y \> Indexregister X,Y \\ S \> Stapelzeiger \\ An \> Akkumulatorbit n \\ M \> Operand \\ C \> Carry \\ PCH \> obere H"alfte Programmz"ahler \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{JAM, KIL} oder \tty{CRS} \\ Funktion \> : \> keine, Prozessor wird angehalten \\ Adressierungsmodi \> : \> implizit \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SLO} \\ Funktion \> : \> $M\leftarrow((M)<<1)|(A)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{ANC} \\ Funktion \> : \> $A\leftarrow(A)\&(M), C\leftarrow A7$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{RLA} \\ Funktion \> : \> $M\leftarrow((M)<<1)\&(A)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SRE} \\ Funktion \> : \> $M\leftarrow((M)>>1)$\verb!^!$(A)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{ASR} \\ Funktion \> : \> $A\leftarrow((A)\&(M))>>1$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{RRA} \\ Funktion \> : \> $M\leftarrow((M)>>>1)+(A)+(C)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{ARR} \\ Funktion \> : \> $A\leftarrow((A)\&(M))>>>1$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SAX} \\ Funktion \> : \> $M\leftarrow(A)\&(X)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, Y-indiziert kurz, \\ \> \> Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{ANE} \\ Funktion \> : \> $M\leftarrow((A)\&\$ee)|((X)\&(M))$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SHA} \\ Funktion \> : \> $M\leftarrow(A)\&(X)\&(PCH+1)$ \\ Adressierungsmodi \> : \> X/Y-indiziert lang \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SHS} \\ Funktion \> : \> $X\leftarrow(A)\&(X), S\leftarrow(X), M\leftarrow(X)\&(PCH+1)$ \\ Adressierungsmodi \> : \> Y-indiziert lang \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SHY} \\ Funktion \> : \> $M\leftarrow(Y)\&(PCH+1)$ \\ Adressierungsmodi \> : \> Y-indiziert lang \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SHX} \\ Funktion \> : \> $M\leftarrow(X)\&(PCH+1)$ \\ Adressierungsmodi \> : \> X-indiziert lang \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{LAX} \\ Funktion \> : \> $A,X\leftarrow(M)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, Y-indiziert lang/kurz, \\ \> \> X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{LXA} \\ Funktion \> : \> $X{04}\leftarrow(X){04} \& (M){04},$ \\ \> \> $A{04}\leftarrow(A){04} \& (M){04}$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{LAE} \\ Funktion \> : \> $X,S,A\leftarrow((S)\&(M))$ \\ Adressierungsmodi \> : \> Y-indiziert lang \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{DCP} \\ Funktion \> : \> $M \leftarrow(M)-1, Flags\leftarrow((A)-(M))$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{SBX} \\ Funktion \> : \> $X\leftarrow((X)\&(A))-(M)$ \\ Adressierungsmodi \> : \> immediate \\ \end{tabbing} \begin{tabbing} Adressierungsmodi \= : \= \kill \\ Anweisung \> : \> \tty{ISB} \\ Funktion \> : \> $M\leftarrow(M)+1, A\leftarrow(A)-(M)-(C)$ \\ Adressierungsmodi \> : \> absolut lang/kurz, X-indiziert lang/kurz, \\ \> \> Y-indiziert lang, X/Y-indirekt \\ \end{tabbing} %%--------------------------------------------------------------------------- \section{MELPS-740} Die Mikrokontroller dieser Reihe haben ein sehr nettes, verstecktes Feature: Setzt man mit dem Befehl \tty{SET} das Bit 5 des Statusregisters, so wird bei allen arithmetischen Operationen (und Ladebefehlen) der Akkumulator durch die durch das X-Register adressierte Speicherzelle ersetzt. Dieses Feature syntaxm"a"sig sauber zu integrieren, ist bisher nicht geschehen, d.h. es kann bisher nur im ,,Handbetrieb'' (\tty{SET}...Befehle mit Akkuadressierung...\tty{CLT}) genutzt werden. \par Nicht alle MELPS-740-Prozessoren implementieren alle Befehle. An dieser Stelle mu"s der Programmierer aufpassen, da"s er nur die Befehle benutzt, die auch wirklich vorhanden sind, da AS die Prozessoren dieser Familie nicht n"aher unterscheidet. Die Besonderheiten der Special-Page-Adressierung werden bei der Erkl"arung von \tty{ASSUME} n"aher erl"autert. %%--------------------------------------------------------------------------- \section{MELPS-7700/65816} \label{MELPS7700Spec} Offensichtlich haben diese beiden Prozessorfamilien ausgehend vom 6502 ("uber ihre 8-bittigen Vorg"anger) etwas disjunkte Entwicklungswege hinter sich. Kurz aufgelistet, ergeben sich folgende Unterschiede: \begin{itemize} \item{der 65816 hat keinen B-Akkumulator.} \item{beim 65816 fehlen Multiplikations- sowie Divisionsbefehle.} \item{Die Befehle \tty{SEB}, \tty{CLB}, \tty{BBC}, \tty{BBS}, \tty{CLM}, \tty{SEM}, \tty{PSH}, \tty{PUL} und \tty{LDM} fehlen beim 65816. An deren Stelle in der Code-Tabelle finden sich \tty{TSB}, \tty{TRB}, \tty{BIT}, \tty{CLD}, \tty{SED}, \tty{XBA}, \tty{XCE} und \tty{STZ}.} \end{itemize} Identische Funktion, jedoch andere Namen haben folgende Befehle: \par \begin{center}\begin{tabular}{|c|c||c|c|} \hline 65816 & MELPS-7700 & 65816 & MELPS-7700 \\ \hline \hline \tty{REP} & \tty{CLP} & \tty{PHK} & \tty{PHG} \\ \tty{TCS} & \tty{TAS} & \tty{TSC} & \tty{TSA} \\ \tty{TCD} & \tty{TAD} & \tty{TDC} & \tty{TDA} \\ \tty{PHB} & \tty{PHT} & \tty{PLB} & \tty{PLT} \\ \tty{WAI} & \tty{WIT} & & \\ \hline \end{tabular}\end{center} \par Besonders t"uckisch sind die Befehle \tty{PHB}, \tty{PLB} und \tty{TSB}: diese Befehle haben jeweils eine v"ollig andere Funktion und Kodierung! \par Leider tun diese Prozessoren mit ihrem Speicher etwas, was f"ur mich auf der nach oben offenen Perversit"atsskala noch vor der Intel-m"a"sigen Segmentierung rangiert: sie banken ihn! Nunja, dies ist wohl der Preis f"ur die 6502-Aufw"artskompatibilit"at; wie dem auch sei, damit AS den gew"unschten Code erzeugen kann, mu"s man ihn "uber den \tty{ASSUME}-Befehl "uber den Inhalt einiger Register in Kenntnis setzen: \par Das M-Flag bestimmt, ob die Akkumulatoren A und B 8 Bit (1) oder 16 Bit (0) breit sein sollen. Analog entscheidet das Flag X "uber die Breite der Indexregister X und Y. AS ben"otigt die Information "uber die Registerbreite bei unmittelbarer Adressierung (\tty{\#}), ob das Argument 8 oder 16 Bit breit sein soll. \par Der Speicher ist in 256 B"anke zu 64 Kbyte geteilt. Da alle Register im Prozessor nur maximal 16 Bit breit sind, kommen die obersten 8 Adre"sbits aus 2 speziellen Bank-Registern: DT liefert die oberen 8 Bits bei Datenzugriffen, PG erweitert den 16-bittigen Programmz"ahler auf 24 Bit. Die vom 6502 her bekannte ,,Zero-Page'' ist mittels des 16 Bit breiten Registers DPR frei innerhalb der ersten Bank verschiebbar. Trifft AS nun im Code auf eine Adresse (egal ob in einem absoluten, indizierten oder indirekten Ausdruck), so versucht er der Reihe nach folgende Adressierungsvarianten: \begin{enumerate} \item{Liegt die Adresse im Bereich von DPR...DPR+\$ff? Falls ja, Verwendung von direkter Adressierung mit 8-Bit-Adresse.} \item{Liegt die Adresse innerhalb der durch DT (bzw. PG f"ur Sprungbefehle) festgelegten Seite? Falls ja, Verwendung von absoluter Adressierung mit 16-Bit-Adresse.} \item{Falls nichts anderes hilft, Verwendung von langer Adressierung mit 24-Bit-Adresse.} \end{enumerate} Aus dieser Aufz"ahlung folgt, da"s das Wissen "uber die momentanen Werte von DT,PG und DPR f"ur die Funktion von AS essentiell ist; sind die Angaben fehlerhaft, adressiert das Programm ,,in die W"uste''. Diese Aufz"ahlung geht "ubrigens davon aus, da"s alle drei Adre"sl"angen verf"ugbar sind; sollte dies einmal nicht der Fall sein, so wird die Entscheidungskette entsprechen k"urzer. Die oben geschilderte, automatische Festlegung der Adre"sl"ange l"a"st sich auch durch die Verwendung von Pr"afixen "ubersteuern. Stellt man der Adresse ein $<$, $>$ oder $>>$ ohne trennendes Leerzeichen voran, so wird eine Adresse mit 1, 2 oder 3 Bytes benutzt, unabh"angig davon, ob dies die optimale L"ange ist. Benutzt man eine f"ur diesen Befehl nicht erlaubte oder f"ur die Adresse zu kurze L"ange, gibt es eine Fehlermeldung. Um die Portierung von 6502-Programmen zu erleichtern, verwendet AS f"ur Hexadezimalkonstanten die Motorola-Syntax und nicht die von Mitsubishi "ubrigens f"ur die 740er favorisierte Intel/IEEE-Schreibweise. Ich halte erstere auch f"ur die bessere Schreibweise, und die Entwickler des 65816 werden dies vermutlich "ahnlich gesehen haben (da man mittels der \tty{RELAXED}-Anweisung auch Intel-Notation benutzen kann, wird durch diese Entscheidung auch niemand festgelegt). Ein f"ur die Portierung "ahnlich wichtiges Detail ist, da"s der Akkumulator A als Ziel von Operationen auch weggelassen werden darf, anstelle von \tty{LDA A,\#0} darf also z.B. auch einfach \tty{LDA \#0} geschrieben werden. \par Ein echtes Bonbon in dem Befehlssatz sind dagegen die Blocktransferbefehle \tty{MVN} und \tty{MVP}. Etwas eigenartig ist nur die Adre"sangabe: Bit 0--15 im Indexregister, Bit 16--23 im Befehl. Bei AS gibt man als Argument f"ur beide Speicherbl"ocke einfach die vollen Adressen an, AS fischt sich dann die passenden Bits automatisch heraus. Dies ist ein feiner, aber wichtiger Unterschied zum Mitsubishi-Assembler, bei dem man die oberen 8 Bit selber herausziehen mu"s. Richtig bequem wird es aber erst mit einem Makro im folgendem Stil: \begin{verbatim} mvpos macro src,dest,len if MomCPU=$7700 lda #len elseif lda #(len-1) endif ldx #(src&$ffff) ldy #(dest&$ffff) mvp dest,src endm \end{verbatim} Vorsicht, Falle: Steht im Akkumulator die Zahl $n$, so transferiert der Mitsubishi $n$ Bytes, der 65816 jedoch $n+1$ Bytes! \par Sehr nett sind auch die Befehle \tty{PSH} und \tty{PUL}, mit deren Hilfe es m"oglich ist, mit einem Befehl einen frei w"ahlbaren Satz von Registern auf dem Stack zu sichern oder von ihm zu laden. Nach dem Mitsubishi-Datenbuch\cite{Mit16} mu"s die Angabe der Bitmasken immediate erfolgen, der Programmierer soll also entweder alle Register$\leftrightarrow$Bitstellen-Zuordnungen im Kopf behalten oder sich passende Symbole definieren. Hier habe ich die Syntax eigenm"achtig erweitert, um die Sache etwas angenehmer zu machen: Es darf eine Liste angegeben werden, die sowohl immediate-Ausdr"ucke als auch Registernamen enthalten darf. Damit sind z.B. die Anweisungen \begin{verbatim} psh #$0f \end{verbatim} und \begin{verbatim} psh a,b,#$0c \end{verbatim} und \begin{verbatim} psh a,b,x,y \end{verbatim} "aquivalent. Da die immediate-Version weiterhin erlaubt ist, bleibt AS hier ,,aufw"artskompatibel'' zu den Mitsubishi-Assemblern. \par Nicht ganz habe ich beim Mitsubishi-Assembler die Behandlung des \tty{PER}-Befehles verstanden: Mit diesem Befehl kann man eine 16-Bit-Variable auf den Stack legen, deren Adresse relativ zum Programmz"ahler angegeben wird. Es ist aus der Sicht des Programmierers also eine absolute Adressierung einer Speicherzelle. Nichtsdestotrotz verlangt Mitsubishi eine immediate-Adressierung, und das Argument wird so in den Code eingesetzt, wie es im Quelltext steht. Die Differenz mu"s man selber ausrechnen, was mit der Einf"uhrung von symbolischen Assemblern ja abgeschafft werden sollte...da ich aber auch ein bi"schen ,,kompatibel'' denken mu"s, enth"alt AS eine Kompromi"sl"osung: W"ahlt man immediate-Adressierung (also mit Gartenzaun), so verh"alt sich AS wie das Original von Mitsubishi. L"a"st man ihn jedoch weg, so berechnet AS die Differenz vom Argument zum momentanen Programmz"ahler und setzt diese ein. \par "Ahnlich sieht es beim \tty{PEI}-Befehl aus, der den Inhalt einer 16-Bit-Variablen auf der Zeropage auf den Stack legt: Obwohl der Operand eine Adresse ist, wird wieder immediate-Adressierung verlangt. Hier l"a"st AS schlicht beide Versionen zu (d.h. mit oder ohne Gartenzaun). %%--------------------------------------------------------------------------- \section{M16} Die M16-Familie ist eine Familie "au"serst komplexer CISC-Prozessoren mit einem entsprechend komplizierten Befehlssatz. Zu den Eigenschaften dieses Befehlssatzes geh"ort es unter anderem, da"s bei Operationen mit zwei Operanden beide Operanden verschiedene L"angen haben d"urfen. Die bei Motorola "ubliche und von Mitsubishi "ubernommene Methode, die Operandengr"o"se als Attribut an den Befehl anzuh"angen, mu"ste daher erweitert werden: Es ist erlaubt, auch an die Operanden selber Attribute anzuh"angen. So wird im folgenden Beispiel \begin{verbatim} mov r0.b,r6.w \end{verbatim} Register 0 8-bittig gelesen, auf 32 Bit vorzeichenerweitert und das Ergebnis in Register 6 kopiert. Da man in 9 von 10 F"allen aber von diesen M"oglichkeiten doch keinen Gebrauch macht, kann man weiterhin die Operandengr"o"se an den Befehl selber schreiben, z.B. so: \begin{verbatim} mov.w r0,r6 \end{verbatim} Beide Varianten d"urfen auch gemischt verwendet werden, eine Gr"o"senangabe am Operanden "ubersteuert dann den ,,Default'' am Befehl. Eine Ausnahme stellen Befehle mit zwei Operanden dar. Bei diesen ist der Default f"ur den Quelloperanden die Gr"o"se des Zieloperanden. In folgendem Beispiel \begin{verbatim} mov.h r0,r6.w \end{verbatim} wird also auf Register 0 32-bittig zugegriffen, die Gr"o"senangabe am Befehl wird "uberhaupt nicht mehr benutzt. Finden sich "uberhaupt keine Angaben zur Operandengr"o"se, so wird Wort(w) verwendet. Merke: im Gegensatz zu den 68000ern bedeutet dies 32 und nicht 16 Bit! \par Reichlich kompliziert sind auch die verketteten Adressierungsmodi; dadurch, da"s AS die Verteilung auf Kettenelemente automatisch vornimmt, bleibt die Sache aber einigerma"sen "ubersichtlich. Die einzige Eingriffsm"oglichkeit, die bei AS gegeben ist (der Originalassembler von Mitsubishi/Green Hills kann da noch etwas mehr), ist die explizite Festlegung von Displacement-L"angen mittels der Anh"angsel \tty{:4}, \tty{:16} und \tty{:32}. %%--------------------------------------------------------------------------- \section{4004} Noch ein St"uck Geschichte...leider habe ich noch keine offizielle Dokumentation zum ersten Mikroprozessor "uberhaupt gefunden, und da gibt es noch das eine oder andere Loch: Die Syntax f"ur Registerpaare (f"ur 8-Bit-Operationen) ist mir noch nicht ganz klar. Momentan ist die Syntax \tty{RnRm}, wobei \tty{n} bzw. \tty{m} gerade Integers im Bereich 0 bis E bzw. 1 bis F sind. Dabei gilt immer \tty{m = n + 1}. %%--------------------------------------------------------------------------- \section{MCS-48} Der maximale Adre"sraum dieser Prozessoren betr"agt 4 Kbyte. Dieser Raum ist jedoch nicht linear organisiert (wie k"onnte das bei Intel auch anders sein...), sondern in 2 B"anke zu 2 Kbyte geteilt. Ein Wechsel zwischen diesen beiden B"anken ist nur durch die Befehle \tty{CALL} und \tty{JMP} erlaubt, indem vor dem Sprung das h"ochste Adre"sbit mit den Befehlen \tty{SEL MB0} bzw. \tty{SEL MB1} vorgegeben wird. Um den Wechsel zwischen den B"anken zu vereinfachen, ist eine Automatik in den Befehlen \tty{JMP} und \tty{CALL} eingebaut, die einen dieser beiden Befehle einf"ugt, falls die Adresse des Sprungbefehles und das Sprungziel in unterschiedlichen B"anken liegen. Die explizite Benutzung der \tty{SEL MBx}-Befehle sollte daher nicht notwendig sein (obwohl sie m"oglich ist) und kann die Automatik auch durcheinanderbringen, wie in dem folgenden Beispiel: \begin{verbatim} 000: SEL MB1 JMP 200h \end{verbatim} AS nimmt an, da"s das MB-Flag auf 0 steht und f"ugt keinen \tty{SEL MB0}-Befehl vor dem Sprung ein, mit der Folge, da"s der Prozessor zur Adresse A00h springt. Weiterhin ist zu beachten, da"s ein Sprungbefehl durch diesen Mechanismus unter Umst"anden ein Byte l"anger wird. %%--------------------------------------------------------------------------- \section{MCS-51} Dem Assembler liegen die Dateien STDDEF51.INC bzw. 80C50X.INC bei, in denen alle Bits und SFRs der Prozessoren 8051, 8052 und 80515 bzw. 80C501, 502 und 504 verzeichnet sind. Je nach Einstellung des Prozessortyps mit dem \tty{CPU}-Befehl wird dabei die korrekte Untermenge eingebunden, die richtige Reihenfolge f"ur den Anfang eines Programmes ist daher \begin{verbatim} CPU INCLUDE stddef51.inc , \end{verbatim} sonst f"uhren die MCS-51-Pseudobefehle in der Include-Datei zu Fehlermeldungen. \par Da der 8051 keinen Befehl kennt, um die Register 0..7 auf den Stack zu legen, mu"s mit deren absoluten Adressen gearbeitet werden. Diese h"angen aber von der momentan aktiven Registerbank ab. Um diesem Mi"sstand etwas abzuhelfen, ist in den Include-Dateien das Makro \tty{USING} definiert, dem als Parameter die Symbole \tty{Bank0..Bank3} gegeben werden k"onnen. Das Makro belegt daraufhin die Symbole \tty{AR0..AR7} mit den passenden absoluten Adressen der Register. Dieses Makro sollte nach jeder Bankumschaltung benutzt werden. Es erzeugt selber \ii{keinen} Code zur Umschaltung! \par Das Makro f"uhrt in der Variablen \tty{RegUsage} gleichzeitig Buch "uber alle jemals benutzten Registerb"anke; Bit 0 entspricht Bank 0, Bit 1 der Bank 1 usw. . Der Inhalt kann am Ende der Quelldatei z.B. mit folgendem Codest"uck ausgegeben werden: \begin{verbatim} irp BANK,Bank0,Bank1,Bank2,Bank3 if (RegUsage&(2^BANK))<>0 message "Bank \{BANK} benutzt" endif endm \end{verbatim} Mit der Mehrpass-F"ahigkeit ab Version 1.38 wurde es m"oglich, zus"atzlich die Befehle \tty{JMP} und \tty{CALL} einzuf"uhren. Bei der Kodierung von Spr"ungen mit diesen Befehlen w"ahlt AS je nach Adre"slage automatisch die optimale Variante, d.h. \tty{SJMP/AJMP/LJMP} f"ur \tty{JMP} und \tty{ACALL/LCALL} f"ur \tty{CALL}. Es ist nat"urlich weiterhin m"oglich, die Varianten direkt zu verwenden, um eine bestimmte Kodierung zu erzwingen. %%--------------------------------------------------------------------------- \section{MCS-251} Intel hat sich beim 80C251 ja bem"uht, den "Ubergang f"ur den Programmierer auf die neue Familie so weich wie m"oglich zu gestalten, was darin gipfelt, da"s alte Anwendungen ohne Neu"ubersetzung auf dem neuen Prozessor ablaufen k"onnen. Sobald man jedoch den erweiterten Befehlssatz der 80C251 nutzen will, gilt es, einige Details zu beachten, die sich als versteckte Fu"sangeln auftun. \par An vorderster Stelle steht dabei die Tatsache, da"s der 80C251 keinen getrennten Bitadre"sraum mehr hat. Es sind nunmehr alle SFRs unabh"angig von ihrer Adre"slage sowie die ersten 128 Speicherstellen des internen RAMs bitadressierbar. M"oglich wird dies dadurch, da"s die Bitadressierung nicht mehr "uber einen zus"atzlichen virtuellen Adre"sraum, der andere Adre"sr"aume "uberdeckt, erfolgt, sondern so wie bei anderen Prozessoren auch durch eine zweidimensionale Adressierung, die aus der Speicherstelle, die das Bit beinhaltet sowie der Bitstelle im Byte besteht. Dies bedeutet zum einen, da"s bei einer Bitangabe wie z.B. PSW.7 AS die Zerlegung der Teile links und rechts vom Punkt selber vornimmt. Es ist also nicht mehr n"otig, mittels eines \tty{SFRB}-Befehls wie noch beim 8051 explizit 8 Bitsymbole zu erzeugen. Dies bedeutet zum anderen, da"s es den \tty{SFRB}-Befehl "uberhaupt nicht mehr gibt. Wird er in zu portierenden 8051-Programmen benutzt, kann er durch einen einfachen \tty{SFR}-Befehl ersetzt werden. \par Weiterhin hat Intel in den unterschiedlichen Adre"sr"aumen des 8051 geh"orig aufger"aumt: Der Bereich des internen RAMs (\tty{DATA} bzw. \tty{IDATA}), der \tty{XDATA}-Bereich und er bisherige \tty{CODE}-Bereich wurden in einem einzigen, 16 Mbyte gro"sen \tty{CODE}-Bereich vereinigt. Das interne RAM beginnt bei Adresse 0, das interne ROM beginnt bei Adresse ff0000h, dorthin mu"s also auch der Code mittels \tty{ORG} hinverlagert werden. Ausgelagert wurden dagegen die \tty{SFRs} in einen eigenen Adre"sraum (der bei AS als \tty{IO}-Segment definiert ist). In diesem neuen Adre"sraum haben sie aber die gleichen Adressen wie beim 8051. Der \tty{SFR}-Befehl kennt diesen Unterschied und legt mit ihm erzeugte Symbole je nach Zielprozessor automatisch ins \tty{DATA}- bzw. \tty{IO}-Segment. Da es keinen Bit-Adre"sraum mehr gibt, funktioniert der \tty{BIT}-Befehl v"ollig anders: anstelle einer linearen Adresse von 0 bis 255 beinhalten Bit-Symbole jetzt in Bit 0..7 die Adresse, in Bit 24..26 die Bitstelle. Damit ist es jetzt leider nicht mehr so einfach m"oglich, Felder von Flags mit symbolischen Namen anzulegen: Wo man beim 8051 noch z.B. \begin{verbatim} segment bitdata bit1 db ? bit2 db ? \end{verbatim} oder \begin{verbatim} defbit macro name name bit cnt cnt set cnt+1 endm \end{verbatim} schreiben konnte, hilft jetzt nur noch die zweite Variante weiter, z.B. so: \begin{verbatim} adr set 20h ; Startadresse Flags im internen RAM bpos set 0 defbit macro name name bit adr.bpos bpos set bpos+1 if bpos=8 bpos set 0 adr set adr+1 endif endm \end{verbatim} Ein weiteres, kleines Detail: Da Intel als Kennzeichnung f"ur den Carry nun CY statt C bevorzugt, sollte man ein eventuell benutztes Symbol umbenennen. AS versteht aber auch weiterhin die alte Variante in den Befehlen \tty{CLR, CPL, SETB, MOV, ANL,} und \tty{ORL}. Gleiches gilt sinngem"a"s f"ur die dazugekommenen Register \tty{R8..R15, WR0..WR30, DR0..DR28, DR56, DR60, DPX} und \tty{SPX}. \par Intel m"ochte es gerne, da"s man absolute Adressen in der Form \tty{XX:YYYY} schreibt, wobei \tty{XX} eine 64K-Bank im Adre"sraum angibt bzw. mit einem \tty{S} Adressen im IO-Raum kennzeichnet. Wie man sich schon denken kann, halte ich davon nicht allzu viel, weshalb man an allen Stellen Adressen genauso gut linear angeben kann; lediglich um das S f"ur die Kennzeichnung von I/O-Adressen kommt man nicht herum, z.B. hier: \begin{verbatim} Carry bit s:0d0h.7 \end{verbatim} Ohne den Pr"afix w"urde AS die absolute Adresse in das Code-Segment legen, und dort sind ja nur die ersten 128 Byte bitadressierbar... \par Wie auch schon beim 8051 gibt es die generischen Befehle \tty{JMP} und \tty{CALL}, die je nach Adre"slage automatisch die k"urzeste Variante einsetzen. W"ahrend \tty{JMP} aber die Variante mit 24 Bit mitber"ucksichtigt, tut \tty{CALL} dies aus gutem Grund nicht: Der \tty{ECALL}-Befehl legt n"amlich im Gegensatz zu \tty{ACALL} und \tty{LCALL} 3 Bytes auf den Stack, und man h"atte sonst einen \tty{CALL}-Befehl, bei dem man nicht mehr genau wei"s, was er tut. Bei \tty{JMP} tritt diese Problem nicht auf. \par Aus einer Sache bin ich nicht ganz schlau geworden: Der 80251 kann auch immediate-Operanden auf den Stack legen, und zwar sowohl einzelne Bytes als auch ganze W"orter. F"ur beide Varianten ist aber der gleiche Befehl \tty{PUSH} vorgesehen -- und woher soll bitte ein Assembler bei einer Anweisung wie \begin{verbatim} push #10 \end{verbatim} wissen, ob ein Byte oder ein Wort mit dem Wert 10 auf den Stack gelegt werden soll? Daher gilt im Augenblick die Regelung, da"s \tty{PUSH} grunds"atzlich ein Byte ablegt; wer ein Wort ablegen will, schreibt einfach \tty{PUSHW} anstelle \tty{PUSH}. \par Noch ein gutgemeinter Ratschlag: Wer den erweiterten Befehlssatz des 80C251 nutzt, sollte den Prozessor auch tunlichst im Source-Modus betreiben, sonst werden alle neuen Anweisungen ein Byte l"anger! Um die origin"aren 8051-Anweisungem, die daf"ur im Source-Modus l"anger werden, ist es nicht besonders schade: Sie werden entweder von AS automatisch durch neue, leistungsf"ahigere ersetzt oder sind be- treffen veraltete Adressierungsarten (indirekte Adressierung mit 8-Bit-Registern). %%--------------------------------------------------------------------------- \section{8086..V35} Eigentlich hatte ich mir geschworen, die Segmentseuche der 8086er aus diesem Assembler herauszuhalten. Da aber nun eine Nachfrage kam und Studenten flexiblere Menschen als die Entwickler dieses Prozessors sind, findet sich ab sofort auch eine rudiment"are Unterst"utzung dieser Prozessoren in AS. Unter ,,rudiment"ar'' verstehe ich dabei nicht, da"s der Befehlssatz nicht vollst"andig abgedeckt wird, sondern da"s ich nicht den ganzen Wust an Pseudoanweisungen integriert habe, die sich bei MASM, TASM \& Co. finden. AS ist auch nicht in erster Linie geschrieben worden, um PC-Programme zu entwickeln (Gott bewahre, das hie"se wirklich, das Rad neu zu erfinden), sondern zur Programmentwicklung f"ur Einplatinenrechner, die eben unter anderem auch mit 8086ern best"uckt sein k"onnen. \par F"ur Unentwegte, die mit AS doch DOS-Programme schreiben wollen, eine kleine Liste dessen, was zu beachten ist: \begin{itemize} \item{Es k"onnen nur COM-Programme erzeugt werden.} \item{Verwenden Sie nur das \tty{CODE}-Segment, und legen Sie auch alle Variablen darin ab.} \item{Alle Segmentregister werden von DOS auf das Codesegment vorinitialisiert. Ein \tty{ASSUME DS:CODE, SS:CODE} am Programmanfang ist daher notwendig.} \item{DOS l"adt den Code ab Adresse 100h. Ein \tty{ORG} auf diese Adresse ist daher zwingend.} \item{Die Umwandlung in eine Bin"ardatei erfolgt mit P2BIN (s.u.), wobei als als Adre"sbereich \tty{\$-\$} anzugeben ist.} \end{itemize} Allgemein unterst"utzt AS f"ur diese Prozessoren nur ein Small-Programmiermodell, d.h. \ii{ein} Codesegment mit maximal 64 KByte und ein ebenfalls h"ochstens 64 KByte gro"ses Datensegment mit (f"ur COM-Dateien uninitialisierten) Daten. Zwischen diesen beiden Segmenten kann mit dem \tty{SEGMENT}-Befehl hin-und hergeschaltet werden. Aus dieser Tatsache folgert, da"s Spr"unge immer intrasegment"ar sind, sofern sie sich auf Adressen im Codesegment beziehen. Falls weite Spr"unge doch einmal erforderlich sein sollten, k"onnen sie mit \tty{CALLF} und \tty{JMPF} und einer Speicheradresse oder einen Segment:Offset-Wert als Argument erreicht werden. \par Ein weiteres gro"ses Problem dieser Prozessoren ist deren Assemblersyntax, deren genaue Bedeutung nur aus dem Zusammenhang erkennbar ist. So kann im folgenden Beispiel je nach Symboltyp sowohl unmittelbare als auch absolute Adressierung gemeint sein: \begin{verbatim} mov ax,wert \end{verbatim} Bei AS ist immer unmittelbare Adressierung gemeint, wenn um den Operanden keine eckigen Klammern stehen. Soll z.B. die Adresse oder der Inhalt einer Variablen geladen werden, so ergeben sich die in Tabelle \ref{TabMASM} aufgelisteten Unterschiede. \begin{table*} \begin{center}\begin{tabular}{|l|l|l|} \hline Assembler & Adresse & Inhalt \\ \hline \hline MASM & \tty{mov ax,offset vari} & \tty{mov ax,vari} \\ & \tty{lea ax,vari} & \tty{mov ax,[vari]} \\ & \tty{lea ax,[vari]} & \\ & & \\ AS & \tty{mov ax,vari} & \tty{mov ax,[vari]} \\ & \tty{lea ax,[vari]} & \\ & & \\ \hline \end{tabular}\end{center} \caption{Unterschiede in der Adressierungssyntax AS$\leftrightarrow$MASM\label{TabMASM}} \normalsize \end{table*} \par Der Assembler pr"uft bei Symbolen, ob sie im Datensegment liegen und versucht, automatisch einen passenden Segmentpr"afix einzuf"ugen, z.B. falls ohne CS-Pr"afix auf Symbole im Code zugegriffen wird. Dieser Mechanismus kann jedoch nur funktionieren, falls der \tty{ASSUME}-Befehl (siehe dort) korrekt angewendet wurde. \par Die Intel-Syntax verlangt eine Abspeicherung, ob an einem Symbol Bytes oder W"orter abgelegt wurden. AS nimmt diese Typisierung nur vor, falls in der gleichen Zeile wie das Label ein \tty{DB} oder \tty{DW} steht. F"ur alle anderen F"alle mu"s mit den Operatoren \tty{WORD PTR, BYTE PTR} usw. explizit angegeben werden, um was f"ur eine Operandengr"o"se es sich handelt. Solange ein Register an der Operation beteiligt ist, kann auf diese Kennzeichnung verzichtet werden, da durch den Registernamen die Operandengr"o"se eindeutig bestimmt ist. \par Der Koprozessor in 8086-Systemen wird "ublicherweise durch den TEST-Eingang des Prozessors synchronisiert, indem selbiger mit dem BUSY-Ausgang des Koprozessors verbunden wird. AS unterst"utzt dieses Handshaking, indem vor jedem 8087-Befehl automatisch ein \tty{WAIT}-Befehl eingef"ugt wird. Ist dies aus irgendwelchen Gr"unden unerw"unscht (z.B. w"ahrend der Initialisierung), so mu"s im Opcode hinter dem \tty{F} ein \tty{N} eingef"ugt werden; aus \begin{verbatim} FINIT FSTSW [vari] \end{verbatim} wird so z.B. \begin{verbatim} FNINIT FNSTSW [vari] \end{verbatim} Diese Variante ist bei \ii{allen} Koprozessorbefehlen erlaubt. %%--------------------------------------------------------------------------- \section{8X30x} \label{8X30xSpec} Die Prozessoren dieser Reihe sind auf eine einfache Manipulation von Bitgruppen auf Peripherieadressen optimiert worden. Um mit solchen Bitgruppen auch symbolisch umgehen zu k"onnen, existieren die Befehle \tty{LIV} und \tty{RIV}, mit denen einer solchen Bitgruppe ein symbolischer Name zugewiesen wird. Diese Befehle arbeiten "ahnlich wie \tty{EQU}, ben"otigen aber drei Parameter: \begin{enumerate} \item{die Adresse der peripheren Speicherzelle, in der sich die Bitgruppe befindet (0..255);} \item{die Bitnummer des ersten Bits in der Gruppe (0..7);} \item{die L"ange der Gruppe in Bits (1..8).} \end{enumerate} \bb{ACHTUNG!} Der 8X30x unterst"utzt keine Bitgruppen, die "uber mehrere Speicherstellen hinausreichen, so da"s je nach Startposition der Wertebereich f"ur die L"ange eingeschr"ankt sein kann. AS nimmt hier \bb{keine} Pr"ufung vor, man bekommt lediglich zur Laufzeit merkw"urdige Ergebnisse! Im Maschinencode dr"ucken sich L"ange und Position durch ein 3-Bit-Feld im Instruktionswort sowie ein passende Registernummer (\tty{LIVx} bzw. \tty{RIVx}) aus. Bei der Verwendung eines symbolischen Objektes wird AS diese Felder automatisch richtig besetzen, es ist aber auch erlaubt, die L"ange als dritten Operanden explizit anzugeben, wenn man nicht mit symbolischen Busobjekten arbeitet. Trifft AS auf eine L"angenangabe trotz eines symbolischen Operanden, so vergleicht er beide L"angen und gibt eine Fehlermeldung bei Ungleichheit aus (das gleiche passiert "ubrigens auch, wenn man bei einem \tty{MOVE}-Befehl zwei symbolische Operanden mit unterschiedlicher L"ange benutzt - die Instruktion hat einfach nur ein L"angenfeld...). Neben den eigentlichen Maschinenbefehlen des 8X30x implementiert AS noch "ahnlich wie das ,,Vorbild'' MCCAP einige Pseudoinstruktionen, die als eingebaute Makros ausgef"uhrt sind: \begin{itemize} \item{\tty{NOP} ist eine Kurzschreibweise f"ur \tty{MOVE AUX,AUX}} \item{\tty{HALT} ist eine Kurzschreibweise f"ur \tty{JMP \verb!*!}} \item{\tty{XML ii} ist eine Kurzschreibweise f"ur \tty{XMIT ii,R12} (nur 8X305)} \item{\tty{XMR ii} ist eine Kurzschreibweise f"ur \tty{XMIT ii,R13} (nur 8X305)} \item{\tty{SEL $<$busobj$>$} ist eine Kurzschreibweise f"ur \tty{XMIT $<$adr$>$,IVL/IVR}, f"uhrt also die notwendige Vorselektion durch, um \tty{$<$busobj$>$} ansprechen zu k"onnen.} \end{itemize} Die bei MCCAP ebenfalls noch vorhandenen \tty{CALL-} und \tty{RTN-}Instruktionen sind mangels ausreichender Dokumentation momentan nicht implementiert. Das gleiche gilt f"ur einen Satz an Pseudoinstruktionen zur Datenablage. Kommt Zeit, kommt Rat... %%--------------------------------------------------------------------------- \section{XA} "Ahnlich wie sein Vorg"anger MCS/51, jedoch im Unterschied zu seinem ,,Konkurrenten'' MCS/251 besitzt der Philips XA einen getrennten Bitadre"sraum, d.h. alle mit Bitbefehlen manipulierbaren Bits haben eine bestimmte, eindimensionale Adresse, die in den Maschinenbefehlen auch so abgelegt wird. Die naheliegende M"oglichkeit, diesen dritten Adre"sraum (neben Code und Daten) auch so in AS anzubieten, habe ich nicht nutzen k"onnen, und zwar aus dem Grund, da"s ein Teil der Bitadressen im Gegensatz zum MCS/51 nicht mehr eindeutig ist: Bits mit den Adressen 256 bis 511 bezeichnen Bits der Speicherzellen 20h..3fh aus dem aktuellen Datensegment. Dies bedeutet aber, da"s diese Adressen je nach Situation unterschiedliche Bits ansprechen k"onnen - ein definieren von Bits mit Hilfe von \tty{DC}-Befehlen, was durch ein extra Segment m"oglich geworden w"are, w"urde also nicht "uberm"a"sig viel Sinn ergeben. Zur Definition einzelner, symbolisch ansprechbarer Bits steht aber nach wie vor der \tty{BIT}-Befehl zur Verf"ugung, mit dem beliebige Bitadressen (Register, RAM, SFR) definiert werden k"onnen. F"ur Bitadressen im internen RAM wird auch die 64K-Bank-Adresse gespeichert, so da"s AS Zugriffe "uberpr"ufen kann, sofern das DS-Register korrekt mit \tty{ASSUME} vorbesetzt wurde. \par Nichts drehen kann man dagegen an den Bem"uhungen von AS, potentielle Sprungziele (also Zeilen im Code mit Label) auf gerade Adressen auszurichten. Dies macht AS genauso wie andere XA-Assembler auch durch Einf"ugen von \tty{NOP}s vor dem fraglichen Befehl. %%--------------------------------------------------------------------------- \section{AVR} Im Gegensatz zum AVR-Assembler verwendet AS defaultm"a"sig das Intel-Format zur Darstellung von Hexadezimalkonstanten und nicht die C-Syntax. OK, nicht vorher in den (freien) AVR-Assembler hineingeschaut, aber als ich mit dem AVR-Teil anfing, gab es zum AVR noch nicht wesentlich mehr als ein vorl"aufiges Datenbuch mit Prozessortypen, die dann doch nie kamen...mit einem \tty{RELAXED ON} schafft man dieses Problem aus der Welt. Optional kann AS f"ur die AVRs (es geht auch f"ur andere CPU's, nur macht es dort keinen Sinn...) sogenannte ,,Objekt-Dateien'' erzeugen. Das sind Dateien, die sowohl Code als auch Quellzeileninformationen enthalten und z.B. eine schrittweise Abarbeitung auf Quellcodeebene mit dem von Atmel gelieferten Simulator WAVRSIM erlauben. Leider scheint dieser mit Quelldateispezifikationen, die l"anger als ca. 20 Zeichen sind, seine liebe Not zu haben: Namen werden abgeschnitten oder um wirre Sonderzeichen erg"anzt, wenn die Maximall"ange "uberschritten wird. AS speichert deshalb in den Objekt-Dateien Dateinamen ohne Pfadangabe, so da"s es eventuell Probleme geben k"onnte, wenn Dateien (z.B. Includes) nicht im Arbeitsverzeichnis liegen. Eine kleine Besonderheit sind Befehle, die Atmel bereits in der Architektur vorgesehen hat, aber noch in keinem Mitglied der Familie implementiert wurden. Dabei handelt es sich um die Befehle {\tt MUL, JMP} und {\tt CALL}. Besonders bei letzteren fragt man sich vielleicht, wie man denn nun den 4 KWorte gro"sen Adre"sraum des AT90S8515 erreichen kann, wenn die 'n"achstbesten' Befehle {\tt RJMP} und {\tt RCALL} doch nur 2 KWorte weit springen kann. Der Kunstgriff lautet 'Abschneiden der oberen Adre"sbits' und ist n"aher bei der {\tt WRAPMODE}-Anweisung beschrieben. %%--------------------------------------------------------------------------- \section{Z80UNDOC} Da es von Zilog naturgem"a"s keine Syntaxvorgaben f"ur die undokumentierten Befehle gibt und wohl auch nicht jeder den kompletten Satz kennt, ist es vielleicht sinnvoll, diese Befehle hier kurz aufzuz"ahlen: \par Wie auch beim Z380 ist es m"oglich, die Byte-H"alften von IX und IY einzeln anzusprechen. Im einzelnen sind dies folgende Varianten: \begin{verbatim} INC Rx LD R,Rx LD Rx,n DEC Rx LD Rx,R LD Rx,Ry ADD/ADC/SUB/SBC/AND/XOR/OR/CP A,Rx \end{verbatim} Dabei stehen \tty{Rx} bzw. \tty{Ry} f"ur \tty{IXL, IXU, IYL} oder \tty{IYU}. Zu beachten ist jedoch, da"s in der \tty{LD Rx,Ry}-Variante beide Register aus dem gleichen Indexregister stammen m"ussen. \par Die Kodierung von Schiebebefehlen besitzt noch eine undefinierte Bitkombination, die als \tty{SLIA}-Befehl zug"anglich ist. \tty{SLIA} funktioniert wie \tty{SLA}, es wird jedoch eine Eins und nicht eine Null in Bit 0 eingeschoben. Dieser Befehl kann, wie alle anderen Schiebebefehle auch, noch in einer weiteren Variante geschrieben werden: \begin{verbatim} SLIA R,(XY+d) \end{verbatim} Dabei steht \tty{R} f"ur ein beliebiges 8-Bit-Register (aber nicht eine Indexregisterh"alfte...), und \tty{(XY+d)} f"ur eine normale indexregister-relative Adressierung. Das Ergebnis dieser Operation ist, da"s das Schiebeergebnis zus"atzlich ins Register geladen wird. Dies funktioniert auch bei den \tty{RES-} und \tty{SET-}Befehlen: \begin{verbatim} SET/RES R,n,(XY+d) \end{verbatim} Des weiteren gibt es noch zwei versteckte I/O-Befehle: \begin{verbatim} IN (C) bzw. TSTI OUT (C),0 \end{verbatim} Deren Funktionsweise sollte klar sein. \bb{ACHTUNG!} Es gibt keine Garantie daf"ur, da"s alle Z80-Masken alle diese Befehle beherrschen, und die Z80-Nachfolger l"osen zuverl"assig Traps aus. Anwendung daher auf eigene Gefahr... %%--------------------------------------------------------------------------- \section{Z380} Da dieser Prozessor als Enkel des wohl immer noch beliebtesten 8-Bit-Prozessors konzipiert wurde, war es bei der Entwicklung unabdingbar, da"s dieser bestehende Z80-Programme ohne "Anderung ausf"uhren kann (nat"urlich geringf"ugig schneller, etwa um den Faktor 10...). Die erweiterten F"ahigkeiten k"onnen daher nach einem Reset mit zwei Flags zugeschaltet werden, die XM (eXtended Mode, d.h. 32- statt 16-Bit-Adre"sraum) und LW (long word mode, d.h. 32- statt 16- Bit-Operanden) hei"sen. Deren Stand mu"s man AS "uber die Befehle \tty{EXTMODE} und \tty{LWORDMODE} mitteilen, damit Adressen und Konstantenwerte gegen die korrekten Obergrenzen gepr"uft werden. Die Umschaltung zwischen 32- und 16-Bit-Befehlen bewirkt nat"urlich nur bei solchen Befehlen etwas, die auch in einer 32-Bit-Version existieren; beim Z380 sind das momentan leider nur Lade- und Speicherbefehle, die ganze Aritmetik kann nur 16-bittig ausgef"uhrt werden. Hier sollte Zilog wohl noch einmal etwas nachbessern, sonst kann man den Z380 selbst beim besten Willen nur als ,,16-Bit-Prozessor mit 32-Bit-Erweiterungen'' bezeichnen... Kompliziert wird die Sache dadurch, da"s die mit LW eingestellte Operandengr"o"se f"ur einzelne Befehle mit den Pr"afixen \tty{DDIR W} und \tty{DDIR LW} "ubersteuert werden kann. AS merkt sich das Auftreten solcher Befehle und schaltet dann f"ur den n"achsten Prozessorbefehl automatisch mit um. Andere \tty{DDIR}-Varianten als \tty{W} und \tty{LW} sollte man "ubrigens nie explizit verwenden, da AS bei zu langen Operanden diese automatisch einsetzt, und das k"onnte zu Verwirrungen f"uhren. Die Automatik geht "ubrigens so weit, da"s in der Befehlsfolge \begin{verbatim} DDIR LW LD BC,12345678h \end{verbatim} automatisch der erforderliche \tty{IW}-Pr"afix mit in die vorangehende Anweisung hineingezogen wird, effektiv wird also der Code \begin{verbatim} DDIR LW,IW LD BC,12345678h \end{verbatim} erzeugt. Der im ersten Schritt erzeugte Code f"ur \tty{DDIR LW} wird verworfen, was an einem \tty{R} im Listing zu erkennen ist. %%--------------------------------------------------------------------------- \section{TLCS-900(L)} \label{TLCS900Spec} Diese Prozessoren k"onnen in zwei Betriebsarten laufen, einmal im \ii{Minimum}-Modus, der weitgehende Z80- und TLCS-90-Quellcodekompatibilit"at bietet, und zum anderen im \ii{Maximum}-Modus, in dem der Prozessor erst seine wahren Qualit"aten entfaltet. Die Hauptunterschiede zwischen den beiden Betriebsarten sind: \begin{itemize} \item{Breite der Register WA,BC,DE und HL: 16 oder 32 Bit;} \item{Anzahl der Registerbanks: 8 oder 4;} \item{Programmadre"sraum: 64 Kbyte oder 16 Mbyte;} \item{Breite von R"ucksprungadressen: 16 oder 32 Bit.} \end{itemize} Damit AS gegen die richtigen Grenzen pr"ufen kann, mu"s man ihm zu Anfang mit dem Befehl \tty{MAXMODE} (siehe dort) mitteilen, in welcher Betriebsart der Code ausgef"uhrt werden wird; Voreinstellung ist der Minimum-Modus. \par Je nach Betriebsart m"ussen demzufolge auch die 16- oder 32-Bit-Versionen der Bankregister zur Adressierung verwendet werden, d.h. WA, BC, DE und HL im Minimum-Modus sowie XWA, XBC, XDE und XHL im Maximum-Modus. Die Register XIX..XIZ und XSP sind \bb{immer} 32 Bit breit und m"ussen zur Adressierung auch immer in dieser Form verwendet werden; hier mu"s bestehender Z80-Code also auf jeden Fall angepa"st werden (neben der Tatsache, da"s es gar keinen I/O-Adre"sraum mehr gibt und alle I/O-Register memory-mapped sind...). \par Die von Toshiba gew"ahlte Syntax f"ur Registernamen ist in der Hinsicht etwas ungl"ucklich, als da"s zur Anwahl der vorherigen Registerbank ein Hochkomma (') benutzt wird. Dieses Zeichen wird von den prozessorunabh"angigen Teilen von AS bereits zur Kennzeichnung von Zeichenkonstanten benutzt. Im Befehl \begin{verbatim} ld wa',wa \end{verbatim} erkennt AS z.B. nicht das Komma zur Parametertrennung. Dieses Problem kann man aber umgehen, indem man ein umgekehrtes Hochkomma (`) verwendet, z.B. \begin{verbatim} ld wa`,wa \end{verbatim} Toshiba liefert f"ur die TLCS-900-Reihe selber einen Assembler (TAS900), der sich in einigen Punkten von AS unterscheidet: \subsubsection{Symbolkonventionen} \begin{itemize} \item{TAS900 unterscheidet Symbolnamen nur auf den ersten 32 Zeichen. AS dagegen speichert Symbolnamen immer in der vollen L"ange (bis 255 Zeichen) und unterscheidet auch auf dieser L"ange.} \item{Unter TAS900 k"onnen Integerkonstanten sowohl in C-Notation (mit vorangestellter 0 f"ur oktal bzw. 0x f"ur hexadezimal) als auch in normaler Intel-Notation geschrieben werden. AS unterst"utzt in der Default-Einstellung \bb{nur} die Intel-Notation. Mit dem \tty{RELAXED}-Befehl bekommt man (unter anderem) auch die C-Notation.} \item{AS macht keinen Unterschied zwischen Gro"s- und Kleinschreibung, TAS900 hingegen unterscheidet Gro"s-und Kleinbuchstaben in Symbolnamen. Dieses Verhalten erh"alt man bei AS erst, wenn man die \tty{-u}-Kommandozeilenoption benutzt.} \end{itemize} \subsubsection{Syntax} AS ist bei vielen Befehlen in der Syntaxpr"ufung weniger streng als TAS900, bei einigen weicht er (sehr) geringf"ugig ab. Diese Erweiterungen bzw. "Anderungen dienen teilweise der leichteren Portierung von bestehendem Z80-Code, teilweise einer Schreiberleichterung und teilweise einer besseren Orthogonalit"at der Assemblersyntax: \begin{itemize} \item{Bei den Befehlen \tty{LDA, JP} und \tty{CALL} verlangt TAS, da"s Adre"sausdr"ucke wie \tty{XIX+5} nicht geklammert sein d"urfen, wie es sonst "ublich ist. AS verlangt im Sinne der Orthogonalit"at f"ur \tty{LDA} dagegen immer eine Klammerung, bei \tty{JP} und \tty{CALL} ist sie dagegen f"ur einfache, absolute Adressen optional.} \item{Bei den bedingten Befehlen \tty{JP, CALL, JR} und \tty{SCC} stellt AS es dem Programmierer frei, die Default-Bedingung \tty{T} (= true) als ersten Parameter anzugeben oder nicht. TAS900 hingegen erlaubt es nur, die Default-Bedingung implizit zu benutzen (also z.B. \tty{jp (xix+5)} anstelle von \tty{jp t,(xix+5)}).} \item{AS erlaubt beim \tty{EX}-Befehl auch Operandenkombinationen, die zwar nicht direkt im User's Manual\cite{Tosh900} genannt werden, aber durch Vertauschung auf eine genannte zur"uckgef"uhrt werden k"onnen. Kombinationen wie \tty{EX f`,f} oder \tty{EX wa,(xhl)} werden damit m"oglich. TAS900 hingegen l"a"st nur die ,,reine Lehre'' zu.} \item{AS erlaubt, bei den Befehlen \tty{INC} und \tty{DEC} die Angabe des Inkrements oder Dekrements wegzulassen, wenn dies 1 ist. Unter TAS900 dagegen mu"s auch eine 1 hingeschrieben werden.} \item{"Ahnlich verh"alt es sich bei allen Schiebebefehlen: Ist der zu verschiebende Operand ein Register, so verlangt TAS900, da"s auch eine Schiebeamplitude von 1 ausgeschrieben werden mu"s; ist dagegen eine Speicherstelle der Operand, so ist die Schiebezahl (hardwarebedingt) immer 1 und darf auch nicht hingeschrieben werden. Unter AS dagegen ist die Schiebezahl 1 immer optional und auch f"ur alle Operandentypen zul"assig.} \end{itemize} \subsubsection{Makroprozessor} Der Makroprozessor wird TAS900 als externes Programm vorgeschaltet und besteht aus zwei Komponenten: einem C-artigen Pr"aprozessor und einer speziellen Makrosprache (MPL), die an h"ohere Programmiersprachen erinnert. Der Makroprozessor von AS dagegen orientiert sich an ,,klassischen'' Makroassemblern wie dem M80 oder MASM (beides Programme von Microsoft). Er ist fester Bestandteil des Programmes. \subsubsection{Ausgabeformat} TAS900 erzeugt relokatiblen Code, so da"s sich mehrere, getrennt assemblierte Teile zu einem Programm zusammenbinden lassen. AS hingegen erzeugt direkt absoluten Maschinencode, der nicht linkbar ist. An eine Erweiterung ist (vorl"aufig) nicht gedacht. \subsubsection{Pseudoanweisungen} Bedingt durch den fehlenden Linker fehlen in AS eine ganze Reihe von f"ur relokatiblen Code erforderlichen Pseudoanweisungen, die TAS900 implementiert. In gleicher Weise wie bei TAS900 sind folgende Anweisungen vorhanden: \begin{quote}{\tt EQU, DB, DW, ORG, ALIGN, END, TITLE, SAVE, RESTORE, }\end{quote} wobei die beiden letzteren einen erweiterten Funktionsumfang haben. Einige weitere TAS900-Pseudobefehle lassen sich durch "aquivalente AS-Befehle ersetzen (siehe Tabelle \ref{TabTAS900}). \par Von Toshiba existieren zwei Versionen des Prozessorkerns, wobei die L-Variante eine ,,Sparversion'' darstellt. Zwischen TLCS-900 und TLCS-900L macht AS folgende Unterschiede: \begin{itemize} \item{Die Befehle \tty{MAX} und \tty{NORMAL} sind f"ur die L-Version nicht erlaubt, der \tty{MIN}-Befehl ist f"ur die Vollversion gesperrt.} \item{Die L-Version kennt den Normal-Stapelzeiger \tty{XNSP/NSP} nicht, daf"ur das Steuerregister \tty{INTNEST}.} \end{itemize} Die Befehle \tty{SUPMODE} und \tty{MAXMODE} werden nicht beeinflu"st, ebenso nicht deren ini\-tiale Einstellung OFF. Die Tatsache, da"s die L-Version im Maximum-Modus startet und keinen Normal-Modus kennt, mu"s also vom Programmierer ber"ucksichtigt werden. AS zeigt sich jedoch insofern kulant gegen"uber der L-Variante, als da"s Warnungen wegen privilegierter Anweisungen im L-Modus unterdr"uckt werden. \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|l|l|} \hline TAS900 & AS & Bedeutung/Funktion \\ \hline \hline \tty{DL} $$ & \tty{DD} $$ & Speicher in Langworten belegen \\ \hline \tty{DSB} $$ & \tty{DB} $$ \tty{DUP} (?) & Speicher byteweise reservieren \\ \hline \tty{DSW} $$ & \tty{DW} $$ \tty{DUP} (?) & Speicher wortweise reservieren \\ \hline \tty{DSD} $$ & \tty{DD} $$ \tty{DUP} (?) & Speicher langwortweise reservieren \\ \hline \tty{\$MIN[IMUM]} & \tty{MAXMODE OFF} & folgender Code im Minimum-Modus \\ \hline \tty{\$MAX[IMUM]} & \tty{MAXMODE ON} & folgender Code im Maximum-Modus \\ \hline \tty{\$SYS[TEM]} & \tty{SUPMODE ON} & folgender Code im System-Modus \\ \hline \tty{\$NOR[MAL]} & \tty{SUPMODE OFF} & folgender Code im User-Modus \\ \hline \tty{\$NOLIST} & \tty{LISTING OFF} & Assemblerlisting ausschalten \\ \hline \tty{\$LIST} & \tty{LISTING ON} & Assemblerlisting einschalten \\ \hline \tty{\$EJECT} & \tty{NEWPAGE} & neue Seite im Listing beginnen \\ \hline \end{tabular}\end{center} \caption{"aquivalente Befehle TAS900$\leftrightarrow$AS\label{TabTAS900}} \end{table*} %%--------------------------------------------------------------------------- \section{TLCS-90} Vielleicht fragt sich der eine oder andere, ob bei mir die Reihenfolge durcheinandergekommen ist, es gab ja von Toshiba zuerst den 90er als ,,aufgebohrten Z80'' und danach den 900er als 16-Bit-Version. Nun, ich bin einfach "uber den 900er zum 90er gekommen (Danke, Oliver!). Die beiden Familien sind sich sehr artverwandt, nicht nur was ihre Syntax angeht, sondern auch ihre Architektur. Die Hinweise f"ur den 90er sind daher eine Untermenge derer f"ur den 900er: Da Schieben, Inkrementieren und Dekrementieren hier nur um eins m"oglich sind, braucht und darf diese Eins auch nicht als erstes Argument hingeschrieben werden. Bei den Befehlen \tty{LDA, JP} und \tty{CALL} m"ochte Toshiba wieder die Klammern um Speicheroperanden weglassen, bei AS m"ussen sie aber aus Gr"unden der Orthogonalit"at gesetzt werden (der tiefere Grund ist nat"urlich, da"s ich mir damit eine Sonderabfrage im Parser gespart habe, aber das sagt man nicht so laut). \par Die TLCS-90er besitzen bereits prinzipiell einen Adre"sraum von 1 Mbyte, dieser Raum erschlie"st sich aber nur bei Datenzugriffen "uber die Indexregister. AS verzichtet daher auf eine Ber"ucksichtigung der Bankregister und begrenzt den Adre"sraum f"ur Code auf 64 Kbyte. Da der Bereich jenseits aber sowieso nur "uber indirekte Adressierung erreichbar ist, sollte dies keine allzu gro"se Einschr"ankung darstellen. %%--------------------------------------------------------------------------- \section{TLCS-870} Schon wieder Toshiba...diese Firma ist im Augenblick wirklich sehr produktiv! Speziell dieser Spro"s der Familie (Toshibas Mikrokontroller sind sich ja alle in Bin"arkodierung und Programmiermodell recht "ahnlich) scheint auf den 8051-Markt abzuzielen: Die Methode, Bitstellen durch einen Punkt getrennt an den Adre"sausdruck anzuh"angen, hatte ja beim 8051 ihren Ursprung, f"uhrt jetzt aber auch genau zu den Problemen, die ich beim 8051 geahnt hatte: Der Punkt ist jetzt einerseits legales Zeichen in Symbolnamen, andererseits aber auch Teil der Adre"ssyntax, d.h. AS mu"s Adresse und Bitstelle trennen und einzeln weiterverarbeiten. Diesen Interessenkonflikt habe ich vorerst so gel"ost, da"s der Ausdruck von \bb{hinten} an nach Punkten durchsucht wird und so der letzte Punkt als Trenner gilt, eventuelle weitere Punkte werden dem Symbolnamen zugerechnet. Es gilt weiterhin die flehentliche Bitte, im eigenen Interesse auf Punkte in Symbolnamen zu verzichten, sie f"uhren nur zu Verwirrungen: \begin{verbatim} LD CF,A.7 ; Akku Bit 7 nach Carry LD C,A.7 ; Konstante A.7 nach Register C \end{verbatim} %%--------------------------------------------------------------------------- \section{TLCS-47} Mit dieser 4-Bit-Prozessorfamilie d"urfte wohl das unter Ende dessen erreicht sein, was AS unterst"utzen kann. Neben dem \tty{ASSUME}-Befehl f"ur das Datenbankregister (siehe dort) ist eigentlich nur ein Detail erw"ahnenswert: im Daten- und I/O-Segment werden keine Bytes, sondern Nibbles reserviert (eben 4-Bitter...). Die Sache funktioniert "ahnlich wie das Bitdatensegment beim 8051, wo ein \tty{DB} ja nur einzelne Bit reserviert, nur da"s es hier eben Nibbles sind. \par Toshiba hat f"ur diese Prozessorfamilie einen ,,erweiterten Befehlssatz'' in Makroform definiert, um das Arbeiten mit diesem doch recht beschr"ankten Befehlssatz zu erleichtern. Im Fall von AS ist er in der Datei STDDEF47.INC definiert. Einige Befehle, deren makrom"a"sige Realisierung nicht m"oglich war, sind allerdings ,,eingebaut'' und stehen daher auch ohne die Include-Datei zur Verf"ugung: \begin{itemize} \item{der \tty{B}-Befehl, der die jeweils optimale Version des Sprungbefehls (\tty{BSS, BS oder BSL}) automatisch w"ahlt;} \item{\tty{LD} in der Variante HL mit immediate;} \item{\tty{ROLC} und \tty{RORC} mit einer Schiebeamplitude $>$1.} \end{itemize} %%--------------------------------------------------------------------------- \section{TLCS-9000} Hier ist es zum ersten Mal passiert, da"s ich einen Prozessor in AS implementiert habe, der zu diesem Zeitpunkt noch gar nicht auf dem Markt war. Toshiba hat sich leider auch vorl"aufig dazu entschieden, diesen Prozessor ,,auf Eis'' zu legen, bis auf weiteres wird es also auch kein Silizium geben. Das hat nat"urlich zur Folge, da"s dieser Teil \begin{description} \item[1.]{ein ,,Paper-Design'' ist, d.h. noch nicht praktisch getestet wurde und} \item[2.]{Die Unterlagen, die ich zum 9000er hatte \cite{Tosh9000}, noch vorl"aufig waren, also noch nicht bis ins letzte Klarheit lieferten.} \end{description} Fehler in diesem Teil sind also durchaus noch m"oglich (und werden nat"urlich bereinigt, wenn es denn einmal gehen sollte!). Zumindest die Handvoll Beispiele in \cite{Tosh9000} werden aber richtig "ubersetzt. %%--------------------------------------------------------------------------- \section{29xxx} Wie schon beim \tty{ASSUME}-Befehl beschrieben, kann AS mit der Kenntnis "uber den Inhalt des RBP-Registers feststellen, ob im User-Modus auf gesperrte Register zugegriffen wird. Diese F"ahigkeit beschr"ankt sich nat"urlich auf direkte Zugriffe (also nicht, wenn die Register IPA...IPC benutzt werden), und sie hat noch einen weiteren Haken: da lokale Register (also solche mit Nummern$>$127) relativ zum Stackpointer adressiert werden, die Bits in RBP sich aber immer auf absolute Nummern beziehen, wird die Pr"ufung f"ur lokale Register NICHT durchgef"uhrt. Eine Erweiterung auf lokale Register w"urde bedingen, da"s AS zu jedem Zeitpunkt den absoluten Wert von SP kennt, und das w"urde sp"atestens bei rekursiven Unterprogrammen scheitern... %%--------------------------------------------------------------------------- \section{80C16x} Wie in der Erkl"arung des \tty{ASSUME}-Befehls schon erl"autert, versucht AS, dem Programmierer die Tatsache, da"s der Prozessor mehr physikalischen als logischen Speicher hat, soweit als m"oglich zu verbergen. Beachten Sie aber, da"s die DPP-Register \bb{nur} Datenzugriffe betreffen und auch dort nur absolute Adressierung, also weder indirekte noch indizierte Zugriffe, da AS ja nicht wissen kann, wie die berechnete Adresse zur Laufzeit aussehen wird...Bei Codezugriffen arbeitet die Paging-Einheit leider nicht, man mu"s also explizit mit langen oder kurzen \tty{CALL}s, \tty{JMP}s oder \tty{RET}s arbeiten. Zumindest bei den ,,universellen'' Befehlen \tty{CALL} und \tty{JMP} w"ahlt AS automatisch die k"urzeste Form, aber sp"atestens beim \tty{RET} sollte man wissen, woher der Aufruf kam. Prinzipiell verlangen \tty{JMPS} und \tty{CALLS} dabei, da"s man Segment und Adresse getrennt angibt, AS ist jedoch so geschrieben, da"s er eine Adresse selber zerlegen kann, z.B. \begin{verbatim} jmps 12345h \end{verbatim} anstelle von \begin{verbatim} jmps 1,2345h \end{verbatim} Leider sind nicht alle Effekte der chipinternen Instruktions-Pipeline versteckt: Werden CP (Registerbankadresse), SP (Stack) oder eines der Paging-Register ver"andert, so steht der neue Wert noch nicht f"ur den n"achsten Befehl zur Verf"ugung. AS versucht, solche Situationen zu erkennen und gibt im Falle eines Falles eine Warnung aus. Aber auch diese Mimik greift nur bei direkten Zugriffen. \par Mit \tty{BIT} definierte Bits werden intern in einem 13-Bit-Wort abgelegt, wobei die Bitadresse in Bit 4..11 liegt und die Bitnummer in den unteren vier Bits. Diese Anordnung erlaubt es, das n"achsth"ohere bzw. n"achstniedrigere Bit durch Inkrementieren bzw. Dekrementieren anzusprechen. Bei expliziten Bitangaben mit Punkt funktioniert das aber nicht "uber Wortgrenzen hinaus. So erzeugt folgender Ausdruck eine Wertebereichs"uberschreitung: \begin{verbatim} bclr r5.15+1 \end{verbatim} Hier mu"s ein \tty{BIT} her: \begin{verbatim} msb bit r5.15 . . . bclr msb+1 \end{verbatim} F"ur den 80C167/165/163 ist der SFR-Bereich verdoppelt worden; da"s ein Bit im zweiten Teil liegt, wird durch ein gesetztes Bit 12 vermerkt. Leider hatte Siemens bei der Definition des 80C166 nicht vorausgesehen, da"s 256 SFRs (davon 128 bitadressierbar) f"ur Nachfolgechips nicht reichen w"urden. So w"are es unm"oglich, den zweiten SFR-Bereich von F000H..F1DFH mit kurzen Adressen oder Bitbefehlen zu erreichen, h"atten die Entwickler nicht einen Umschaltbefehl eingebaut: \begin{verbatim} EXTR #n \end{verbatim} Dieser Befehl bewirkt, da"s f"ur die n"achsten \tty{n} Befehle (0$<$\tty{n}$<$5) anstelle des normalen der erweiterte SFR-Bereich angesprochen werden kann. AS erzeugt bei diesm Befehl nicht nur den passenden Code, sondern setzt intern ein Flag, da"s f"ur die n"achsten \tty{n} Befehle nur Zugriffe auf den erweiterten SFR-Bereich zul"a"st. Da d"urfen nat"urlich keine Spr"unge dabei sein... Bits aus beiden Bereichen lassen sich nat"urlich jederzeit definieren, ebenso sind komplette Register aus beiden SFR-Bereichen jederzeit mit absoluter Adressierung erreichbar. Nur die kurze bzw. Bitadressierung geht immer nur abwechselnd, Zuwiderhandlungen werden mit einer Fehlermeldung geahndet. \par "Ahnlich sieht es mit den Pr"afixen f"ur absolute bzw. indirekte Adressierung aus: Da aber sowohl Argument des Pr"afixes als auch der Adre"sausdruck nicht immer zur "Ubersetzungszeit bestimmbar sind, sind die Pr"ufungsm"oglichkeiten durch AS sehr eingeschr"ankt, weshalb er es auch bei Warnungen bel"a"st...im einzelnen sieht das folgenderma"sen aus: \begin{itemize} \item{feste Vorgabe einer 64K-Bank mittels \tty{EXTS} oder \tty{EXTSR}: Im Adre"sausdruck werden direkt die unteren 16 Bit der Zieladresse eingesetzt. Haben sowohl Pr"afix als auch Befehl einen konstanten Operanden, so wird "uberpr"uft, ob Pr"afixargument und Bit 16..23 der Zieladresse identisch sind.} \item{feste Vorgabe einer 16K-Seite mittels \tty{EXTP} oder \tty{EXTPR}: Im Adre"sausdruck werden direkt die unteren 14 Bit der Zieladresse eingesetzt. Bit 14 und 15 bleiben konstant 0, da sie in diesem Modus nicht vom Prozessor ausgewertet werden. Haben sowohl Pr"afix als auch Befehl einen konstanten Operanden, so wird "uberpr"uft, ob Pr"afixargument und Bit 14..23 der Zieladresse identisch sind.} \end{itemize} Damit das etwas klarer wird, ein Beispiel (die DPP-Register haben die Reset-Vorbelegung) : \begin{verbatim} extp #7,#1 ; Bereich von 112K..128K mov r0,1cdefh ; ergibt Adresse 0defh im Code mov r0,1cdefh ; -->Warnung exts #1,#1 ; Bereich von 64K..128K mov r0,1cdefh ; ergibt Adresse 0cdefh im Code mov r0,1cdefh ; -->Warnung \end{verbatim} %%--------------------------------------------------------------------------- \section{PIC16C5x/16C8x} "Ahnlich wie die MCS-48-Familie teilen auch die PICs ihren Programmspeicher in mehrere B"anke auf, da im Opcode nicht gen"ugend Platz f"ur die vollst"andige Adresse war. AS verwendet f"ur die Befehle \tty{CALL} und \tty{GOTO} die gleiche Automatik, d.h. setzt die PA-Bits im Statuswort entsprechend Start- und Zieladresse. Im Gegensatz zu den 48ern ist dieses Verfahren hier aber noch deutlich problematischer: \begin{enumerate} \item{Die Befehle sind nicht mehr nur ein Wort, sondern bis zu drei Worten lang, k"onnen also nicht mehr in jedem Fall mit einem bedingten Sprung "ubergangen werden.} \item{Es ist m"oglich, da"s der Programmz"ahler beim normalen Programmfortgang eine Seitengrenze "uberschreitet. Die vom Assembler angenommene Belegung der PA-Bits stimmt dann nicht mehr mit der Realit"at "uberein.} \end{enumerate} Bei den Befehlen, die das Register W mit einem anderen Register verkn"upfen, mu"s normalerweise als zweiter Parameter angegeben werden, ob das Ergebnis in W oder im Register abgelegt werden soll. Bei diesem Assembler ist es erlaubt, den zweiten Parameter wegzulassen. Welches Ziel dann angenommen werden soll, h"angt vom Typ des Befehls ab: bei un"aren Operationen wird defaultm"a"sig das Ergebnis zur"uck ins Register gelegt. Diese Befehle sind: \begin{quote} {\tt COMF, DECF, DECFSZ, INCF, INCFSZ, RLF, RRF} und {\tt SWAPF} \end{quote} Die anderen Befehle betrachten W defaultm"a"sig als Akkumulator, zu dem ein Register verkn"upft wird: \begin{quote} {\tt ADDWF, ANDWF, IORWF, MOVF, SUBWF} und {\tt XORWF} \end{quote} \par Die von Microchip vorgegebene Schreibweise f"ur Literale ist ziemlich abstrus und erinnert an die auf IBM 360/370-Systemen "ubliche Schreibweise (Gr"u"se aus Neandertal...). Um nicht noch einen Zweig in den Parser einf"ugen zu m"ussen, sind bei AS Konstanten in Motorola-Syntax zu schreiben (wahlweise auch Intel oder C im \tty{RELAXED}-Modus). \par Dem Assembler liegt die Include-Datei STDDEF16.INC bei, in der die Adressen der Hardware-Register und Statusbits verewigt sind. Daneben enth"alt sie eine Liste von ,,Befehlen'', die der Microchip-Assembler als Makro implementiert. Bei der Benutzung dieser Befehlsmakros ist gro"se Vorsicht angebracht, da sie mehrere Worte lang sind und sich somit nicht "uberspringen lassen!! %%--------------------------------------------------------------------------- \section{PIC17C4x} F"ur diese Prozessoren gelten im wesentlichen die gleichen Hinweise wie f"ur ihre kleinen Br"uder, mit zwei Ausnahmen: Die zugeh"orige Include-Datei enth"alt nur Registerdefinitionen, und die Probleme bei Sprungbefehlen sind deutlich kleiner. Aus der Reihe f"allt nur \tty{LCALL}, der einen 16-Bit-Sprung erlaubt. Dieser wird mit folgendem ,,Makro'' "ubersetzt: \begin{verbatim} MOVLW MOWF 3 LCALL \end{verbatim} %%--------------------------------------------------------------------------- \section{ST6} Diese Prozessoren k"onnen das Code-ROM seitenweise in den Datenbereich einblenden. Weil ich nicht die ganze Mimik des \tty{ASSUME}-Befehles hier wiederk"auen m"ochte, verweise ich auf das entsprechende Kapitel (\ref{ST6Assume}), in dem steht, wie man mit diesem Befehl einigerma"sen unfallfrei Konstanten aus dem ROM lesen kann. \par Bei n"ahererer Betrachtung des Befehlssatzes fallen einige eingebaute ,,Makros'' auf. Die Befehle, die mir aufgefallen sind (es gibt aber vielleicht noch mehr...), sind in Tabelle \ref{TabHid62} aufgelistet. \par \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|l|} \hline Befehl & in Wirklichkeit \\ \hline \hline \tty{CLR A} & \tty{SUB A,A} \\ \tty{SLA A} & \tty{ADD A,A} \\ \tty{CLR adr} & \tty{LDI adr,0} \\ \tty{NOP} & \tty{JRZ PC+1} \\ \hline \end{tabular}\end{center} \caption{versteckte Makros im ST6225-Befehlssatz\label{TabHid62}} \end{table*} Insbesondere der letztere Fall verbl"ufft doch etwas... Leider fehlen aber einige Anweisungen wirklich. So gibt es z.B. zwar einen \tty{AND}-Befehl, aber kein \tty{OR}...von \tty{XOR} gar nicht zu reden. In der Datei STDDEF62.INC finden sich deshalb neben den Adressen der SFRs noch einige Makros zur Abhilfe. \par Der Original-Assembler AST6 von SGS-Thomson verwendet teilweise andere Pseudobefehle als AS. Au"ser der Tatsache, da"s AS Pseudobefehle nicht mit einem vorangestellten Punkt kennzeichnet, sind folgende Befehle identisch: \begin{verbatim} ASCII, ASCIZ, BLOCK, BYTE, END, ENDM, EQU, ERROR, MACRO, ORG, TITLE, WARNING \end{verbatim} Tabelle \ref{TabAST6} zeigt die AST6-Befehle, zu denen analoge in AS existieren. \par \begin{table*}[htbp] \begin{center}\begin{tabular}{|l|l|l|} \hline AST6 & AS & Bedeutung/Funktion \\ \hline \hline \tty{.DISPLAY} & \tty{MESSAGE} & Meldung ausgeben \\ \hline \tty{.EJECT} & \tty{NEWPAGE} & neue Seite im Listing \\ \hline \tty{.ELSE} & \tty{ELSEIF} & bed. Assemblierung \\ \hline \tty{.ENDC} & \tty{ENDIF} & bed. Assemblierung \\ \hline \tty{.IFC} & \tty{IF...} & bed. Assemblierung \\ \hline \tty{.INPUT} & \tty{INCLUDE} & Include-Datei einbinden \\ \hline \tty{.LIST} & \tty{LISTING}, \tty{MACEXP} & Listing-Einstellung \\ \hline \tty{.PL} & \tty{PAGE} & Seitenl"ange Listing \\ \hline \tty{.ROMSIZE} & \tty{CPU} & Zielprozessor einstellen \\ \hline \tty{.VERS} & \tty{VERSION} (Symbol) & Version abfragen \\ \hline \tty{.SET} & \tty{EVAL} & Variablen neu setzen \\ \hline \end{tabular}\end{center} \caption{"aquivalente Befehle AST6$\leftrightarrow$AS\label{TabAST6}} \end{table*} %%--------------------------------------------------------------------------- \section{ST7} In \cite{ST7Man} ist der '.w'-Postfix f"ur 16-Bit-Adressen nur f"ur speicherindirekte Operanden definiert, um zu vermerken, da"s auf einer Zeropageadresse eine 16-bittige Adresse liegt; AS unterst"utzt ihn jedoch zus"atzlich auch f"ur absolute Adressen oder Displacements in indizierter Adressierung, um trotz eines nur 8 Bit langen Wertes (0..255) ein 16-bittiges Displacement zu erzeugen. %%--------------------------------------------------------------------------- \section{ST9} Die Bitadressierungsm"oglichkeiten des ST9 sind relativ eingeschr"ankt: Mit Ausnahme des \tty{BTSET}-Befehls ist es nur m"oglich, auf Bits innerhalb des aktuellen Arbeitsregistersatzes zuzugreifen. Eine Bit-Adresse sieht also folgenderma"sen aus: \begin{verbatim} rn.[!]b \end{verbatim} wobei \verb?!? eine optionale Invertierung eines Quelloperanden bedeutet. Wird ein Bit symbolisch mittels des \tty{BIT}-Befehles definiert, so wird die Registernummer im Symbolwert in Bit 7..4, die Bitnummer in Bit 3..1 und eine optionale Invertierung in Bit 0 vermerkt. AS unterscheidet direkte und symbolische Bitangaben am Fehlen eines Punktes, der Name eines Bitsymboles darf also keinen Punkt enthalten, obwohl sie an sich zul"assig w"aren. Es ist auch zul"assig, bei der Referenzierung von Bitsymbolen diese zu nachtr"aglich zu invertieren: \begin{verbatim} bit2 bit r5.3 . . bld r0.0,!bit2 \end{verbatim} Auf diese Weise ist es auch m"oglich, eine inverse Definition nachtr"aglich wieder aufzuheben. \par Bitdefinitionen finden sich in gro"ser Zahl in der Include-Datei REGST9.INC, in der die Register- und Bitnamen aller On-Chip-Peripherie beschrieben sind. Beachten Sie jedoch, da"s deren Nutzung nur m"oglich ist, wenn die Arbeitsregisterbank vorher auch auf diese Register ausgerichtet wurde! \par Im Gegensatz zu der zum AST9 von SGS-Thomson geh"orenden Definitionsdatei sind f"ur AS die Namen der Peripherieregister nur als allgemeine Registernamen definiert (\tty{R...}), nicht auch noch als Arbeitsregister (\tty{r...}). Dies ist so, weil AS Geschwindigkeitsgr"unden keine Aliasnamen f"ur Register definieren kann. %%--------------------------------------------------------------------------- \section{6804} Eigentlich habe ich diesen Prozessor ja nur eingebaut, um mich "uber das seltsame Gebaren von SGS-Thomson zu beklagen: Als ich das 6804-Datenbuch zum ersten Mal in die Hand bekam, f"uhlte ich mich ob des etwas ,,unvollst"andigen'' Befehlssatzes und der eingebauten Makros spontan an die ST62-Serie vom gleichen Hersteller erinnert. Ein genauerer Vergleich der Opcodes f"orderte erstaunliches zu Tage: Ein 6804-Opcode ergibt sich durch Spiegelung aller Bits im entsprechenden ST62-OpCode! Thomson hat hier also offensichtlich etwas Prozessorkern-Recycling betrieben...wogegen ja auch nichts einzuwenden w"are, wenn nicht so eine Verschleierungstaktik betrieben werden w"urde: andere Peripherie, Motorola- anstelle Zilog-Syntax sowie das h"a"sliche Detail, in Opcodes enthaltene Argumente (z.B. Bitfelder mit Displacements) \bb{nicht} zu drehen. Letzterer Punkt hat mich auch nach l"angerem "Uberlegen dazu bewogen, den 6804 doch in AS aufzunehmen. Ich wage "ubrigens keine Spekulationen, welche Abteilung bei Thomson von welcher abgekupfert hat... \par Im Gegensatz zur ST62-Version enth"alt die Include-Datei f"ur den 6804 keine Makros, die die L"ucken im Befehlssatz etwas ,,auspolstern'' sollen. Dies "uberlasse ich dem geneigten Leser als Finger"ubung! %%--------------------------------------------------------------------------- \section{TMS3201x} Offensichtlich ist es Ehrgeiz jedes Prozessorherstellers, seine eigene Notation f"ur Hexadezimalkonstanten zu erfinden. Texas Instruments war bei diesen Prozessoren besonders originell: ein vorangestelltes $>$-Zeichen! Die "Ubernahme dieses Formates in AS h"atte zu schweren Konflikten mit den Vergleichs-und Schiebeoperatoren von AS im Formelparser gef"uhrt. Ich habe mich deshalb f"ur die Intel-Notation entschieden, zu der sich TI bei der 340x0-Serie und den 3201x-Nachfolgern ja dann auch durchgerungen hat... \par Leider hat das Instruktionswort dieser Prozessoren nicht gen"ugend Bits, um bei direkter Adressierung alle 8 Bits zu enthalten, weshalb der Datenadre"sraum logisch in 2 B"anke zu 128 W"ortern gespalten ist. AS verwaltet diesen als ein durchgehendes Segment von 256 W"ortern und l"oscht bei direkten Zugriffen automatisch das Bit 7 (Ausnahme: Befehl \tty{SST}, der nur in die obere Bank schreiben kann). Der Programmierer ist daf"ur erforderlich, da"s das Bank-Bit stets den richtigen Wert hat! \par Ein weiterer, nur sehr versteckt im Datenbuch stehender Hinweis: Die \tty{SUBC}-Anweisung ben"otigt zur Ausf"uhrung intern mehr als einen Takt, das Steuerwerk arbeitet jedoch schon an dem n"achsten Befehl weiter. Im auf ein \tty{SUBC} folgenden Befehl darf deshalb nicht auf den Akkumulator zugegriffen werden. AS nimmt hier \bb{keine} Pr"ufung vor! %%--------------------------------------------------------------------------- \section{TMS320C2x} Da ich nicht selber diesen Codegenerator geschrieben habe (was nichts an seiner Qualit"at mindert), kann ich nur kurz hier umrei"sen, wieso es Befehle gibt, bei denen ein vorangestelltes Label als untypisiert, d.h. keinem Adre"sraum zugeordnet, gespeichert wird: Der 20er der TMS-Reihe kennt sowohl ein 64 Kbyte gro"ses Code- als auch Datensegment. Je nach externer Beschaltung kann man dabei Code- und Datenbereiche "uberlappen, um z.B. Konstanten im Codebereich zu abzulegen und auf diese als Daten zuzugreifen (Ablage im Code ist notwendig, weil "altere AS-Versionen davon ausgehen, da"s ein Datensegment aus RAM besteht, das in einem Standalone-System nach dem Einschalten keinen definierten Inhalt hat und verweigern in Segmenten au"ser Code deshalb die Ablage von Daten). Ohne dieses Feature w"urde AS nun jeden Zugriff auf die abgelegten Daten mit einer Warnung (,,Symbol aus falschem Segment'') quittieren. Im einzelnen erzeugen folgende Pseudobefehle untypisierte Labels: \begin{quote} {\tt BSS, STRING, RSTRING, BYTE, WORD , LONG, FLOAT \\ DOUBLE, EFLOAT, BFLOAT} und {\tt TFLOAT} \end{quote} Sollten doch einmal typisierte Labels gew"unscht sein, so kann man sich behelfen, indem man das Label in eine getrennte Zeile vor dem Pseudobefehl schreibt. Umgekehrt kann man einen der anderen Pseudobefehle mit einem typenlosen Label versehen, indem man vor dem Befehl das Label mit \begin{verbatim} EQU $ \end{verbatim} definiert. %%--------------------------------------------------------------------------- \section{TMS320C3x} Die gr"o"sten Magenschmerzen bei diesem Prozessor hat mir die Syntax paralleler Befehle bereitet, die auf zwei Zeilen verteilt werden, wobei beide Befehle an sich auch sequentiell ausgef"uhrt werden k"onnen. Deshalb erzeugt AS zuerst den Code f"ur die einzelne erste Operation, wenn er dann in der zweiten Zeile erkennt, da"s eine parallele Aweisung vorliegt, wird der zuerst erzeugte Code durch den neuen ersetzt. Im Listing kann man dies daran erkennen, da"s der Programmz"ahler nicht weiterl"auft und in der zweiten Zeile anstelle eines Doppelpunktes ein \tty{R} vor dem erzeugten Code steht. \par Bez"uglich der doppelten senkrechten Striche und ihrer Position in der Zeile ist man nicht ganz so flexibel wie beim TI-Assembler: Entweder man schreibt sie anstelle eines Labels (d.h. in der ersten Spalte oder mit einem angeh"angten Doppelpunkt, das ist aber nicht mehr TI-kompatibel...) oder direkt vor den zweiten Befehl ohne Leerzeichen, sonst bekommt der Zeilenparser von AS Probleme und h"alt die Striche f"ur das Mnemonic. %%--------------------------------------------------------------------------- \section{TMS9900} Wie bei den meisten "alteren Prozessorfamilien auch, hatte TI seinerzeit ein eigenes Format zur Schreibweise von Hexadezimal- und Bin"arkonstanten verwendet, anstelle deren AS die normale, heute auch bei TI gebr"auchliche Intel-Notation verwendet. Die TI-Syntax f"ur Register erlaubt es, da"s anstelle eines echten Namens (entweder \tty{Rx} oder \tty{WRx}) auch eine einfache Integer-Zahl zwischen 0 und 15 benutzt werden kann. Dies hat zwei Folgen: \begin{itemize} \item{\tty{R0...R15} bzw. \tty{WR0..WR15} sind einfache, vordefinierte Integersymbole mit den Werten 0..15, und die Definition von Registeraliasen funktioniert "uber schlichte \tty{EQUs}.} \item{Im Gegensatz zu einigen anderen Prozessoren kann ich nicht das zus"atzliche AS-Feature anbieten, da"s das Kennzeichen f"ur absolute Adressierung (hier ein Klammeraffe) weggelassen werden darf. Da ein fehlendes Kennzeichen hier aber Registernummern (im Bereich 0 bis 15) bedeuten w"urde, war das hier nicht m"oglich.} \end{itemize} Weiterhin wechselt TI mit der Registerbezeichnung zwischen \tty{Rx} und \tty{WRx}...vorerst ist beides zugelassen. %%--------------------------------------------------------------------------- \section{TMS70Cxx} Diese Prozessorreihe geh"ort noch zu den "alteren, von TI entwickelten Reihen, und deswegen benutzt TI in ihren eigenen Assemblern noch die herstellereigene Syntax f"ur hexadezimale und bin"are Konstanten (vorangestelltes $<$ bzw. ?). Da das in AS aber so nicht machbar ist, wird defaultm"a"sig die Intel-Syntax verwendet. Auf diese ist Texas bei den Nachfolgern dieser Familie, n"amlich den 370ern auch umgestiegen. Beim genaueren Betrachten des Maschinenbefehlssatzes stellt man fest, da"s ca. 80\% der 7000er-Befehle bin"ar aufw"artskompatibel sind, und auch die Assemblersyntax ist fast gleich - aber eben nur fast. Bei der Erweiterung des 7000er-Befehlssatzes hat TI n"amlich auch gleich die Chance genutzt, die Syntax etwas zu vereinheitlichen und zu vereinfachen. Ich habe mich bem"uht, einen Teil dieser "anderungen auch in die 7000er Syntax einflie"sen zu lassen: \begin{itemize} \item{Anstelle eines Prozentzeichens zur Kennzeichnung von unmittelbarer Adressierung darf auch das allgemein bekanntere Doppelkreuz verwendet werden.} \item{Wenn bei den Befehlen \tty{AND, BTJO, BTJZ, MOV, OR} und \tty{XOR} eine Port-Adresse (\tty{P...}) als Quelle oder Ziel benutzt wird, ist es nicht notwendig, die Mnemonic-Form mit explizit angeh"angtem \tty{P} zu benutzen - die allgemeine Form reicht genauso aus.} \item{Der vorangestelle Klammeraffe f"ur absolute oder B-indizierte Adressierung darf weggelassen werden.} \item{Anstelle des \tty{CMPA}-Befehls darf auch einfach \tty{CMP} mit \tty{A} als Ziel benutzt werden.} \item{Anstelle \tty{LDA} oder \tty{STA} darf auch einfach der \tty{MOV}-Befehl mit \tty{A} als Ziel bzw. Quelle benutzt werden.} \item{Anstelle des \tty{MOVD}-Befehls darf auch \tty{MOVW} benutzt werden.} \item{Anstelle von \tty{RETS} oder \tty{RETI} darf auch verk"urzt \tty{RTS} bzw. \tty{RTI} geschrieben werden.} \item{\tty{TSTA} bzw. \tty{TSTB} d"urfen auch als \tty{TST A} bzw. \tt{TST B} geschrieben werden.} \item{\tty{XCHB B} ist als Alias f"ur \tty{TSTB} zugelassen.} \end{itemize} Wichtig - diese Varianten sind nur beim TMS70Cxx zugelassen - entsprechende 7000er-Varianten sind bei den 370ern {\em nicht} erlaubt! %%--------------------------------------------------------------------------- \section{TMS370xxx} Obwohl diese Prozessoren keine speziellen Befehle zur Bitmanipulation besitzen, wird mit Hilfe des Assemblers und des \tty{DBIT}-Befehles (siehe dort) die Illusion erzeugt, als ob man einzelne Bits manipulieren w"urde. Dazu wird beim \tty{DBIT}-Befehl eine Adresse mit einer Bitposition zusammengefa"st und in einem Symbol abgelegt, das man dann als Argument f"ur die Pseudobefehle \tty{SBIT0, SBIT1, CMPBIT, JBIT0} und \tty{JBIT1} verwenden kann. Diese werden in die Befehle \tty{OR, AND, XOR, BTJZ} und \tty{BTJO} mit einer passenden Bitmaske "ubersetzt. \par An diesen Bit-Symbolen ist "uberhaupt nichts geheimnisvolles, es handelt sich um schlichte Integerwerte, in deren unterer H"alfte die Speicheradresse und in deren oberer H"alfte die Bitstelle gespeichert wird. Man k"onnte sich seine Symbole also auch ohne weiteres selber basteln: \begin{verbatim} defbit macro name,bit,adr name equ adr+(bit<<16) endm \end{verbatim} aber mit dieser Schreibweise erreicht man nicht den \tty{EQU}-artigen Stil, den Texas vorgegeben hat (d.h. das zu definierende Symbol steht anstelle eines Labels). ACHTUNG! Obwohl \tty{DBIT} eine beliebige Adresse zul"a"st, k"onnen f"ur die Pseudobefehle nur die Adressen 0..255 und 1000h..10ffh verwendet werden, eine absolute Adressierungsart kennt der Prozessor an dieser Stelle nicht... %%--------------------------------------------------------------------------- \section{MSP430} \label{MSPSpec} Der MSP430 wurde als RISC-Prozessor mit minimalem Stromverbrauch konzipiert. Aus diesem Grund ist der Satz von Befehlen, die der Prozessor in Hardware versteht, auf das absolut notwendige reduziert worden (da RISC-Prozessoren keinen Mikrocode besitzen, mu"s jeder Befehl mit zus"atzlichem Silizium implementiert werden und erh"oht so den Stromverbrauch). Eine Reihe von Befehlen, die bei anderen Prozessoren in Hardware gegossen wurden, werden beim MSP durch eine Emulation mit anderen Befehlen realisiert. Bei AS finden sich diese Befehle mit in der Datei \tty{REGMSP.INC}. Wer diese Datei nicht einbindet, wird bei "uber der H"alfte der insgesamt von TI definierten Befehle Fehlermeldungen bekommen!! %%--------------------------------------------------------------------------- \section{COP8 \& SC/MP} \label{COP8Spec} Leider Gottes hat sich auch National dazu entschieden, als Schreibweise f"ur nichtdezimale Integer-Konstanten die von IBM-Gro"srechnern bekannte (und von mir vielgeha"ste) Variante \verb!X'...! zu benutzen. Das geht nat"urlich (wie immer) nicht. Zum Gl"uck scheint der ASMCOP aber auch die C-Variante zuzulassen, und diese wurde deshalb der Default f"ur die COPs... %%--------------------------------------------------------------------------- \section{SC144xxx} \label{SC144xxspec} Original gab es f"ur diese Reihe von DECT-Controllern mit relativ einfachem Befehlssatz nur einen sehr schlichten Assembler von National selber. Ein Assembler von IAR Systems ist angek"undigt, aber noch nicht erh"altlich. Da die Entwicklungstools von IAR allerdings auch nach M"oglichkeit CPU-unabh"angig angelegt sind, kann man anhand erh"altlicher Zielplattformen in ungef"ahr absch"atzen, wie dessen Pseudobefehle aussehen werden, und damit im Blick sind die (wenigen) SC144xx-spezifisch realisierten Befehle {\tt DC, DC8, DW16, DS, DS8, DS16, DW} angelegt. Bei Befehlen, die bereits im AS-Kern angelegt sind, wollte ich nat"urlich nicht das Rad neu erfinden, deshalb hier eine Tabelle mit "Aquivalenzen: Die Befehle \tty{ALIGN, END, ENDM, EXITM, MACRO, ORG, RADIX, SET} und \tty{REPT} exisieren sowohl bei IAR als auch AS und haben gleiche Bedeutung. Bei folgenden Befehlen mu"s man umstellen: \begin{table*}[htb] \begin{center}\begin{tabular}{|l|l|l|} \hline IAR & AS & Funktion\\ \hline \hline \tty{\#include} & \tty{include} & Include-Datei einbinden \\ \tty{\#define} & \tty{SET, EQU} & Symbole definieren \\ \tty{\#elif, ELIF, ELSEIF} & \tty{ELSEIF} & Weiterer Zweig einer IF-Kette \\ \tty{\#else, ELSE} & \tty{ELSE} & Letzter Zweig einer IF-Kette \\ \tty{\#endif, ENDIF} & \tty{ENDIF} & Beendet eine IF-Kette \\ \tty{\#error} & \tty{ERROR, FATAL} & Fehlermeldung erzeugen \\ \tty{\#if, IF} & \tty{IF} & Beginn einer IF-Kette\\ \tty{\#ifdef} & \tty{IFDEF} & Symbol definiert ? \\ \tty{\#ifndef} & \tty{IFNDEF} & Symbol nicht definiert ? \\ \tty{\#message} & \tty{MESSAGE} & Nachricht ausgeben \\ \tty{=, DEFINE, EQU} & \tty{=, EQU} & Feste Wertzuweisung \\ \tty{EVEN} & \tty{ALIGN 2} & Programmz"ahler gerade machen \\ \tty{COL, PAGSIZ} & \tty{PAGE} & Seitengr"o"se f"ur Listing setzen \\ \tty{ENDR} & \tty{ENDM} & Ende einer REPT-Struktur \\ \tty{LSTCND, LSTOUT} & \tty{LISTING} & Umfang des Listings steuern \\ \tty{LSTEXP, LSTREP} & \tty{MACEXP} & Expandierte Makros anzeigen? \\ \tty{LSTXRF} & \verb!! & Querverweisliste erzeugen \\ \tty{PAGE} & \tty{NEWPAGE} & Neue Seite im Listing \\ \tty{REPTC} & \tty{IRPC} & Repetition mit Zeichenersetzung \\ \hline \end{tabular}\end{center} \end{table*} Keine direkte Entsprechung gibt es f"ur die Befehle {\tt CASEON, CASEOFF, LOCAL, LSTPAG, \#undef} und {\tt REPTI}. Ein direktes "Aquivalent der Pr"aprozessorbefehle ist nat"urlich nicht m"oglich, solange AS keinen C-artigen Pr"aprozessor besitzt. C-artige Kommentare sind im Moment leider auch nicht m"oglich. Achtung: Wer IAR-Codes f"ur AS umsetzt, mu"s die Pr"aprozessorstatements nicht nur umwandeln, sondern auch aus Spalte 1 herausbewegen, da bei AS in Spalte 1 nur Labels stehen d"urfen! %%--------------------------------------------------------------------------- \section{75K0} \label{75K0Spec} Wie bei einigen anderen Prozessoren auch, kennt die Assemblersprache der 75er von NEC Pseudo-Bitoperanden, d.h. man kann einem Symbol eine Kombination aus Adresse und Bitnummer zuweisen, die dann bei bitorientierten Befehlen anstelle direkter Ausdr"ucke verwendet werden kann. Die drei folgenden Befehle erzeugen daher z.B. identischen Code: \begin{verbatim} ADM sfr 0fd8h SOC bit ADM.3 skt 0fd8h.3 skt ADM.3 skt SOC \end{verbatim} AS unterscheidet direkte und symbolische Bitzugriffe an einem bei Symbolen fehlenden Punkt; Punkte in Symbolnamen darf man daher nicht verwenden, da es sonst zu Mi"sverst"andnissen bei der Aufl"osung kommt. \par Die Ablage von Bitsymbolen orientiert sich dabei weitgehend an der bin"aren Kodierung, die die Prozessorhardware selber verwendet: Es werden 16 Bit belegt, und es existieren ein ,,kurzes'' und ein ,,langes'' Format. Das kurze Format kann folgende Varianten aufnehmen: \begin{itemize} \item{direkte Zugriffe auf die Bereiche 0FBxH und 0FFxH} \item{indirekte Zugriffe der Form Adr.@L (0FC0H $\leq$ \tty{Adr} $\leq$ 0FFFH)} \item{indirekte Zugriffe der Form @H+d4.bit} \end{itemize} Das obere Byte ist auf 0 gesetzt, das untere Byte enth"alt den gem"a"s \cite{NEC75} kodierten Bitausdruck. Das lange Format kennt im Gegensatz dazu nur direkte Adressierung, kann daf"ur aber (korrekte Einstellungen von \tty{MBS} und \tty{MBE} vorausgesetzt) den ganzen Adre"sraum abdecken. Bei langen Ausdr"ucken stehen im unteren Byte Bit 7..0 der Adresse, in Bit 8 und 9 die Bitstelle sowie in Bit 10 und 11 konstant 01. Letztere erm"oglichen es, langes und kurzes Format einfach durch einen Vergleich des oberen Bytes gegen Null zu unterscheiden. Die Bits 12..15 enthalten Bit 8..11 der Adresse; sie werden zwar nicht zur Generierung des Kodes ben"otigt, m"ussen jedoch gespeichert werden, da eine Pr"ufung auf ein korrektes Banking erst bei der Verwendung des Symboles erfolgen kann. %%--------------------------------------------------------------------------- \section{78K0} \label{78K0Spec} NEC benutzt in seinen Datenb"uchern zur Kennzeichnung der Zugriffsweise auf absolute Adressen verschiedene Schreibweisen: \begin{itemize} \item{absolut kurz: kein Pr"afix} \item{absolut lang: vorangestelltes \verb"!"} \item{PC-relativ: vorangestelltes \verb"$"} \end{itemize} Bei AS sind diese Pr"afixe nur notwendig, falls man eine bestimmte Adressierung erzwingen will und der Befehl verschiedene Varianten zul"a"st. Setzt man keinen Pr"afix, so w"ahlt AS automatisch die k"urzeste Variante. Es d"urfte daher in der Praxis sehr selten notwendig sein, einen Pr"afix zu verwenden. %%--------------------------------------------------------------------------- \section{$\mu$PD772x} Sowohl 7720 als auch 7725 werden von dem gleichen Codegenerator behandelt und sind sich in ihren Befehlssatz extrem "ahnlich. Trotzdem sollte man sich nicht zu der Annahme verleiten lassen, sie seien bin"ar kompatibel: Um die l"angeren Adre"sfelder und zus"atzlichen Befehle unterbringen zu k"onnen, haben sich die Bitpositionen einiger Felder im Instruktionswort verschoben, die Instruktionsl"ange hat sich auch insgesamt von 23 auf 24 Bit ge"andert. Im Code-Format sind deshalb auch unterschiedliche Header-Ids f"ur beide reserviert. Gemeinsam ist beiden, da"s sie neben Code- und Datensegment auch noch ein ROM zur Ablage von Konstanten besitzen. Dieses ist bei AS auf das \tty{ROMDATA}-Segment abgebildet! %%=========================================================================== \cleardoublepage \chapter{Dateiformate} In diesem Kapitel sollen die Formate von von AS erzeugten Dateien beschrieben werden, deren Format sich nicht direkt erschlie"st. \section{Code-Dateien} \label{SectCodeFormat} Das vom Assembler ausgegebene Codedatenformat mu"s in der Lage sein, die Codeteile f"ur unterschiedliche Prozessoren voneinander zu trennen, und sieht daher etwas anders aus als g"angige Formate. Obwohl dem Assembler Tools zur Bearbeitung der Codedateien beiliegen, halte ich es f"ur guten Stil, das Format hier kurz offenzulegen: \par Sofern in der Datei Mehrbyte-Integers gespeichert sind, werden sie im Intelformat abgelegt, d.h. mit dem LSB zuerst. Diese Regel gilt bereits f"ur das 16-Bit-Kennungswort mit dem Wert \$1489, d.h. jede Codedatei beginnt mit den Bytes \$89/\$14. \par Danach folgt eine Reihe beliebig vieler ,,Records'', wobei ein Record entweder ein zusammenh"angendes Teilfeld des Codes darstellt oder bestimmte Zusatzinformationen enth"alt. Eine Datei kann auch ohne Umschaltung des Prozessortyps mehrere Records enthalten, wenn Code- oder Konstantenbereiche durch reservierte (und nicht zu initialisierende) Speicherbereiche unterbrochen werden. Der Assembler versucht auf diese Weise, die Datei nicht l"anger als n"otig werden zu lassen. \par Allen Records ist gemein ist ein Header-Byte, das den Typ des Records und die damit folgenden Datenstrukturen festlegt. In einer Pascal-artigen Form l"a"st sich die Record-Struktur folgenderma"sen beschreiben: \begin{verbatim} FileRecord = RECORD CASE Header:Byte OF $00:(Creator:ARRAY[] OF Char); $01.. $7f:(StartAdr : LongInt; Length : Word; Data : ARRAY[0..Length-1] OF Byte); $80:(EntryPoint:LongInt); $81:(Header : Byte; Segment : Byte; Gran : Byte; StartAdr : LongInt; Length : Word; Data : ARRAY[0..Length-1] OF Byte); END \end{verbatim} Was in dieser Schreibweise nicht ganz zum Ausdruck kommt, ist, da"s die L"ange von Datenfeldern variabel ist und von {\tt Length} abh"angt. \par Ein Record mit einem Header-Byte von \verb!$81! ist ein Record, der Code oder Daten aus beliebigen Segmenten beinhalten kann. Das erste Byte (Header) gibt an, f"ur welche Prozessorfamilie die folgenden Daten bzw. der folgende Code bestimmt ist (siehe Tabelle \ref{TabHeader}). \begin{table*}[htbp] \begin{center}\begin{tabular}{|c|l||c|l|} \hline Header & Familie & Header & Familie \\ \hline \hline \input{tabids.tex} \end{tabular}\end{center} \caption{Headerbytes f"ur die verschiedenen Prozessorfamilien\label{TabHeader}} \end{table*} Das Segment-Feld gibt an, in welchen Adre"sraum des Prozessors der folgende Code geh"ort. Dabei gilt die in Tabelle \ref{TabSegments} angegeben Zuordnung. \begin{table*}[htbp] \begin{center}\begin{tabular}{|c|l||c|l|} \hline Nummer & Segment & Nummer & Segment \\ \hline \hline \$00 & $<$undefiniert$>$ & \$01 & CODE \\ \$02 & DATA & \$03 & IDATA \\ \$04 & XDATA & \$05 & YDATA \\ \$06 & BDATA & \$07 & IO \\ \$08 & REG & \$09 & ROMDATA \\ \hline \end{tabular}\end{center} \caption{Kodierungen des {\tt Segment}-Feldes\label{TabSegments}} \end{table*} Das Gran-Feld gibt die ,,Granularit"at'' des Codes an, d.h. die Gr"o"se der kleinsten, adressierbaren Einheit im folgenden Datensatz. Dieser Wert ist eine Funktion von Prozessortyp und Segment und ein wichtiges Detail f"ur die Interpretation der beiden folgenden Felder, die Startadresse und L"ange angeben: W"ahrend die Startadresse sich auf die Granularit"at bezieht, erfolgt die L"angenangabe immer in Bytes! W"are die Startadresse z.B. \$300 und die L"ange 12, so w"are die sich ergebende Endadresse bei einer Granularit"at von 1 \$30b, bei einer Granularit"at von z.B. 4 jedoch \$303! Andere Granularit"aten als eins sind selten und treten in erster Linie bei Signalprozessoren auf, die nicht auf Einzelbyteverarbeitung ausgelegt sind deren Datenspeicher z.B. aus 64kWorten zu 16 Bit besteht (DSP56K). Der sich ergebende Speicherplatz betr"agt dann zwar 128 KByte, er ist aber in $2^{16}$ Worten organisiert, die mit Adressen von 0,1,2,...65535 adressiert werden! \par Die Startadresse ist 32-bittig, unabh"angig von der Adre"sbreite der jeweiligen Prozessorfamilie. Im Gegensatz dazu ist die L"angenangabe nur 16 Bit lang, ein Record kann also maximal (4+4+2+(64K-1)) = 65545 Byte lang werden. \par Daten-Records mit den Header-Bytes \verb!$01..$7f! stellen eine Kurzschreibweise dar und stellen die Abw"artskompatibilit"at mit fr"uheren Definitionen des Dateiformats her: Das Header-Byte gibt direkt den Prozessortyp gem"a"s der ersten Tabelle an, das Zielsegment ist auf \tty{CODE} festgelegt und die Granularit"at ergibt sich aus dem Prozessortyp, aufgerundet auf eine Zweierpotenz von Bytes. AS bevorzugt diese Records, wenn Daten bzw. Code f"ur das \tty{CODE}-Segment anstehen. \par Der Record mit dem Typ-Byte \verb!$80! legt den Einsprungpunkt fest, d.h. die Adresse, an der mit der Ausf"uhrung des Programmes begonnen werden soll. Ein solcher Record ist das Ergebnis einer \tty{END}-Anweisung mit einer entsprechenden Adresse als Argument. \par Der letzte Record in der Datei tr"agt das Header-Byte \verb!$00! und besitzt als einziges Datenfeld einen String, dessen Ende durch das Dateiende definiert ist. Dieser String spezifiziert, von welchem Programm diese Datei erzeugt wurde und hat keine weitere Bedeutung. \section{Debug-Dateien}\label{SectDebugFormat} Debug-Dateien k"onnen optional von AS erzeugt werden und liefern nachgeschalteten Werkzeugen wie Disassemblern oder Debuggern f"ur diese wichtige Informationen. AS kann Debug-Informationen in drei Formaten ausgeben: Zum einen im Objekt-Format der AVR-Tools von Atmel sowie eine zu NoICE kompatible Kommandodatei und zum anderen in einem eigenen Format. Die ersten beiden werden in \cite{AVRObj} bzw. der Dokumentation zu NoICE ausf"uhrlich beschrieben, deshalb beschr"ankt sich die folgende Beschreibung auf das AS-eigene MAP-Format: Diese Informationen in einer MAP-Datei teilen sich in drei Gruppen: \begin{itemize} \item{Symboltabelle} \item{Speicherberlegung, auf Sektionen verteilt} \item{Maschinenadressen von Quellzeilen} \end{itemize} Letzterer Teil findet sich zuerst in der Datei. Ein einzelner Eintrag in dieser Liste besteht aus zwei, von einem Doppelpunkt getrennten Zahlen: \begin{verbatim} : \end{verbatim} Ein solcher Eintrag besagt, da"s der aus einer bestimmten Quellcodezeile erzeugte Maschinencode auf der angegebenen Adresse (hexadezimal) zu liegen kam. Mit einer solchen Information kann ein Debugger beim Durchsteppen des Programmes die entsprechenden Quellcodezeilen anzeigen. Da ein Programm aber auch aus mehreren Include-Dateien bestehen kann, und viele Prozessoren mehr als nur einen Adre"sraum besitzen (von dem zugegebenerma"sen nur in einem Code liegt), m"ussen die oben beschriebenen Eintr"age sortiert werden. AS tut dies in zwei Stufen: Das prim"are Sortierkriterium ist das Zielsegment, innerhalb dieser Segmente wird noch einmal nach Dateien sortiert. Einzelne Abschnitte werden dabei durch durch spezielle Zeilen der Form \begin{verbatim} Segment \end{verbatim} bzw. \begin{verbatim} File \end{verbatim} getrennt. Die Symboltabelle folgt der Quellzeileninformation und ist wieder prim"ar nach den Segmenten geordnet, aus denen die Symbole stammen. Im Gegensatz zur Zeileninformation kommt hier allerdings auch der Abschnitt \tty{NOTHING} hinzu, der die Symbole beinhaltet, die keinem speziellen Adre"sraum zugeordnet sind (z.B. Symbole, die einfach mit \tty{EQU} definiert wurden). Die Einleitung eines Abschnittes in der Symboltabelle erfolgt mit einer Zeile der Form \begin{verbatim} Symbols in Segment . \end{verbatim} Innerhalb eines Abschnittes sind die Symbole nach Namen sortiert, und ein Symboleintrag belegt genau eine Zeile. Eine solche Zeile besteht wiederum aus 5 Feldern, die durch jeweils mindestens ein Leerzeichen getrennt sind: Das erste Feld ist der Name des Symbols selber, eventuell erweitert um eine in eckigen Klammern eingeschlossene Sektionsnummer, die den G"ultigkeitsbereich des Symbols einschr"ankt. Die zweite Spalte bezeichnet den Typ des Symbols: \tty{Int} f"ur Integerzahlen, \tty{Float} f"ur Gleitkommazahlen und \tty{String} f"ur Zeichenketten. Die dritte Zeile schlie"slich beinhaltet den eigentliche Wert des Symbols. Falls das Symbol eine Zeichenkette beinhaltet, ist es notwendig, Steuer- und Leerzeichen mit einer gesonderten Notation zu kennzeichnen, damit ein im String enthaltenes Leerzeichen nicht eventuell als Trennzeichen zur n"achsten Spalte interpretiert werden kann. AS bedient sich dazu der bereits der in Assemblerquellen "ublichen Schreibweise, den ASCII-Zahlenwert mit einem f"uhrenden Backslash (\verb!\!) einzusetzen. Aus dem String \begin{verbatim} Dies ist ein Test \end{verbatim} wird also z.B. \begin{verbatim} Dies\032ist\032ein\032Test \end{verbatim} Die Zahlenangabe ist immer dezimal und dreistellig, und der Backslash selber wird ebenfalls in dieser Schreibweise kodiert. Das vierte Feld gibt - falls vorhanden - die Gr"o"se der Datenstruktur an, die an der durch das Symbol gekennzeichneten Adresse abgelegt ist. Ein Debugger kann eine solche Information z.B. nutzen, um symbolisch angesprochene Variablen direkt in der korrekten L"ange aufzulisten. Hat AS keine Informationen "uber die Symbolgr"o"se, so steht in diesem Feld eine schlichte -1. Das f"unfte und letzte Feld gibt schlu"sendlich durch eine 0 oder 1 an, ob das Symbol w"ahrend der Assemblierung jemals referenziert wurde. Ein Programm, da"s die Symboltabelle liest, kann auf diese Weise z.B. nicht benutzte Symbole automatisch verwerfen, da sie beim folgenden Debugging oder der Disassemblierung mit hoher Wahrscheinlichkeit auch nicht ben"otigt werden. Der dritte Abschnitt in einer Debug-Datei beschreibt die im Programm benutzten Sektionen n"aher. Eine solche Beschreibung ist erforderlich, da Sektionen den G"ultigkeitsbereich von Symbolen einschr"anken k"onnen. Je nach momentanem Stand des Programmz"ahlers kann z.B. ein symbolischer Debugger einzelne Symboldefinitionen f"ur eine R"uck"ubersetzung nicht nutzen oder mu"s Priorit"aten bei der Symbolnutzung beachten. Die Definition einer Sektion beginnt mit einer Zeile der Form \begin{verbatim} Info for Section nn ssss pp , \end{verbatim} wobei \tty{nn} die Nummer der Sektion angibt (die Nummer, die als Postfix f"ur Symbolnamen in der Symboltabelle genutzt wird), \tty{ssss} der Name der Sektion ist und \tty{pp} die Nummer der Vatersektion darstellt. Letztere Information ben"otigt ein R"uck"ubersetzer, um sich bei der Auffindung eines Symbols f"ur einen Zahlenwert ausgehend von der aktuellen Sektion im Baum bis zur Wurzel ,,durchhangeln'' kann, bis ein passendes Symbol gefunden wird. Auf diese Zeile folgt eine Reihe weiterer Zeilen, die den von dieser Sektion belegten Code-Bereich beschreiben. Jeder einzelne Eintrag (genau einer pro Zeile) beschreibt entweder eine einzelne Adresse oder einen durch zwei Grenzwerte beschriebenen Bereich (Trennung von Anfangs-und Endwert durch ein Minuszeichen). Die Grenzen sind dabei ,,inklusive'', d.h. die Grenzen geh"oren auch zu dem Bereich. Wichtig ist, da"s ein einer Sektion zugeh"origer Bereich nicht nochmals f"ur ihre Vatersektionen aufgef"uhrt wird (eine Ausnahme ist nat"urlich, wenn Bereiche absichtlich mehrfach belegt werden, aber so etwas macht man ja auch nicht, gelle?). Dies dient einer Optimierung der Bereichsspeicherung w"ahrend der Assemblierung und sollte auch f"ur eine Symbolr"uck"ubersetzung keine Probleme darstellen, da durch die einfache Kennzeichnung bereits der Einstiegspunkt und damit der Suchpfad im Sektionsbaum gegeben ist. Die Beschreibung einer Sektion wird durch eine Leerzeile oder das Dateiende gekennzeichnet. Programmteile, die au"serhalb aller Sektionen liegen, werden nicht gesondert ausgewiesen. Diese ,,implizite Wurzelsektion'' tr"agt die Nummer -1 und wird auch als Vatersektion f"ur Sektionen benutzt, die keine eigentliche Vatersektion besitzen. Es ist m"oglich, da"s die Datei Leerzeilen oder Kommentarzeilen (Semikolon am Zeilenanfang) beinhaltet. Diese sind von einem Leseprogramm zu ignorieren. %%=========================================================================== \cleardoublepage \chapter{Hilfsprogramme} \label{ChapTools} Um die Arbeit mit dem Codeformat des Assemblers etwas zu erleichtern, lege ich einige Progamme zu deren Bearbeitung bei. F"ur diese Programme gilt sinngem"a"s das gleiche wie in \ref{SectLicense}! Allen Programmen gemeinsam sind die Returncodes, die sie liefern (Tabelle \ref{TabToolReturns}). \par \begin{table*}[ht] \begin{center}\begin{tabular}{|c|l|} \hline Returncode & tritt auf bei... \\ \hline \hline 0 & kein Fehler \\ 1 & Kommandozeilenparameterfehler \\ 2 & I/O-Fehler \\ 3 & Dateiformatfehler \\ \hline \end{tabular}\end{center} \caption{Returncodes der Dienstprogramme\label{TabToolReturns}} \end{table*} Ebenso eintr"achtig wie AS lesen sie ihre Eingaben von STDIN und schreiben Meldungen auf STDOUT (bzw. Fehlermeldungen auf STDERR). Ein-und Ausgaben sollten sich daher problemlos umleiten lassen. \par Sofern Programme im folgenden Zahlen-oder Adre"sangaben von der Kommandozeile lesen, d"urfen diese auch hexadezimal geschrieben werden, indem man sie mit einem voranstehenden Dollarzeichen oder \tty{0x} wie in C versieht (z.B. \verb!$10! oder \verb!0x10! anstelle von 16). \par Unix-Shells \marginpar{{\em UNIX}} ordnen dem Dollarzeichen allerdings eine spezielle Bedeutung zu (Parameterexpansion), weshalb es n"otig ist, einem Dollarzeichen direkt einen Backslash voranzustellen. Die \tty{0x}-Variante ist hier sicherlich angenehmer. \par Ansonsten folgen die Aufrufkonventionen und -variationen (bis auf PLIST und AS2MSG) denen von AS, d.h. man kann dauernd gebrauchte Schalter in einer Environmentvariablen ablegen (deren Name sich aus dem Anh"angen von CMD an den Programmnamen ergibt, z.B. BINDCMD f"ur BIND), Optionen negieren und Gro"s-bzw. Kleinschreibung erzwingen (n"aheres zu dem Wie in Abschnitt \ref{SectCallConvention}). \par Sofern Adre"sangaben benutzt werden, beziehen sie sich immer auf die Granularit"at des Adre"sraumes des jeweiligen Prozessors; beim PIC bedeutet z.B. eine Adre"sdifferenz von 1 nicht ein Byte, sondern ein Wort. %%--------------------------------------------------------------------------- \section{PLIST} PLIST ist das einfachste Programm der vier mitgelieferten; es dient einfach nur dazu, die in einer Codedatei gespeicherten Records aufzulisten. Da das Programm nicht allzuviel bewirkt, ist der Aufruf ziemlich simpel: \begin{verbatim} PLIST $<$Dateiname$>$ \end{verbatim} Der Dateiname wird automatisch um die Endung P erweitert, falls keine Endung vorhanden ist. \par \bb{ACHTUNG!} An dieser Stelle sind keine Jokerzeichen erlaubt! Falls mit einem Befehl trotzdem mehrere Programmdateien gelistet werden sollen, kann man sich mit folgendem ''Minibatch'' behelfen: \begin{verbatim} for %n in (*.p) do plist %n \end{verbatim} PLIST gibt den Inhalt der Codedatei in Tabellenform aus, wobei f"ur jeden Record genau eine Zeile ausgegeben wird. Die Spalten haben dabei folgende Bedeutung: \begin{itemize} \item{Codetyp: die Prozessorfamilie, f"ur die der Code erzeugt wurde.} \item{Startadresse: absolute Speicheradresse, an die der Code zu laden ist.} \item{L"ange: L"ange des Codest"ucks in Byte.} \item{Endadresse: letzte absolute Adresse des Codest"ucks. Diese berechnet sich als Startadresse+L"ange-1.} \end{itemize} Alle Angaben sind als hexadezimal zu verstehen. \par Zuletzt gibt PLIST noch einen Copyrightvermerk aus, sofern er einen solchen in der Datei findet, und die Summe aller Codel"angen. \par PLIST ist praktisch ein DIR f"ur Codedateien. Man kann es benutzen, um sich den Inhalt einer Datei auflisten zu lassen, bevor man sie weiterbearbeitet. %%--------------------------------------------------------------------------- \section{BIND} BIND ist ein Programm, mit dem man die Records mehrerer Codedateien in eine Datei zusammenkopieren kann. Die dabei vorhandene Filterfunktion erlaubt es aber auch, nur Records eines bestimmten Typs zu "ubernehmen. Auf diese Weise kann BIND auch dazu verwendet werden, um eine Codedatei in mehrere aufzuspalten. \par Die allgemeine Syntax von BIND lautet \begin{verbatim} BIND [Optionen] \end{verbatim} Wie auch AS betrachtet BIND alle nicht mit einem +, - oder / eingeleiteten Parameter als Dateiangaben, von denen die letzte die Zieldatei angeben mu"s. Alle anderen Dateiangaben bezeichnen Quellen, diese Angaben d"urfen auch wieder Jokerzeichen enthalten. \par An Optionen definiert BIND momentan nur eine: \begin{itemize} \item{\tty{f $<$Header[,Header...]$>$}: gibt eine Liste von Header-IDs an, die kopiert werden sollen. Alle anderen Records werden nicht kopiert. Ohne diese Angabe werden alle Records kopiert. Die in der Liste angegebenen entsprechen dem Header-Feld in der Recordstruktur, wie es in Abschnitt \ref{SectCodeFormat} beschrieben wurden. Die einzelnen Header-Nummern in der Liste werden durch Kommas getrennt.} \end{itemize} Um z.B. alle MCS-51-Codeteile aus einer Programmdatei auszusieben, benutzt man BIND folgenderma"sen: \begin{verbatim} BIND -f $31 \end{verbatim} Fehlt bei einer Dateiangabe eine Endung, so wird automatisch die Endung P angef"ugt. %%--------------------------------------------------------------------------- \section{P2HEX} P2HEX ist eine Erweiterung von BIND. Es besitzt alle Kommandozeilenoptionen von BIND und hat die gleichen Konventionen bzgl. Dateinamen. Im Gegensatz zu BIND wird die Zieldatei aber als Hexfile ausgegeben, d.h. als eine Folge von Zeilen, die den Code als ASCII-Hexzahlen enthalten. \par P2HEX kennt 8 verschiedene Zielformate, die "uber den Kommandozeilenparameter \bb{F} ausgew"ahlt werden k"onnen: \begin{itemize} \item{Motorola S-Record (\tty{-F Moto})} \item{MOS Hex (\tty{-F MOS})} \item{Intel-Hex (Intellec-8, \tty{-F Intel})} \item{16-Bit Intel-Hex (MCS-86, \tty{-F Intel16})} \item{32-Bit Intel-Hex (\tty{-F Intel32})} \item{Tektronix Hex (\tty{-F Tex})} \item{Texas Instruments DSK (\tty{-F DSK})} \item{Atmel AVR Generic (-F Atmel, siehe \cite{AVRObj})} \end{itemize} Wird kein Zielformat explizit angegeben, so w"ahlt P2HEX anhand des Prozessortyps automatisch eines aus, und zwar S-Records f"ur Motorola- Prozessoren, Hitachi und TLCS-900(0), MOS f"ur 65xx/MELPS, DSK f"ur die 16-Bit-Texas-Signalprozessoren, Atmel Generic f"ur die AVRs und Intel-Hex f"ur den Rest. Je nach Breite der Startadresse kommen bei S-Record Records der Typen 1,2 oder 3 zum Einsatz, jedoch nie in einer Gruppe gemischt. Diese Automatik l"a"st sich mit der Kommandozeilenoption \begin{verbatim} -M <1|2|3> \end{verbatim} teilweise unterdr"ucken: Ein Wert von 2 bzw. 3 sorgt daf"ur, da"s S-Records mit einem Mindesttyp von 2 bzw. 3 benutzt werden, w"ahrend ein Wert von 0 der vollen Automatik entspricht. Die Intel-, Tektronix- und MOS-Formate sind auf 16 Bit-Adressen beschr"ankt, das 16-Bit Intel-Format reicht 4 Bit weiter. L"angere Adressen werden von P2HEX mit einer Warnung gemeldet und abgeschnitten(!). F"ur die PICs k"onnen die drei von Microchip spezifizierten Varianten des Intel-Hex-Formates erzeugt werden, und zwar mit dem Schalter \begin{verbatim} -m <0..3> \end{verbatim} Das Format 0 ist INHX8M, in dem alle Bytes in Lo-Hi-Ordnung enthalten sind. Die Adre"sangaben verdoppeln sich, weil bei den PICs die Adresse sich nur um 1 pro Wort erh"oht. Dieses Format ist gleichzeitig die Vorgabe. Im Format 1 (INHX16M) werden alle Worte in ihrer nat"urlichen Ordnung abgelegt. Dieses Format verwendet Microchip f"ur seine eigenen Programierger"ate. Format 2 (INHX8L) und 3 (INHX8H) trennen die Worte in ihre oberen und unteren Bytes auf. Um die komplette Information zu erhalten, mu"s P2HEX zweimal aufgerufen werden, z.B. so: \begin{verbatim} p2hex test -m 2 rename test.hex test.obl p2hex test -m 3 rename test.hex test.obh \end{verbatim} F"ur das Motorola-Format verwendet P2HEX zus"atzlich einen in \cite{CPM68K} genannten Recordtyp mit der Nummer 5, der die Zahl der folgenden Daten-Records (S1/S2/S3) bezeichnet. Da dieser Typ vielleicht nicht jedem Programm bekannt ist, kann man ihn mit der Option \begin{verbatim} +5 \end{verbatim} unterdr"ucken. \par Finden sich Code-Records verschiedener Prozessoren in einer Quelldatei, so erscheinen die verschiedenen Hexformate auch gemischt in der Zieldatei --- es empfiehlt sich also dringend, von der Filterfunktion Gebrauch zu machen. \par Neben dem Codetypenfilter kennt P2HEX noch ein Adre"sfilter, das n"utzlich ist, falls der Code auf mehrere EPROMs verteilt werden mu"s: \begin{verbatim} -r - \end{verbatim} Die Startadresse ist dabei die erste Speicherzelle, die im Fenster liegen soll, die Endadresse die der letzten Speicherzelle im Fenster, \ii{nicht} die der ersten au"serhalb. Um z.B. ein 8051-Programm in 4 2764-EPROMs aufzuteilen, geht man folgenderma"sen vor: \begin{verbatim} p2hex eprom1 -f $31 -r $0000-$1fff p2hex eprom2 -f $31 -r $2000-$3fff p2hex eprom3 -f $31 -r $4000-$5fff p2hex eprom4 -f $31 -r $6000-$7fff \end{verbatim} Defaultm"a"sig ist das Fenster 32 KByte gro"s und beginnt bei Adresse 0. \par \bb{ACHTUNG!} Die Splittung "andert nichts an den absoluten Adressen, die in den Hexfiles stehen! Sollen die Adressen im Hexfile bei 0 beginnen, so kann man dies durch den zus"atzlichen Schalter \begin{verbatim} -a \end{verbatim} erreichen. Um im Gegenteil die Adre"slage auf einen bestimmten Wert zu verschieben, kann man den Schalter \begin{verbatim} -R \end{verbatim} verwenden. Der dabei angegebene Wert ist ein {\em Offset}, d.h. er wird auf die in der Code-Datei angegebenen Adressen aufaddiert. \par Als Sonderwerte f"ur Start-und Endadresse beim r-Parameter ist ein schlichtes Dollar-Zeichen (\$) erlaubt. Diese kennzeichnet die erste bzw. letzte in der Programmdatei belegte Adresse. Wer also sicher sein will, da"s immer das ganze Programm in der Hex-Datei abgelegt wird, braucht sich mit dem Schalter \begin{verbatim} -r $-$ \end{verbatim} keine Gedanken mehr zu machen. Dollarzeichen und feste Adressen lassen sich selbstverst"andlich auch gemischt verwenden, z.B. kann mit \begin{verbatim} -r $-$7fff \end{verbatim} das obere Ende auf die ersten 32K begrenzt werden. \par Den Inhalt einer Datei kann man mit einem Offset auf eine beliebige Position verschieben; diesen Offset h"angt man einfach in Klammern an den Dateinamen an. Ist der Code in einer Datei z.B. auf Adresse 0 in der P-Datei abgelegt, man m"ochte ihn jedoch auf Adresse 1000h verschieben, so h"angt man an \tty{(\$1000)} an den Dateinamen (ohne Leerzeichen!) an. \par Da das TI-DSK-Format Daten und Code unterscheiden kann, l"a"st sich mit dem Schalter \begin{verbatim} -d - \end{verbatim} festlegen, welche Adre"sbereiche als Daten ausgegeben werden sollen. Dollarzeichen sind hier \bb{nicht} zugelassen. F"ur das DSK- sowie Intel- und Motorola-Format relevant ist dagegen die Option \begin{verbatim} -e , \end{verbatim} mit der man die in die Hex-Datei einzutragende Startadresse festlegen kann. Fehlt diese Angabe, so wird nach einen entsprechenden Eintrag in der Code-Datei gesucht. Ist auch dort kein Hinweis auf einen Einsprungpunkt zu finden, so wird kein Eintrag in die HEX-Datei geschrieben (DSK/Intel) bzw. das entsprechende Feld wird auf 0 gesetzt (Motorola). \par Leider ist sich die Literatur nicht ganz "uber die Endezeile f"ur Intel-Hexfiles einig. P2HEX kennt daher 3 Varianten, einstellbar "uber den Parameter \bb{i} mit einer nachfolgenden Ziffer: \begin{description} \item[0]{ :00000001FF} \item[1]{ :00000001} \item[2]{ :0000000000} \end{description} \par Defaultm"a"sig wird die Variante 0 benutzt, die die gebr"auchlichste zu sein scheint. \par Fehlt der Zieldateiangabe eine Endung, so wird \tty{HEX} als Endung angenommen. \par Defaultm"a"sig gibt P2HEX pro Zeile maximal 16 Datenbytes aus, wie es auch die meisten anderen Tools tun, die Hex-Files erzeugen. Wollen Sie dies "andern, so k"onnen Sie dies mit dem Schalter \begin{verbatim} -l \end{verbatim} tun. Der erlaubte Wertebereich liegt dabei zwischen 2 und 254 Datenbytes; ungerade Werte werden implizit auf gerade Anzahlen aufgerundet. \par Meist werden die tempor"aren, von AS erzeugten Code-Dateien nach einer Umwandlung nicht mehr unbedingt gebraucht. Mit der Kommandozeilen- option \begin{verbatim} -k \end{verbatim} kann man P2HEX anweisen, diese automatisch nach der Konversion zu l"oschen. \par Anders als BIND erzeugt P2HEX keine Leerdatei, wenn nur ein Dateiname (=Zieldatei) angegeben wurde, sondern bearbeitet die dazugeh"orige Codedatei. Es ist also ein Minimalaufruf \`a la \begin{verbatim} P2HEX \end{verbatim} m"oglich, um $<$Name$>$.HEX aus $<$Name$>$.P zu erzeugen. %%--------------------------------------------------------------------------- \section{P2BIN} P2BIN funktioniert wie P2HEX und bietet die gleichen Optionen (bis auf die a- und i- Optionen, die bei Bin"ardateien keinen Sinn ergeben), nur wird das Ergebnis nicht als Hexdatei, sondern als einfache Bin"ardatei abgelegt. Dies kann dann z.B. direkt in ein EPROM gebrannt werden. \par Zur Beeinflussung der Bin"ardatei kennt P2BIN gegen"uber P2HEX noch drei weitere Optionen: \begin{itemize} \item{\tty{l $<8-Bit-Zahl>$}: gibt den Wert an, mit dem unbenutzte Speicherstellen in der Datei gef"ullt werden sollen. Defaultm"a"sig ist der Wert \$ff, so da"s ein halbwegs intelligenter EPROM-Brenner sie "uberspringt. Man kann aber hiermit auch andere Werte einstellen, z.B. enthalten die gel"oschten Speicherzellen der MCS-48-EPROM-Versionen Nullen. In einem solchen Falle w"are 0 der richtige Wert.} \item{\tty{s}: weist das Programm an, eine Pr"ufsumme "uber die Bin"ardatei zu berechnen. Die Pr"ufsumme wird einmal als 32-Bit-Wert ausgegeben, zum anderen wird das Zweierkomplement der Bits 0..7 in der letzten Speicherstelle abgelegt, so da"s die Modulo-256-Summe zu 0 wird.} \item{\tty{m}: f"ur den Fall, da"s ein Prozessor mit 16- oder 32-Bit-Datenbus eingesetzt wird und die Bin"ardatei f"ur mehrere EPROMs aufgesplittet werden mu"s. Das Argument kann folgende Werte annnehmen: \begin{itemize} \item{\tty{ALL}: alles kopieren} \item{\tty{ODD}: alle Bytes mit ungerader Adresse kopieren} \item{\tty{EVEN}: alle Bytes mit gerader Adresse kopieren} \item{\tty{BYTE0}..\tty{BYTE3}: nur alle Bytes kopieren, deren Adresse die Form $4n+0$...$4n+3$ hat.} \item{\tty{WORD0},\tty{WORD1}: nur das untere bzw. obere 16-Bit-Wort der 32-Bit-Worte kopieren.} \end{itemize}} \end{itemize} Nicht wundern: Bei letzteren Optionen ist die Bin"ardatei um den Faktor 2 oder 4 kleiner als bei \tty{ALL}. Dies ist bei konstantem Adre"sfenster logisch! Falls die Code-Datei keine Startadresse enth"alt, kann man diese analog zu P2HEX "uber die \tty{-e}-Kommandozeilenoption vorgeben. Auf Anforderung teilt P2BIN ihren Wert der Ergebnisdatei voran. Mit der Kommandozeilenoption \begin{verbatim} -S \end{verbatim} wird diese Funktion aktiviert. Sie erwartet als Argument eine Zahlenangabe zwischen 1 und 4, die die L"ange des Adressfeldes in Bytes bestimmt. Optional kann dieser Angabe auch noch der Buchstabe L oder B vorangestellt werden, um die Byte-Order dieser Adresse festzulegen. So erzeugt z.B. die Angabe \tty{B4} eine 4-Byte-Adresse in Big-Endian-Anordnung, \tty{L2} oder nur '2' eine 2-Byte-Adresse in Little-Endian-Anordnung. %%--------------------------------------------------------------------------- \section{AS2MSG} Bei AS2MSG handelt es sich eigentlich um kein Hilfsprogramm, sondern um ein Filter, das (gl"ucklichen) Besitzern von Borland-Pascal 7.0 das Arbeiten mit dem Assembler erleichtern soll. In den DOS-Arbeitsumgebungen existiert ein ,,Tools''-Men"u, das man um eigene Programme, z.B. AS erweitern kann. Das Filter erlaubt, die von AS gelieferten Fehlermeldungen mit Zeilenangabe direkt im Editorfenster anzuzeigen. Dazu mu"s im Tools-Men"u ein neuer Eintrag angelegt werden (\tty{Options/Tools/New}). Tragen Sie in die einzelnen Felder folgende Werte ein : \begin{itemize} \item{Title: \tty{\verb!~!M\verb!~!akroassembler}} \item{Program path: \tty{AS}} \item{Command line: \tty{-E !1 \$EDNAME \$CAP MSG(AS2MSG) \$NOSWAP \$SAVE ALL}} \item{bei Bedarf einen Hotkey zuordnen (z.B. Shift-F7)} \end{itemize} Die Option \tty{-E} sorgt daf"ur, da"s Turbo-Pascal nicht mit STDOUT und STDERR durcheinander kommt. \par Ich setze dabei voraus, da"s sowohl AS als auch AS2MSG sich in einem Verzeichnis befinden, welches in der Pfadliste aufgef"uhrt ist. Nach einem Druck auf dem passenden Hotkey (oder Auswahl aus dem Tools-Men"u) wird AS mit dem Namen der Textdatei im aktiven Editorfenster aufgerufen. Die dabei aufgetretenen Fehler werden in ein separates Fenster geleitet, durch das man nun ,,browsen'' kann. Mit \bb{Ctrl-Enter} springt man eine fehlerhafte Zeile an. Zus"atzlich enth"alt das Fenster die Statistik, die AS am Ende der Assemblierung ausgibt. Diese erhalten als Dummy-Zeilennummer 1. \par F"ur diese Arbeitsweise sind sowohl TURBO.EXE (Real Mode) als auch BP.EXE (Protected Mode) geeignet. Ich empfehle BP, da in dieser Variante beim Aufruf nicht erst der halbe DOS-Speicher ,,freigeswappt'' werden mu"s. \cleardoublepage \appendix %%=========================================================================== \cleardoublepage \chapter{Fehlermeldungen von AS} \label{ChapErrMess} Im folgenden findet sich eine halb-tabellarische Auflistung der in AS definierten Fehlermeldungen. Zu jeder Fehlermeldung finden sich folgende Angaben: \begin{itemize} \item{interne Fehlernummer (f"ur den Anwender nur mit der \tty{n}-Option sichtbar);} \item{Fehlermeldung im Klartext;} \item{Typ: \begin{itemize} \item{Warnung: zeigt m"ogliche Fehler oder ineffizienten Code an. Assemblierung geht weiter.} \item{Fehler: echte Fehler. Assemblierung geht weiter, aber keine Code-Datei wird geschrieben.} \item{Fatal: schwerwiegende Fehler. Assemblierung wird abgebrochen.} \end{itemize}} \item{Ursache: die Situation(en), in denen der Fehler ausgegeben wird;} \item{Argument: Die Ausgabe, die auf Wunsch als erweiterte Fehlermeldung erfolgt.} \end{itemize} \par \newcommand{\errentry}[5] {\item[#1]{#2 \begin{description} \item[Type:]{\ \\#3} \item[Reason:]{\ \\#4} \item[Argument:]{\ \\#5} \end{description}} } \begin{description} \errentry{ 0}{Displacement=0, "uberfl"ussig} {Warnung} {bei 680x0-,6809- und COP8-Prozessoren: Das Displacement in einem Adre"sausdruck hat den Wert 0 ergeben. Es wird ein Adre"sausdruck ohne Displacement erzeugt. Um keine Phasenfehler zu erzeugen, werden NOP-Befehle eingef"ugt.} {keines} \errentry{ 10}{Kurzadressierung m"oglich} {Warnung} {bei 680x0-, 6502- und 68xx-Prozessoren k"onnen bestimmte Speicherbereiche mit kurzen Adressen erreicht werden. Um keine Phasefehler zu erzeugen, wird zwar der k"urzere Ausdruck erzeugt, der freie Platz wird aber mit NOPs aufgef"ullt.} {keines} \errentry{ 20}{kurzer Sprung m"oglich} {Warnung} {Bei 680x0 und 8086-Prozessoren kann der Sprung sowohl mit langem als auch kurzem Displacement ausgef"uhrt werden. Da kein kurzer Sprung angefordert wurde, wurde im ersten Pass Platz f"ur den langen Sprung freigehalten. Es wird ein kurzer Sprung erzeugt, der freie Platz wird mit NOPs aufgef"ullt, um Phasenfehler zu vermeiden.} {keines} \errentry{ 30}{kein Sharefile angelegt, SHARED ignoriert} {Warnung} {Es wurde eine \tty{SHARED}-Anweisung gefunden, es wurde aber keine Kommandozeilenoption angegeben, um eine Shared-Datei zu erzeugen.} {keines} \errentry{ 40}{FPU liest Wert evtl. nicht korrekt ein ($>$=1E1000)} {Warnung} {Das BCD-Gleitkommaformat der 680x0-Koprozessoren erlaubt zwar vierstellige Exponenten, lt. Datenbuch k"onnen solche Werte aber nicht korrekt eingelesen werden. Der vierstellige Wert wird zwar erzeugt, eine Funktion ist aber nicht gew"ahleistet.} {keines} \errentry{ 50}{Privilegierte Anweisung} {Warnung} {Es wurde eine Anweisung benutzt, die nur im Supervisor-Mode zul"assig ist, obwohl dieser nicht mittels \tty{SUPMODE ON} vorher explizit angezeigt wurde.} {keines} \errentry{ 60}{Distanz 0 nicht bei Kurzsprung erlaubt (NOP erzeugt)} {Warnung} {Ein kurzer Sprung mit der Distanz 0 ist bei 680x0- bzw. COP8-Prozessoren nicht erlaubt, da dieser Sonderwert f"ur lange Spr"unge ben"otigt wird. Stattdessen wurde ein NOP-Befehl eingef"ugt.} {keines} \errentry{ 70}{Symbol aus falschem Segment} {Warnung} {Das in dem Operanden benutzte Symbol ist aus einem Adre"sraum, der nicht mit dem benutzten Befehl bearbeitet werden kann.} {keines} \errentry{ 75}{Segment nicht adressierbar} {Warnung} {Das in dem Operanden benutzte Symbol ist aus einem Adre"sraum, der mit keinem der Segmentregister des 8086 adressiert werden kann.} {Name des nicht adressierbaren Segments} \errentry{ 80}{"Anderung des Symbolwertes erzwingt zus"atzlichen Pass} {Warnung} {Ein Symbol hat einen anderen Wert zugewiesen bekommen als im vorhergehenden Pass. Diese Warnung wird nur ausgegeben, falls die \tty{r}-Option angegeben wurde.} {Der Name des fraglichen Symbols} \errentry{ 90}{"Uberlappende Speicherbelegung} {Warnung} {Bei der Bildung der Belegungsliste wurde festgestellt, da"s ein Speicherbereich im Codesegment mehrfach benutzt wurde. Ursache k"onnen un"uberlegte \tty{ORG}-Anweisungen sein.} {keines} \errentry{ 100}{keine CASE-Bedingung zugetroffen} {Warnung} {bei einem \tty{SWITCH}..\tty{CASE}-Konstrukt ohne \tty{ELSECASE}-Zweig traf keiner der \tty{CASE}-Zweige zu.} {keines} \errentry{ 110}{Seite m"oglicherweise nicht adressierbar} {Warnung} {Das in dem Operanden benutzte Symbol liegt nicht in der momentan mit \tty{ASSUME} eingestellten Fenster (ST6,78(C)10).} {keines} \errentry{ 120}{Registernummer mu"s gerade sein} {Warnung} {Die Hardware erlaubt nur ein Registerpaar zu verketten, dessen Startadresse gerade ist (RR0, RR2..., nur Z8).} {keines} \errentry{ 130}{veralteter Befehl} {Warnung} {Der verwendete Befehl ist zwar noch definiert, ist in seiner Funktion aber durch andere, neue Befehle ersetzbar und daher in zuk"unftigen Prozessorversionen eventuell nicht mehr vorhanden.} {keines} \errentry{ 140}{Nicht vorhersagbare Ausf"uhrung dieser Anweisung} {Warnung} {Die verwendete Adressierungsart ist bei diesem Befehl zwar prinzipiell erlaubt, ein Register wird jedoch in einer Weise doppelt verwendet, da"s je nach Aus"uhrungsreihenfolge sich unterschiedliche Ergebnisse einstellen k"onnen.} {keines} \errentry{ 150}{Lokaloperator au"serhalb einer Sektion "uberfl"ussig} {Warnung} {Ein vorangestellter Klammeraffe dient dazu, sich explizit auf zu der Sektion lokale Symbole zu beziehen. Wenn man sich au"serhalb einer Sektion befindet, gibt es keine lokalen Symbole, weshalb dieser Operator "uberfl"ussig ist.} {keines} \errentry{ 160}{sinnlose Operation} {Warnung} {Die Anweisung ergibt entweder "uberhaupt keinen Sinn oder kann auf andere Weise schneller und k"urzer ausgef"uhrt werden.} {keines} \errentry{ 170}{unbekannter Symbolwert erzwingt zus"atzlichen Pass} {Warnung} {AS vermutet eine Vorw"artsreferenz eines Symbols, d.h. das Symbol wird benutzt, bevor es definiert wurde, und h"alt einen weiteren Pass f"ur unumg"anglich. Diese Warnung wird nur ausgegeben, falls die \tty{r}-Option angegeben wurde.} {Der Name des fraglichen Symbols} \errentry{ 180}{Adresse nicht ausgerichtet} {Warnung} {Eine Adresse ist nicht ein mehrfaches der Operandengr"o"se. Das Datenbuch verbietet zwar solche Zugriffe, im Instruktionswort ist aber Platz f"ur diese Adresse, so da"s AS es bei einer Warnung belassen hat.} {keines} \errentry{ 190}{I/O-Adresse darf nicht verwendet werden} {Warnung} {Der verwendete Adressierungsmodus oder die angesprochene Adresse sind zwar prinzipiell erlaubt, die Adresse liegt aber im Bereich der Peripherieregister, die in diesem Zusammenhang nicht verwendet werden d"urfen.} {keines} \errentry{ 200}{m"ogliche Pipeline-Effekte} {Warnung} {Ein Register wird in einer Befehlsfolge so verwendet, da"s die Befehlsausf"uhrung m"oglicherweise nicht in der hingeschriebenen Form ablaufen wird. "Ublicherweise wird ein Register benutzt, bevor der neue Wert zur Verf"ugung steht.} {das die Verklemmung verursachende Register} \errentry{ 210}{mehrfache Adre"sregisterbenutzung in einer Anweisung} {Warnung} {Ein Adre"sregister wird in mehreren Adre"sausdr"ucken eines Befehls benutzt. Sofern einer der beiden Ausdr"ucke das Register modifiziert, sind die Ergebnisadressen nicht eindeutig festgelegt.} {das mehrfach verwendete Register} \errentry{ 220}{Speicherstelle ist nicht bitadressierbar} {Warnung} {Mit einer \tty{SFRB}-Anweisung wurde versucht, eine Speicherstelle als bitadressierbar zu deklarieren, die aufgrund der Architektur des 8051 nicht bitadressierbar ist.} {keines} \errentry{ 230}{Stack ist nicht leer} {Warnung} {Am Ende eines Durchlaufes ist ein vom Programm definierter Stack nicht leer.} {der Name des Stacks sowie seine Resttiefe} \errentry{ 240}{NUL-Zeichen in Strings, Ergebnis undefiniert} {Warnung} {Eine String-Konstante enth"alt ein NUL-Zeichen. Dies funktioniert zwar mit der Pascal-Version, in Hinblick auf die C-Version von AS ist dies aber ein Problem, da C Strings mit einem NUL-Zeichen terminiert, d.h. der String w"are f"ur C an dieser Stelle zu Ende...} {keines} \errentry{ 250}{Befehl "uberschreitet Seitengrenze} {Warnung} {Ein Befehl steht zu Teilen auf verschiedenen Seiten. Da der Programmz"ahler des Prozessors aber nicht "uber Seitengrenzen hinweg inkrementiert wird, w"urde zur Laufzeit anstelle des Instruktionsbytes von der Folgeseite wieder das erste Byte der alten Seite geholt; das Programm w"urde fehlerhaft ablaufen.} {keines} \errentry{ 260}{Bereichs"uberschreitung} {Warnung} {Ein Zahlenwert lag au"serhalb des erlaubten Bereichs. AS hat den Wert durch ein Abschneiden der oberen Bitstellen in den erlaubten Bereich gebracht, es ist jedoch nicht garantiert, da"s sich durch diese Operation sinnvoller und korrekter Code ergibt.} {keines} \errentry{ 270}{negatives Argument f"ur DUP} {Warnung} {Das Wiederholungsargument einer \tty{DUP}-Direktive war kleiner als 0. Es werden (analog zu einem Argument von genau 0) keine Daten abgelegt.} {keines} \errentry{1000}{Symbol doppelt definiert} {Fehler} {Einem Symbol wurde durch ein Label oder \tty{EQU}, \tty{PORT}, \tty{SFR}, \tty{LABEL}, \tty{SFRB} oder \tty{BIT} ein neuer Wert zugewiesen, dies ist aber nur bei \tty{SET/EVAL} erlaubt.} {Name des fraglichen Symbols, bei eingeschalteter Querverweisliste zus"atzlich die Zeile der ersten Definition} \errentry{1010}{Symbol nicht definiert} {Fehler} {Ein benutztes Symbol ist auch im 2.Pass noch nicht in der Symboltabelle enthalten.} {Name des nicht gefundenen Symbols} \errentry{1020}{Ung"ultiger Symbolname} {Fehler} {Ein Symbolname entspricht nicht den Bedingungen f"ur einen g"ultigen Symbolnamen. Beachten Sie, da"s f"ur Makro-und Funktionsparameter strengere Regeln gelten!} {der fehlerhafte Symbolname} \errentry{1090}{Ung"ultiges Format} {Fehler} {Das benutzte Befehlsformat existiert bei diesem Befehl nicht.} {Der Kennbuchstabe des verwendeten Formates} \errentry{1100}{"Uberfl"ussiges Attribut} {Fehler} {Der benutzte Befehl (Prozessor oder Pseudo) darf kein mit einem Punkt angeh"angtes Attribut haben.} {keines} \errentry{1105}{Attribut darf nur 1 Zeichen lang sein} {Fehler} {Das mit einem Punkt an einen Befehl angeh"angte Attribut mu"s genau ein Zeichen lang sein; weder mehr noch weniger ist erlaubt.} {keines} \errentry{1110}{Unpassende Operandenzahl} {Fehler} {Die bei einem Befehl (Prozessor oder Pseudo) angegebene Operandenzahl liegt nicht in dem f"ur diesen Befehl erlaubten Bereich.} {keines} \errentry{1115}{Unpassende Optionenzahl} {Fehler} {Die bei diesem Befehl angegebene Zahl von Optionen liegt nicht in dem f"ur diesen Befehl erlaubten Bereich.} {keines} \errentry{1120}{nur immediate-Adressierung erlaubt} {Fehler} {Der benutzte Befehl l"a"st nur immediate-Operanden (mit vorangestelltem \#) zu.} {keines} \errentry{1130}{Unpassende Operandengr"o"se} {Fehler} {Der Operand hat zwar einen f"ur den Befehl zugelassenen Typ, jedoch nicht die richtige L"ange (in Bits).} {keines} \errentry{1131}{Widersprechende Operandengr"o"sen} {Fehler} {Die angegebenen Operanden haben unterschiedliche L"angen (in Bit).} {keines} \errentry{1132}{Undefinierte Operandengr"o"se} {Fehler} {Aus Opcode und Operanden l"a"st sich die Operandengr"o"se nicht eindeutig bestimmen (ein Problem des 8086-Assemblers). Sie m"ussen die Operandengr"o"se durch einen \tty{BYTE}, \tty{WORD}, usw. \tty{PTR}-Pr"afix festlegen.} {keines} \errentry{1135}{Ung"ultiger Operandentyp} {Fehler} {Ein Ausdruck hat einen an dieser Stelle nicht zul"assigen Typ (Integer/Gleitkomma/String).} {Die an dieser Stelle zul"assigen Datentypen} \errentry{1140}{Zuviele Argumente} {Fehler} {Einem Befehl wurden mehr als die unter AS zul"assigen 20 Parameter "ubergeben.} {keines} \errentry{1200}{Unbekannter Befehl} {Fehler} {Der benutzte Befehl ist weder ein Pseudobefehl von AS noch ein Befehl des momentan eingestellten Prozessors.} {keines} \errentry{1300}{Klammerfehler} {Fehler} {Der Formelparser ist auf einen (Teil-)Ausdruck gesto"sen, in dem die Summe "offnender und schlie"sender Klammern nicht "ubereinstimmt.} {der beanstandete (Teil-)Ausdruck} \errentry{1310}{Division durch 0} {Fehler} {Bei einer Division oder Modulooperation ergab die Auswertung des rechten Teilausdruckes 0.} {keines} \errentry{1315}{Bereichsunterschreitung} {Fehler} {Der angegebene Integer-Wert unterschreitet den zul"assigen Bereich.} {aktueller Wert und zul"assiges Minimum (manchmal, ich stelle das gerade um...)} \errentry{1320}{Bereichs"uberschreitung} {Fehler} {Der angegebene Integer-Wert "uberschreitet den zul"assigen Bereich.} {aktueller Wert und zul"assiges Maximum (manchmal,ich stelle das gerade um...)} \errentry{1325}{Adresse nicht ausgerichtet} {Fehler} {Die angegebene direkte Speicheradresse entspricht nicht den Anspr"uchen des Datentransfers, d.h. ist nicht ein mehrfaches der Operandengr"o"se. Nicht alle Prozessoren erlauben unausgerichtete Datenzugriffe.} {keines} \errentry{1330}{Distanz zu gro"s} {Fehler} {Der in einem Adre"sausdruck enthaltene Displacement-Wert ist zu gro"s.} {keines} \errentry{1340}{Kurzadressierung nicht m"oglich} {Fehler} {Die Adresse des Operanden liegt au"serhalb des Speicherbereiches, in dem Kurzadressierung m"oglich ist.} {keines} \errentry{1350}{Unerlaubter Adressierungsmodus} {Fehler} {Der benutzte Adressierungsmodus existiert generell zwar, ist an dieser Stelle aber nicht erlaubt.} {keines} \errentry{1351}{Nummer mu"s ausgerichtet sein} {Fehler} {An dieser Stelle sind nur ausgerichtete (d.h z.B. gerade) Adressen erlaubt, da die untersten Bits f"ur andere Zwecke verwendet werden oder reserviert sind.} {keines} \errentry{1355}{Adressierungsmodus im Parallelbetrieb nicht erlaubt} {Fehler} {Die verwendeten Adressierungsmodi sind zwar im sequentiellen Modus zul"assig, jedoch nicht bei parallelen Instruktionen.} {keines} \errentry{1360}{Undefinierte Bedingung} {Fehler} {Die benutzte Bedingung f"ur bedingte Spr"unge existiert nicht.} {keines} \errentry{1370}{Sprungdistanz zu gro"s} {Fehler} {Sprungbefehl und Sprungziel liegen zu weit auseinander, um mit einem Sprung der benutzten L"ange "uberbr"uckt werden zu k"onnen.} {keines} \errentry{1375}{Sprungdistanz ist ungerade} {Fehler} {Da Befehle nur auf geraden Adressen liegen d"urfen, mu"s eine Sprungdistanz zwischen zwei Befehlen auch immer gerade sein, das Bit 0 der Distanz wird anderweitig verwendet. Diese Bedingung ist verletzt worden. Grund ist "ublicherweise die Ablage einer ungeraden Anzahl von Daten in Bytes oder ein falsches \tty{ORG}.} {keines} \errentry{1380}{ung"ultiges Schiebeargument} {Fehler} {als Argument f"ur die Schiebeamplitude darf nur eine Konstante oder ein Datenregister verwendet werden. (nur 680x0)} {keines} \errentry{1390}{Nur Bereich 1..8 erlaubt} {Fehler} {Konstanten f"ur Schiebeamplituden oder \tty{ADDQ}-Argumente d"urfen nur im Bereich 1..8 liegen. (nur 680x0)} {keines} \errentry{1400}{Schiebezahl zu gro"s} {Fehler} {(nicht mehr verwendet)} {keines} \errentry{1410}{Ung"ultige Registerliste} {Fehler} {Das Registerlisten-Argument von \tty{MOVEM} oder \tty{FMOVEM} hat ein falsches Format. (nur 680x0)} {keines} \errentry{1420}{Ung"ultiger Modus mit CMP} {Fehler} {Die verwendete Operandenkombination von \tty{CMP} ist nicht erlaubt. (nur 680x0)} {keines} \errentry{1430}{Ung"ultiger Prozessortyp} {Fehler} {Den mit CPU angeforderten Zielprozessor kennt AS nicht.} {der unbekannte Prozessortyp} \errentry{1440}{Ung"ultiges Kontrollregister} {Fehler} {Das bei z.B. \tty{MOVEC} benutzte Kontrollregister kennt der mit CPU gesetzte Prozessor (noch) nicht.} {keines} \errentry{1445}{Ung"ultiges Register} {Fehler} {Das benutzte Register ist zwar prinzipiell vorhanden, hier aber nicht erlaubt.} {keines} \errentry{1450}{RESTORE ohne SAVE} {Fehler} {Es wurde ein \tty{RESTORE}-Befehl gefunden, obwohl kein mit \tty{SAVE} gespeicherter Zustand (mehr) auf dem Stapel vorhanden ist.} {keines} \errentry{1460}{fehlendes RESTORE} {Fehler} {Nach der Assemblierung sind nicht alle \tty{SAVE}-Befehle wieder aufgel"ost worden.} {keines} \errentry{1465}{unbekannte Makro-Steueranweisung} {Fehler} {Eine beim \tty{MACRO}-Befehl zus"atzlich angegebene Steueranweisung ist AS unbekannt.} {die fragliche Anweisung} \errentry{1470}{fehlendes ENDIF/ENDCASE} {Fehler} {Nach der Assemblierung sind nicht alle Konstrukte zur bedingten Assemblierung aufgel"ost worden.} {keines} \errentry{1480}{ung"ultiges IF-Konstrukt} {Fehler} {Die Reihenfolge der Befehle in einem \tty{IF}- oder \tty{SWITCH}-Konstrukt stimmt nicht.} {keines} \errentry{1483}{doppelter Sektionsname} {Fehler} {Es existiert bereits eine Sektion gleichen Namens auf dieser Ebene.} {der doppelte Name} \errentry{1484}{unbekannte Sektion} {Fehler} {Im momentanen Sichtbarkeitsbereich existiert keine Sektion dieses Namens.} {der unbekannte Name} \errentry{1485}{fehlendes ENDSECTION} {Fehler} {Nach Ende eines Durchganges sind nicht alle Sektionen wieder geschlossen worden.} {keines} \errentry{1486}{falsches ENDSECTION} {Fehler} {die bei \tty{ENDSECTION} angegebene Sektion ist nicht die innerste offene.} {keines} \errentry{1487}{ENDSECTION ohne SECTION} {Fehler} {Es wurde ein \tty{ENDSECTION}-Befehl gegeben, obwohl gar keine Sektion offen war.} {keines} \errentry{1488}{nicht aufgel"oste Vorw"artsdeklaration} {Fehler} {ein mit \tty{FORWARD} oder \tty{PUBLIC} angek"undigtes Symbol wurde nicht in der Sektion definiert.} {der Name des fraglichen Symbols} \errentry{1489}{widersprechende FORWARD $\leftrightarrow$PUBLIC-Deklaration} {Fehler} {Ein Symbol wurde sowohl als privat als auch global definiert.} {der Name des Symbols} \errentry{1490}{falsche Argumentzahl f"ur Funktion} {Fehler} {Die Anzahl der Argumente f"ur eine selbstdefinierte Funktion stimmt nicht mit der geforderten Anzahl "uberein.} {keines} \errentry{1495}{unaufgel"oste Literale (LTORG fehlt)} {Fehler} {Am Programmende oder beim Umachalten zu einem anderen Zielprozessor blieben noch nicht abgelegte Literale "ubrig.} {keines} \errentry{1500}{Befehl auf dem ... nicht vorhanden} {Fehler} {Der benutzte Befehl existiert zwar grunds"atzlich, das eingestellte Mitglied der Prozessorfamilie beherrscht ihn aber noch nicht.} {keines} \errentry{1505}{Adressierungsart auf dem ... nicht vorhanden} {Fehler} {Der benutzte Adressierungsmodus existiert zwar grunds"atzlich, das eingestellte Mitglied der Prozessorfamilie beherrscht ihn aber noch nicht.} {keines} \errentry{1510}{Ung"ultige Bitstelle} {Fehler} {Die angegebene Bitnummer ist nicht erlaubt oder eine Angabe fehlt komplett.} {keines} \errentry{1520}{nur ON/OFF erlaubt} {Fehler} {Dieser Pseudobefehl darf als Argument nur \tty{ON} oder \tty{OFF} haben.} {keines} \errentry{1530}{Stack ist leer oder nicht definiert} {Fehler} {Es wurde bei einem \tty{POPV} einen Stack anzusprechen, der entweder nie definiert oder bereits leerger"aumt wurde.} {der Name des fraglichen Stacks} \errentry{1540}{Nicht genau ein Bit gesetzt} {Fehler} {In einer Bitmaske, die der \tty{BITPOS}- Funktion "ubergeben wurde, war nicht genau ein Bit gesetzt.} {keines} \errentry{1550}{ENDSTRUCT ohne STRUCT} {Fehler} {Eine \tty{ENDSTRUCT}-Anweisung wurde gegeben, obwohl momentan keine Strukturdefinition in Gange war.} {keines} \errentry{1551}{offene Strukturdefinition} {Fehler} {Nach Ende der Assemblierung waren noch nicht alle \tty{STRUCT}-Anweisungen durch passende \tty{ENDSTRUCT}s abgeschlossen.} {die innerste, noch nicht abgeschlossene Strukturdefinition} \errentry{1552}{falsches ENDSTRUCT} {Fehler} {Der Namensparameter einer \tty{ENDSTRUCT}-Anweisung entspricht nicht der innersten, offenen Strukturdefinition.} {keines} \errentry{1553}{Phasendefinition nicht in Strukturen erlaubt} {Fehler} {Was gibt es dazu zu sagen? \tty{PHASE} in einem Record ergibt einfach keinen Sinn und nur Verwirrung...} {keines} \errentry{1554}{ung"ultige \tty{STRUCT}-Direktive} {Fehler} {Als Direktive f"ur \tty{STRUCT} ist nur \tty{EXTNAMES} oder \tty{NOEXTNAMES} zugelassen.} {die unbekannte Direktive} \errentry{1600}{vorzeitiges Dateiende} {Fehler} {Es wurde mit einem \tty{BINCLUDE}-Befehl versucht, "uber das Ende einer Datei hinauszulesen.} {keines} \errentry{1700}{ROM-Offset geht nur von 0..63} {Fehler} {Das Konstanten-ROM der 680x0-Koprozessoren hat nur max. 63 Eintr"age.} {keines} \errentry{1710}{Ung"ultiger Funktionscode} {Fehler} {Als Funktionscodeargument darf nur SFC, DFC, ein Datenregister oder eine Konstante von 0..15 verwendet werden. (nur 680x0-MMU)} {keines} \errentry{1720}{Ung"ultige Funktionscodemaske} {Fehler} {Als Funktionscodemaske darf nur ein Wert von 0..15 verwendet werden. (nur 680x0-MMU)} {keines} \errentry{1730}{Ung"ultiges MMU-Register} {Fehler} {Die MMU hat kein Register mit dem angegebenen Namen. (nur 680x0-MMU)} {keines} \errentry{1740}{Level nur von 0..7} {Fehler} {Die Ebene f"ur \tty{PTESTW} und \tty{PTESTR} mu"s eine Konstante von 0..7 sein. (nur 680x0-MMU)} {keines} \errentry{1750}{ung"ultige Bitmaske} {Fehler} {Die bei den Bit-Feld-Befehlen angegebene Bitmaske hat ein falsches Format. (nur 680x0)} {keines} \errentry{1760}{ung"ultiges Registerpaar} {Fehler} {Das angegebene Registerpaar ist hier nicht verwendbar oder syntaktisch falsch. (nur 680x0)} {keines} \errentry{1800}{offene Makrodefinition} {Fehler} {Eine Makrodefinition war am Dateiende nicht zuende. Vermutlich fehlt ein \tty{ENDM}.} {keines} \errentry{1805}{EXITM au"serhalb eines Makrorumpfes} {Fehler} {\tty{EXITM} bricht die Expansion von Makro-Konstrukten ab. Dieser Befehl macht nur innerhalb von Makros Sinn und es wurde versucht, ihn au"serhalb aufzurufen.} {keines} \errentry{1810}{mehr als 10 Makroparameter} {Fehler} {Ein Makro darf h"ochstens 10 Parameter haben.} {keines} \errentry{1815}{doppelte Makrodefinition} {Fehler} {Ein Makronamne wurde in einer Sektion doppelt vergeben.} {der doppelt verwendete Name} \errentry{1820}{Ausdruck mu"s im ersten Pass berechenbar sein} {Fehler} {Der benutzte Befehl beeinflu"st die Codel"ange, daher sind Vorw"artsreferenzen hier nicht erlaubt.} {keines} \errentry{1830}{zu viele verschachtelte IFs} {Fehler} {(nicht mehr verwendet)} {keines} \errentry{1840}{ELSEIF/ENDIF ohne ENDIF} {Fehler} {es wurde ein \tty{ELSEIF}- oder \tty{ENDIF}-Befehl gefunden, obwohl kein offener \tty{IF}-Befehl vorhanden ist.} {keines} \errentry{1850}{verschachtelter/rekursiver Makroaufruf} {Fehler} {(nicht mehr verwendet)} {keines} \errentry{1860}{unbekannte Funktion} {Fehler} {Die angesprochene Funktion ist weder eingebaut noch nachtr"aglich definiert worden.} {der Funktionsname} \errentry{1870}{Funktionsargument au"serhalb Definitionsbereich} {Fehler} {Das Argument liegt nicht im Bereich der angesprochenen transzendenten Funktion.} {keines} \errentry{1880}{Gleitkomma"uberlauf} {Fehler} {Das Argument liegt zwar im Bereich der angesprochenen transzendenten Funktion, das Ergebnis w"are aber nicht mehr darstellbar.} {keines} \errentry{1890}{ung"ultiges Wertepaar} {Fehler} {Das benutzte P"archen aus Basis und Exponent kann nicht berechnet werden.} {keines} \errentry{1900}{Befehl darf nicht auf dieser Adresse liegen} {Fehler} {Die Prozessorhardware erlaubt keine Spr"unge von dieser Adresse.} {keines} \errentry{1905}{ung"ultiges Sprungziel} {Fehler} {Die Prozessorhardware erlaubt keine Spr"unge zu dieser Adresse.} {keines} \errentry{1910}{Sprungziel nicht auf gleicher Seite} {Fehler} {Sprungbefehl und Sprungziel m"ussen bei diesem Befehl auf der gleichen Seite liegen.} {keines} \errentry{1920}{Code"uberlauf} {Fehler} {Es wurde versucht, mehr als 1024 Bytes Code oder Daten in einer Zeile zu erzeugen.} {keines} \errentry{1925}{Adre"s"uberlauf} {Fehler} {Der Adre"sraum dieses Prozessors wurde "uberschritten.} {keines} \errentry{1930}{Konstanten und Platzhalter nicht mischbar} {Fehler} {Anweisungen, die Speicher reservieren und solche, die ihn mit Konstanten belegen, d"urfen nicht in einer Pseudoanweisung gemischt werden.} {keines} \errentry{1940}{Codeerzeugung in Strukturdefinition nicht zul"assig} {Fehler} {Ein \tty{STRUCT}-Konstrukt dient nur der Beschreibung einer Datenstruktur und nicht dem Anlegen einer solchen, es sind daher keine Befehle zugelassen, die Code erzeugen.} {keines} \errentry{1950}{Paralleles Konstrukt nicht m"oglich} {Fehler} {Entweder sind die beiden Instruktionen prinzipiell nicht parallel ausf"uhrbar, oder sie stehen nicht unmittelbar untereinander.} {keines} \errentry{1960}{ung"ultiges Segment} {Fehler} {Das angegebene Segment ist an dieser Stelle nicht anwendbar.} {der benutzte Segmentname} \errentry{1961}{unbekanntes Segment} {Fehler} {Das angegebene Segment existiert bei diesem Prozessor nicht.} {der benutzte Segmentname} \errentry{1962}{unbekanntes Segmentregister} {Fehler} {Das angegebene Segmentregister existiert nicht (nur 8086).} {keines} \errentry{1970}{ung"ultiger String} {Fehler} {Der angegebene String hat ein ung"ultiges Format.} {keines} \errentry{1980}{ung"ultiger Registername} {Fehler} {Das angegebene Register existiert nicht oder darf hier nicht verwendet werden.} {keines} \errentry{1985}{ung"ultiges Argument} {Fehler} {Der angegebene Befehl darf nicht mit einem \tty{REP}-Pr"afix versehen werden.} {keines} \errentry{1990}{keine Indirektion erlaubt} {Fehler} {in dieser Kombination ist keine indirekte Adressierung erlaubt.} {keines} \errentry{1995}{nicht im aktuellen Segment erlaubt} {Fehler} {(nicht mehr verwendet)} {keines} \errentry{1996}{nicht im Maximum-Modus zul"assig} {Fehler} {Dieses Register ist nur im Minimum-Modus definiert.} {keines} \errentry{1997}{nicht im Minimum-Modus zul"assig} {Fehler} {Dieses Register ist nur im Maximum-Modus definiert.} {keines} \errentry{2000}{ung"ultige Pr"afix-Kombination} {Fehler} {Die angegebene Kombination von Pr"afixen ist nicht zul"assig oder nicht im Maschinenkode darstellbar.} {keines} \errentry{2010}{Ung"ultige Escape-Sequenz} {Fehler} {Das mit einem Backslash eingeleitete Sonderzeichen ist nicht definiert.} {keines} \errentry{10001}{Fehler bein "Offnen der Datei} {fatal} {Beim Versuch, eine Datei zu "offnen, ist ein Fehler aufgetreten.} {Beschreibung des E/A-Fehlers} \errentry{10002}{Listingschreibfehler} {fatal} {Beim Schreiben des Assemblerlistings ist ein Fehler aufgetreten.} {Beschreibung des E/A-Fehlers} \errentry{10003}{Dateilesefehler} {fatal} {Beim Lesen aus einer Quelldatei ist ein Fehler aufgetreten.} {Beschreibung des E/A-Fehlers} \errentry{10004}{Dateischreibfehler} {fatal} {Beim Schreiben von Code- oder Share-Datei ist ein Fehler aufgetreten.} {Beschreibung des E/A-Fehlers} \errentry{10006}{Speicher"uberlauf} {fatal} {Der verf"ugbare Speicher reicht nicht mehr, alle Datenstrukturen aufzunehmen. Weichen Sie auf die DPMI- oder OS/2-Version von AS aus.} {keines} \errentry{10007}{Stapel"uberlauf} {fatal} {Der Programmstapel ist wegen zu komplizierter Formelausdr"ucke oder einer ung"unstigen Anlage der Symbol- oder Makrotabelle "ubergelaufen. Versuchen Sie es noch einmal mit der \tty{-A}-Option.} {keines} \end{description} %%=========================================================================== \cleardoublepage \chapter{E/A-Fehlermeldungen} Die hier aufgelisteten Fehlermeldungen werden nicht nur von AS bei E/A- Fehlern ausgegeben, sondern auch von den Hilfsprogrammen PLIST, BIND, P2HEX und P2BIN. Es sind nur die Fehler n"aher erkl"art, die m.E. bei der Arbeit auftreten k"onnen. Sollte doch einmal ein nicht erl"auterter E/A-Fehler auftreten, so d"urfte der Grund in einem Programmfehler liegen. Melden Sie dies unbedingt!! \begin{description} \item[2]{Datei nicht gefunden\\ Die angegebene Datei existiert nicht oder liegt auf einem anderen Laufwerk.} \item[3]{Pfad nicht gefunden\\ Der Pfad eines Dateinamens existiert nicht oder liegt auf einem anderen Laufwerk.} \item[4]{zu viele offene Dateien\\ DOS sind die Dateihandles ausgegangen. Erh"ohen Sie die \tty{FILES=}-Angabe in der CONFIG.SYS.} \item[5]{Dateizugriff verweigert\\ Entweder reichen die Netzwerkrechte f"ur einen Dateizugriff nicht, oder es wur\-de ver\-sucht, ei\-ne schreib\-ge\-sch"utz\-te Da\-tei zu "uber\-schrei\-ben oder zu ver\-"an\-dern. Bei Benutzung in DOS- Fenstern von Multitasking- Systemen ist es "uberdies m"oglich, da"s ein andere Proze"s die Datei in exklusivem Zugriff hat.} \item[6]{ung"ultiger Dateihandle} \item[12]{ung"ultiger Zugriffsmodus} \item[15]{ung"ultiger Laufwerksbuchstabe\\ Das angesprochene Laufwerk existiert nicht.} \item[16]{aktuelles Verzeichnis kann nicht gel"oscht werden} \item[17]{RENAME geht nicht "uber Laufwerke} \item[100]{vorzeitiges Dateiende\\ Eine Datei war zuende, obwohl sie es aufgrund ihrer Struktur noch nicht sein d"urfte. Vermutlich ist sie besch"adigt.} \item[101]{Diskette/Platte voll\\ Das spricht wohl f"ur sich! Aufr"aumen!!} \item[102]{ASSIGN fehlt} \item[103]{Datei nicht offen} \item[104]{Datei nicht f"ur Einlesen offen} \item[105]{Datei nicht f"ur Ausgaben offen} \item[106]{Ung"ultiges numerisches Format} \item[150]{Diskette ist schreibgesch"utzt\\ Wenn Sie schon keine Festplatte als Arbeitsmedium verwenden, so sollten Sie wenigstens den Schreibschutz entfernen!} \item[151]{Unbekanntes Ger"at\\ Sie haben versucht, ein Peripherieger"at anzusprechen, welches DOS unbekannt ist. Dies sollte normalerweise nicht auftreten, da der Name dann automatisch als Datei interpretiert wird.} \item[152]{Laufwerk nicht bereit\\ Schlie"sen Sie die Klappe des Diskettenlaufwerks.} \item[153]{unbekannte DOS-Funktion} \item[154]{Pr"ufsummenfehler auf Diskette/Platte\\ Ein harter Lesefehler auf der Diskette. Nochmal versuchen; wenn immer noch vorhanden, Diskette neu formatieren bzw. ernste Sorgen um Festplatte machen!} \item[155]{ung"ultiger DPB} \item[156]{Positionierfehler\\ Der Platten/Disketten-Controller hat eine bestimmte Spur nicht gefunden. Siehe Nr. 154!} \item[157]{unbekanntes Sektorformat\\ DOS kann mit dem Format der Diskette nichts anfangen.} \item[158]{Sektor nicht gefunden\\ Analog zu Nr. 158, nur da"s hier der angeforderte Sektor auf der Spur nicht gefunden werden konnte.} \item[159]{Papierende\\ Offensichtlich haben Sie die Ausgaben von AS direkt auf einen Drucker umgeleitet. Assemblerlistings k"onnen seeehr lang sein...} \item[160]{Ger"atelesefehler\\ Nicht n"aher vom Ger"atetreiber klassifizierter Lesefehler.} \item[161]{Ger"ateschreibfehler\\ Nicht n"aher vom Ger"atetreiber klassifizierter Schreibfehler.} \item[162]{allgemeiner Ger"atefehler\\ Hier ist der Ger"atetreiber v"ollig ratlos, was passiert sein k"onnte.} \end{description} %%=========================================================================== \cleardoublepage \chapter{H"aufig gestellte Fragen} In diesem Kapitel habe ich versucht, einige besonders h"aufig gestellte Fragen mit den passenden Antworten zu sammeln. Die Antworten auf die hier auftauchenden Probleme finden sich zwar auch an anderer Stelle in der Anleitung, jedoch findet man sie vielleicht nicht auf den ersten Blick... \begin{description} \item[F:]{Ich bin DOS leid. F"ur welche Plattformen gibt es AS sonst ?} \item[A:]{Neben der Protected-Mode-Version, die AS unter DOS mehr Speicher zur Verf"ugung stellt, existieren Portierungen f"ur OS/2 und Unix-Systeme wie z.B. Linux (im Teststadium). An Versionen, die Softwareherstellern in Redmond beim Geldscheffeln zuarbeiten w"urden, ist momentan nicht gedacht. Sofern jemand anders in dieser Hinsicht aktiv werden will, stelle ich ihm aber gerne die AS-Quellen zur Verf"ugung, von denen sich die C-Variante insbesondere eignen d"urfte. "Uber Fragen zu diesen Quellen hinaus sollte er sich aber nicht viel von mir erwarten...} \vspace{0.3cm} \item[F:]{Ist eine Unterst"utzung des XYZ-Prozessors f"ur AS geplant?} \item[A:]{Es kommen immer neue Prozessoren heraus, und ich bem"uhe mich, bei Erweiterung von AS Schritt zu halten. Der Stapel mit der Aufschrift ,,Unerledigt'' auf meinem Schreibtisch unterschreitet aber selten die 10cm-Grenze... Bei der Planung, welche Kandidaten zuerst abgearbeitet werden, spielen W"unsche von Anwendern nat"urlich eine gro"se Rolle. Das Internet und die steigende Zahl elektronisch publizierter Dokumentation erleichtern die Beschaffung von Unterlagen, speziell bei ausgefallenen oder "alteren Architekturen wird es aber immer wieder schwierig. Wenn sich die fragliche Prozessorfamilie nicht in der Liste in Planung befindlicher Prozessoren befindet (siehe Kapitel 1), macht es sich sehr gut, der Anfrage auch gleich ein passendes Datenbuch hinzuzupacken (zur Not auch leihweise!).} \vspace{0.3cm} \item[F:]{Ein freier Assembler ist ja eine feine Sache, aber eigentlich br"auchte ich jetzt auch noch einen Disassembler...und einen Debugger...ein Simulator w"are auch ganz nett..} \item[A:]{AS ist ein Freizeitprojekt von mir, d.h. etwas, was ich in der Zeit tue, wenn ich mich nicht gerade um den Broterwerb k"ummere. Von dieser Zeit nimmt AS schon einen ganz erheblichen Teil ein, und ab und zu genehmige ich mir auch mal eine Auszeit, um den L"otkolben zu schwingen, mal wieder eine Tangerine Dream-Platte bewu"st zu h"oren, mich vor den Fernseher zu hocken oder einfach nur dringenden menschlichen Bed"urfnissen nachzugehen. Ich habe einmal angefangen, einen Disassembler zu konzipieren, der wieder voll reassemblierbaren Code erzeugt und automatisch Daten- und Code-Bereiche trennt, habe das Projekt aber relativ schnell wieder eingestellt, weil die restliche Zeit f"ur so etwas einfach nicht mehr reicht. Ich mache lieber eine Sache gut als ein halbes Dutzend m"a"sig. Von daher mu"s die Antwort also wohl ,,nein'' hei"sen...} \vspace{0.3cm} \item[F:]{In den Bildschirmausgaben von AS tauchen seltsame Zeichen auf, z.B. Pfeile und eckige Klammern. Warum?} \item[A:]{AS verwendet zur Bildschirmsteuerung defaultm"a"sig einige ANSI-Terminal-Steuersequenzen. Haben Sie keinen ANSI-Treiber installiert, so kommen diese Steuerzeichen ungefiltert auf Ihrem Bildschirm heraus. Installieren Sie entweder einen ANSI-Treiber oder schalten Sie die Steuersequenzen mit dem DOS-Befehl \tty{SET USEANSI=N} ab.} \vspace{0.3cm} \item[F:]{W"ahrend der Assemblierung bricht AS pl"otzlich mit der Meldung eines Stapel"uberlaufes ab. Ist mein Programm zu kompliziert?} \item[A:]{Ja und Nein. Die Symboltabelle f"ur Ihr Programm ist nur etwas unregelm"a"sig gewachsen, was zu zu hohen Rekursionstiefen im Zugriff auf die Tabelle gef"uhrt hat. Diese Fehler treten insbesondere bei der 16-Bit-OS/2-Version von AS auf, die nur "uber einen relativ kleinen Stack verf"ugt. Starten Sie AS noch einmal mit dem \tty{-A}-Kommandozeilenschalter. Hilft dies auch nicht, so kommen als m"ogliche Problemstellen noch zu komplizierte Formelausdr"ucke in Frage. Versuchen Sie in einem solchen Fall, die Formel in Zwischenschritte aufzuspalten.} \vspace{0.3cm} \item[F:]{AS scheint mein Programm nicht bis zum Ende zu assemblieren. Mit einer "alteren Version von AS (1.39) hat es dagegen funktioniert.} \item[A:]{Neuere Versionen von AS ignorieren das \tty{END}-Statement nicht mehr, sondern beenden danach wirklich die Assemblierung. Insbesondere bei Include-Dateien ist es fr"uher vorgekommen, da"s Anwender jede Datei mit einem \tty{END}-Statement beendet haben. Entfernen Sie die "uberfl"ussigen \tty{END}s.} \vspace{0.3cm} \item[F:]{Weil ich noch ein paar kompliziertere Assemblierfehler im Programm hatte, habe ich mir ein Listing gemacht und es einmal genauer angeschaut. Dabei ist mir aufgefallen, da"s einige Spr"unge nicht auf das gew"unschte Ziel, sondern auf sich selbst zeigen!} \item[A:]{Dieser Effekt tritt bei Vorw"artsspr"ungen auf, bei denen der Formelparser von AS im ersten Pass die Zieladresse noch nicht kennen kann. Da der Formelparser ein unabh"angiges Modul ist, mu"s er sich in einem solchen Fall einen Wert ausdenken, der auch relativen Spr"ungen mit kurzer Reichweite nicht wehtut, und dies ist nun einmal die aktuelle Programmz"ahleradresse selber...im zweiten Pass w"aren die korrekten Werte erschienen, aber zu diesem ist es nicht gekommen, da schon im ersten Pass Fehler auftraten. Korrigieren Sie die anderen Fehler zuerst, so da"s AS zum zweiten Pass kommt, und das Listing sollte wieder vern"unftiger aussehen.} \vspace{0.3cm} \item[F:]{Mein Programm wird zwar korrekt assembliert, bei der Umwandlung mit P2BIN oder P2HEX erhalte ich aber nur eine leere Datei.} \item[A:]{Dann haben Sie wahrscheinlich das Adre"s\-fil\-ter nicht korrekt eingestellt. De\-faul\-tm"a"sig reicht der Filter von 0 bis 32 Kbyte, falls Ihr Programm Teile au"serhalb dieses Bereiches besitzen sollte, werden diese nicht "ubernommen. Sollte Ihr Code komplett jenseits 32 Kbyte liegen (wie es bei 65er und 68er-Prozessoren "ublich ist), dann erhalten Sie das von Ihnen geschilderte Ergebnis. Setzen Sie das Adre"sfilter einfach auf einen passenden Bereich (s. das Kapitel zu P2BIN/P2HEX).} \vspace{0.3cm} \item[F:]{Ich bekomme unter Unix bei der Benutzung von P2BIN oder P2HEX das Dollarzeichen nicht eingegeben. Die automatische Bereichsfestlegung funktioniert nicht, stattdessen gibt es eigenartige Fehlermeldungen.} \item[A:]{Unix-Shells benutzen das Dollarzeichen zur Expansion von Shell-Variablen. Wollen Sie ein Dollarzeichen an eine Anwendung durchreichen, stellen Sie einen Backslash (\verb!\!) voran. Im Falle der Adre"sangabe bei P2BIN und P2HEX darf aber auch \tty{0x} anstelle des Dollarzeichens benutzt werden, was dieses Problem von vornherein vermeidet.} \end{description} %%=========================================================================== \cleardoublepage \chapter{Pseudobefehle gesammelt} In diesem Anhang finden sich noch einmal als schnelle Referenz alle von AS zur Verf"ugung gestellten Pseudobefehle. Die Liste ist in zwei Teile gegliedert: Im ersten Teil finden sich Befehle, die unabh"angig vom eingestellten Zielprozessor vorhanden sind, danach folgen f"ur jede Prozessorfamilie die zus"atzlich vorhandenen Befehle: \subsubsection{Immer vorhandene Befehle} \input{pscomm.tex} Zus"atzlich existiert \tty{SET} bzw. \tty{EVAL}, falls \tty{SET} bereits ein Prozessorbefehl ist. \input{pscpu.tex} %%=========================================================================== \cleardoublepage \chapter{Vordefinierte Symbole}\label{AppInternSyms} \begin{table*}[ht] \begin{center}\begin{tabular}{|l|l|l|l|} \hline Name & Datentyp & Definition & Bedeutung \\ \hline\hline \tty{ARCHITECTURE} & String & vordef. & Zielplattform, f"ur die AS \\ & & & "ubersetzt wurde, in der Form \\ & & & Prozesor-Hersteller-Betriebs- \\ & & & system \\ \hline \tty{BIGENDIAN} & Boolean & normal & Konstantenablage mit MSB \\ & & & first ? \\ \hline \tty{CASESENSITIVE} & Boolean & normal & Unterscheidung von Gro"s- \\ & & & und Kleinbuchstaben in \\ & & & Symbolnamen ? \\ \hline \tty{CONSTPI} & Gleitkomma & normal & Kreiszahl Pi (3.1415.....) \\ \hline \tty{DATE} & String & vordef. & Datum des Beginns der \\ & & & Assemblierung (1.Pass) \\ \hline \tty{FALSE} & Boolean & vordef. & 0 = logisch ,,falsch'' \\ \hline \tty{HASFPU} & Boolean & dynam.(0) & Koprozessor-Befehle \\ & & & freigeschaltet ? \\ \hline \tty{HASPMMU} & Boolean & dynam.(0) & MMU-Befehle frei- \\ & & & geschaltet ? \\ \hline \tty{INEXTMODE} & Boolean & dynam.(0) & XM-Flag f"ur 4 Gbyte \\ & & & Adre"sraum gesetzt ? \\ \hline \tty{INLWORDMODE} & Boolean & dynam.(0) & LW-Flag f"ur 32-Bit-Befehle \\ & & & gesetzt ? \\ \hline \tty{INMAXMODE} & Boolean & dynam.(0) & Prozessor im Maximum- \\ & & & Modus ? \\ \hline \tty{INSUPMODE} & Boolean & dynam.(0) & Prozessor im Supervisor- \\ & & & Modus ? \\ \hline \tty{INSRCMODE} & Boolean & dynam.(0) & Prozessor im Quellmodus ? \\ \hline \tty{FULLPMMU} & Boolean & dynam.(0/1) & voller PMMU-Befehlssatz ? \\ \hline \tty{LISTON} & Boolean & dynam.(1) & Listing freigeschaltet ? \\ \hline \end{tabular}\end{center} \caption{Vordefinierte Symbole - Teil 1\label{TabInternSyms1}} \end{table*} \begin{table*} \begin{center}\begin{tabular}{|l|l|l|l|} \hline Name & Datentyp & Definition & Bedeutung \\ \hline\hline \tty{MACEXP} & Boolean & dynam.(1) & Expansion von Makrokon- \\ & & & strukten im Listing \\ & & & freigeschaltet ? \\ \hline \tty{MOMCPU} & Integer & dynam. & Nummer der momentan \\ & & (68008) & gesetzten Ziel-CPU \\ \hline \tty{MOMCPUNAME} & String & dynam. & Name der momentan \\ & & (68008) & gesetzten Ziel-CPU \\ \hline \tty{MOMFILE} & String & Spezial & augenblickliche Quelldatei \\ & & & (schlie"st Includes ein) \\ \hline \tty{MOMLINE} & Integer & Spezial & aktuelle Zeilennummer in \\ & & & der Quelldatei \\ \hline \tty{MOMPASS} & Integer & Spezial & Nummer des laufenden \\ & & & Durchgangs \\ \hline \tty{MOMSECTION} & String & Spezial & Name der aktuellen Sektion \\ & & & oder Leerstring, fall au"ser- \\ & & & halb aller Sektionen \\ \hline \tty{MOMSEGMENT} & String & Spezial & Name des mit \tty{SEGMENT} ein- \\ & & & gestellten Adre"sraumes \\ \hline \tty{PADDING} & Boolean & dynam.(1) & Auff"ullen von Bytefeldern \\ & & & auf ganze Anzahl ? \\ \hline \tty{RELAXED} & Boolean & dynam.(0) & Schreibweise von Integer-Kon- \\ & & & stanten in beliebiger Syntax \\ & & & erlaubt ? \\ \hline \tty{PC} & Integer & Spezial & mom. Programmz"ahler \\ & & & (Thomson) \\ \hline \tty{TIME} & String & vordef. & Zeit des Beginns der Assem- \\ & & & blierung (1. Pass) \\ \hline \tty{TRUE} & Integer & vordef. & 1 = logisch ,,wahr'' \\ \hline \tty{VERSION} & Integer & vordef. & Version von AS in BCD-Kodie- \\ & & & rung, z.B. 1331 hex f"ur \\ & & & Version 1.33p1 \\ \hline \tty{WRAPMODE} & Integer & vordef. & verk"urzter Programmz"ahler \\ & & & angenommen? \\ \hline \verb!*! & Integer & Spezial & mom. Programmz"ahler (Motorola, \\ & & & Rockwell, Microchip, Hitachi) \\ \hline \tty{\$} & Integer & Spezial & mom. Programmz"ahler (Intel, \\ & & & Zilog, Texas, Toshiba, NEC, \\ & & & Siemens, AMD) \\ \hline \end{tabular}\end{center} \caption{Vordefinierte Symbole - Teil 2\label{TabInternSyms2}} \end{table*} \par Boolean-Symbole sind eigentlich normale normale Integer-Symbole, mit dem Unterschied, da"s ihnen von AS nur zwei verschiedene Werte (0 oder 1, entsprechend FALSE oder TRUE) zugewiesen werden. Spezialsymbole werden von AS nicht in der Symboltabelle abgelegt, sondern aus Geschwindigkeitsgr"unden direkt im Parser abgefragt. Sie tauchen daher auch nicht in der Symboltabelle des Listings auf. W"ahrend vordefinierte Symbole nur einmal am Anfang eines Passes besetzt werden, k"onnen sich die Werte dynamischer Symbole w"ahrend der Assemblierung mehrfach "andern, da sie mit anderen Befehlen vorgenommene Einstellungen widerspiegeln. \par Die hier aufgelistete Schreibweise ist diejenige, mit der man die Symbole auch im case-sensitiven Modus erreicht. \par Die hier aufgef"uhrten Namen sollte man f"ur eigene Symbole meiden; entweder kann man sie zwar definieren, aber nicht darauf zugreifen (bei Spezialsymbolen), oder man erh"alt eine Fehlermeldung wegen eines doppelt definierten Symboles. Im gemeinsten Fall f"uhrt die Neubelegung durch AS zu Beginn eines Passes zu einem Phasenfehler und einer Endlosschleife... %%=========================================================================== \cleardoublepage \chapter{Mitgelieferte Includes} Der Distribution von AS liegen eine Reihe von Include-Dateien bei. Neben Includes, die sich nur auf eine Prozessorfamilie beziehen (und deren Funktion sich demjenigen unmittelbar erschlie"st, der mit dieser Familie arbeitet), existieren aber auch ein paar Dateien, die prozessorunabh"angig sind und die eine Reihe n"utzlicher Funktionen implementieren. Die definierten Funktionen sollen hier kurz beschrieben werden: \section{BITFUNCS.INC} Diese Datei definiert eine Reihe bitorientierter Operationen, wie man sie bei anderen Assemblern vielleicht fest eingebaut sind. Bei AS werden sie jedoch mit Hilfe benutzerdefinierter Funktionen implementiert: \begin{itemize} \item{{\em mask(start,bits)} liefert einen Integer, in dem ab Stelle {\em start} {\em bits} Bits gesetzt sind;} \item{{\em invmask(start,bits)} liefert das Einerkomplement zu {\em mask()};} \item{{\em cutout(x,start,bits)} liefert ausmaskierte {\em bits} Bits ab Stelle {\em start} aus {\em x}, ohne sie auf Stelle 0 zu verschieben;} \item{{\em hi(x)} liefert das zweitniedrigste Byte (Bit 8..15) aus {\em x};} \item{{\em lo(x)} liefert das niederwertigste Byte (Bit 0..7) aus {\em x};} \item{{\em hiword(x)} liefert das zweitniedrigste Wort (Bit 16..31) aus {\em x};} \item{{\em loword(x)} liefert das niederwertigste Wort (Bit 0..15) aus {\em x};} \item{{\em odd(x)} liefert TRUE, falls {\em x} ungerade ist;} \item{{\em even(x)} liefert TRUE, falls {\em x} gerade ist;} \item{{\em getbit(x,n)} extrahiert das Bit {\em n} aus {\em x} und liefert es als 0 oder 1;} \item{{\em shln(x,size,n)} schiebt ein Wort {\em x} der L"ange {\em size} Bits um {\em n} Stellen nach links;} \item{{\em shrn(x,size,n)} schiebt ein Wort {\em x} der L"ange {\em size} Bits um {\em n} Stellen nach rechts;} \item{{\em rotln(x,size,n)} rotiert die untersten {\em size} Bits eines Integers {\em x} um {\em n} Stellen nach links;} \item{{\em rotrn(x,size,n)} rotiert die untersten {\em size} Bits eines Integers {\em x} um {\em n} Stellen nach rechts;} \end{itemize} \section{CTYPE.INC} Dieser Include ist das Pendant zu dem bei C vorhandenen Header {\tt ctype.h}, der Makros zur Klassifizierung von Zeichen anbietet. Alle Funktionen liefern entweder TRUE oder FALSE: \begin{itemize} \item{{\em isdigit(ch)} ist TRUE, falls {\em ch} eine Ziffer (0..9) ist;} \item{{\em isxdigit(ch)} ist TRUE, falls {\em ch} eine g"ultige Hexadezimal-Ziffer (0..9, A..F, a..f) ist;} \item{{\em isascii(ch)} ist TRUE, falls {\em ch} sich im Bereich normaler ASCII-Zeichen ohne gesetztes Bit 7 bewegt;} \item{{\em isupper(ch)} ist TRUE, falls {\em ch} ein Gro"sbuchstabe ist (Sonderzeichen ausgenommen);} \item{{\em islower(ch)} ist TRUE, falls {\em ch} ein Kleinbuchstabe ist (Sonderzeichen ausgenommen);} \item{{\em isalpha(ch)} ist TRUE, falls {\em ch} ein Buchstabe ist (Sonderzeichen ausgenommen);} \item{{\em isalnum(ch)} ist TRUE, falls {\em ch} ein Buchstabe oder eine Ziffer ist);} \item{{\em isspace(ch)} ist TRUE, falls {\em ch} ein 'Leerzeichen' (Space, Formfeed, Zeilenvorschub, Wagenr"ucklauf, Tabulator) ist);} \item{{\em isprint(ch)} ist TRUE, falls {\em ch} ein druckbares Zeichen ist (also kein Steuerzeichen bis Code 31);} \item{{\em iscntrl(ch)} ist das Gegenteil zu {\em isprint()};} \item{{\em isgraph(ch)} ist TRUE, falls {\em ch} ein druckbares und {\it sichtbares} Zeichen ist;} \item{{\em ispunct(ch)} ist TRUE, falls {\em ch} ein druckbares Sonderzeichen ist (d.h. weder Space, Buchstabe noch Ziffer);} \end{itemize} %%=========================================================================== \cleardoublepage \chapter{Danksagungen} \begin{quote}{\it ''If I have seen farther than other men, \\ it is because I stood on the shoulders of giants.'' \\ \hspace{2cm} --Sir Isaac Newton} \end{quote} \begin{quote}{\it ''If I haven't seen farther than other men, \\ it is because I stood in the footsteps of giants.'' \\ \hspace{2cm} --unknown} \end{quote} \par Wenn man sich entschlie"st, ein solches Kapitel neu zu schreiben, nachdem es eigentlich schon zwei Jahre veraltet ist, l"auft man automatisch Gefahr, da"s dabei der eine oder andere gute Geist, der etwas zum bisherigen Gelingen dieses Projektes beigetragen hat, vergessen wird. Der allererste Dank geb"uhrt daher allen Personen, die ich in der folgenden Aufz"ahlung unfreiwillig unterschlagen habe! \par AS als Universalassembler, wie er jetzt besteht, ist auf Anregung von Bernhard (C.) Zschocke entstanden, der einen ,,studentenfreundlichen'', d.h. kostenlosen 8051-Assembler f"ur sein Mikroprozessorpraktikum brauchte und mich dazu bewegt hat, einen bereits bestehenden 68000-Assembler zu erweitern. Von dortan nahm die Sache ihren Lauf... Das Mikroprozessorpraktikum an der RWTH Aachen hat auch immer die eifrigsten Nutzer der neuesten AS-Features (und damit Bug-Sucher) gestellt und damit einiges zur jetzigen Qualit"at von AS beigetragen. \par Das Internet und FTP haben sich als gro"se Hilfe bei der Meldung von Bugs und der Verbreitung von AS erwiesen. Ein Dank geht daher an die FTP-Administratoren (Bernd Casimir in Stuttgart, Norbert Breidohr in Aachen und J"urgen Mei"sburger in J"ulich). Insbesondere letzterer hat sich sehr engagiert, um eine praxisnahe L"osung im ZAM zu finden. \par Ach ja, wo wir schon im ZAM sind: Wolfgang E. Nagel hat zwar nichts direkt mit AS zu tun, immerhin ist er aber mein Chef und wirft st"andig vier Augen auf das, was ich tue. Bei AS scheint zumindest ein lachendes dabei zu sein... \par Ohne Datenb"ucher und Unterlagen zu Prozessoren ist ein Programm wie AS nicht zu machen. Ich habe von einer enormen Anzahl von Leuten Informationen bekommen, die von einem kleinen Tip bis zu ganzen Datenb"uchern reichen. Hier eine Aufz"ahlung (wie oben gesagt, ohne Garantie auf Vollst"andigkeit!): \par Ernst Ahlers, Charles Altmann, Rolf Buchholz, Bernd Casimir, Gunther Ewald, Stephan Hruschka, Peter Kliegelh"ofer, Ulf Meinke, Matthias Paul, Norbert Rosch, Steffen Schmid, Leonhard Schneider, Ernst Schwab, Michael Schwingen, Oliver Sellke, Christian Stelter, Oliver Thamm, Thorsten Thiele. \par ...und ein geh"assiger Dank an Rolf-Dieter-Klein und Tobias Thiel, die mit ihren ASM68K demonstrierten, wie man es \bb{nicht} machen sollte und mich damit indirekt dazu angeregt haben, etwas besseres zu schreiben! \par So ganz allein habe ich AS nicht verzapft. AS enth"alt die OverXMS-Routinen von Wilbert van Leijen, um die Overlay-Module ins Extended Memory verlagern zu k"onnen. Eine wirklich feine Sache, einfach und problemlos anzuwenden! \par Die TMS320C2x/5x-Codegeneratoren sowie die Datei \tty{STDDEF2x.INC} stammen von Thomas Sailer, ETH Z"urich. Erstaunlich, an einem Wochenende hat er es geschafft, durch meinen Code durchzusteigen und den neuen Generator zu implementieren. Entweder waren das reichliche Nachtschichten oder ich werde langsam alt... %%=========================================================================== \cleardoublepage \chapter{"Anderungen seit Version 1.3} \begin{itemize} \item{Version 1.31: \begin{itemize} \item{zus"atzlicher MCS-51-Prozessortyp 80515. Die Nummer wird wiederum nur vom Assembler verwaltet. Die Datei STDDEF51.INC wurde um die dazugeh"origen SFRs erweitert. \bb{ACHTUNG!} Einige 80515-SFRs haben sich adre"sm"a"sig verschoben!} \item{zus"atzlich Prozessor Z80 unterst"utzt;} \item{schnellerer 680x0-Codegenerator.} \end{itemize}} \item{Version 1.32: \begin{itemize} \item{Schreibweise von Zeropageadressen f"ur 65xx nicht mehr als Adr.z, sondern wie beim 68xx als $<$Adr;} \item{unterst"utzt die Prozessoren 6800, 6805, 6301 und 6811;} \item{der 8051-Teil versteht jetzt auch \tty{DJNZ}, \tty{PUSH} und \tty{POP} (sorry);} \item{im Listing werden neben den Symbolen jetzt auch die definierten Makros aufgelistet;} \item{Befehle \tty{IFDEF}/\tty{IFNDEF} f"ur bedingte Assemblierung, mit denen sich die Existenz eines Symboles abfragen l"a"st;} \item{Befehle \tty{PHASE}/\tty{DEPHASE} zur Unterst"utzung von Code, der zur Laufzeit auf eine andere Adresse verschoben werden soll;} \item{Befehle \tty{WARNING}/\tty{ERROR}/\tty{FATAL}, um anwenderspezifische Fehlermeldungen ausgeben zu k"onnen;} \item{Die Datei STDDEF51.INC enth"alt zus"atzlich das Makro \tty{USING} zur einfacheren Handhabung der Registerb"anke der MCS-51er;} \item{Kommandozeilenoption \tty{u}, um Segmentbelegung anzuzeigen.} \end{itemize}} \item{Version 1.33: \begin{itemize} \item{unterst"utzt den 6809;} \item{zus"atzlich Stringvariablen;} \item{Die Befehle \tty{TITLE}, \tty{PRTINIT}, \tty{PRTEXIT}, \tty{ERROR}, \tty{WARNING} und \tty{FATAL} erwarten jetzt einen Stringausdruck als Parameter, Konstanten m"ussen demzufolge nicht mehr in Hochkommas, sondern in G"ansef"u"schen eingeschlossen werden. Analoges gilt f"ur \tty{DB}, \tty{DC.B} und \tty{BYT};} \item{Befehl \tty{ALIGN} zur Ausrichtung des Programmz"ahlers bei Intel- Prozessoren;} \item{Befehl \tty{LISTING}, um die Erzeugung eines Listings ein- und ausschalten zu k"onnen;} \item{Befehl \tty{CHARSET} zur Definition eigener Zeichens"atze.} \end{itemize}} \item{Version 1.34: \begin{itemize} \item{Wenn im ersten Pass Fehler auftreten, wird gar kein zweiter Pass mehr durchgef"uhrt;} \item{neues vordefiniertes Symbol \tty{VERSION}, welches die Version von AS enth"alt;} \item{Befehl \tty{MESSAGE}, um Durchsagen und Meldungen programmgesteuert zu erzeugen;} \item{Formelparser "uber Stringkonstanten zug"anglich;} \item{Bei Fehler in Makroexpansionen wird zus"atzlich die laufende Zeile im Makro angezeigt;} \item{Funktion \tty{UPSTRING}, um einen String in Gro"sbuchstaben zu wandeln.} \end{itemize}} \item{Version 1.35: \begin{itemize} \item{Funktion \tty{TOUPPER}, um ein einzelnes Zeichen in Gro"sbuchstaben zu wandeln;} \item{Befehl \tty{FUNCTION}, um eigene Funktionen definieren zu k"onnen;} \item{Kommandozeilenoption \tty{D}, um Symbole von au"sen definieren zu k"onnen;} \item{Fragt die Environment-Variable \tty{ASCMD} f"ur h"aufig gebrauchte Optionen ab;} \item{bei gesetzter \tty{u}-Option wird das Programm zus"atzlich auf doppelt belegte Speicherbereiche abgepr"uft;} \item{Kommandozeilenoption \tty{C}, um eine Querverweisliste zu erzeugen.} \end{itemize}} \item{Version 1.36: \begin{itemize} \item{unterst"utzt zus"atzlich die Familien PIC 16C5x und PIC17C4x;} \item{im Listing wird zus"atzlich die Verschachtelungsebene bei Include-Dateien angezeigt;} \item{in der Querverweisliste wird zus"atzlich die Stelle angezeigt, an der ein Symbol definiert wurde;} \item{Kommandozeilenoption \tty{A}, um eine kompaktere Ablage der Symboltabelle zu erzwingen.} \end{itemize}} \item{Version 1.37: \begin{itemize} \item{unterst"utzt zus"atzlich die Prozessoren 8086, 80186, V30, V35, 8087 und Z180;} \item{Befehle \tty{SAVE} und \tty{RESTORE} zur besseren Umschaltung von Flags;} \item{Operatoren zur logischen Verschiebung und Bitspiegelung;} \item{Kommandozeilenoptionen k"onnen mit einem Pluszeichen negiert werden;} \item{Filter \tty{AS2MSG} zur bequemen Arbeit mit AS unter Turbo-Pascal 7.0;} \item{\tty{ELSEIF} darf ein Argument zur Bildung von \tty{IF-THEN-ELSE}-Leitern haben;} \item{Zur bequemeren bedingten Assemblierung zus"atzlich ein \tty{CASE}-Konstrukt;} \item{Selbstdefinierte Funktionen d"urfen mehr als ein Argument haben;} \item{P2HEX kann nun auch Hexfiles f"ur 65er-Prozessoren erzeugen;} \item{BIND, P2HEX und P2BIN haben jetzt die gleichen Variationsm"oglichkeiten in der Kommandozeile wie AS;} \item{Schalter \tty{i} bei P2HEX, um 3 Varianten f"ur den Ende-Record einzustellen;} \item{Neue Funktionen \tty{ABS} und \tty{SGN};} \item{Neue Pseudovariablen \tty{MOMFILE} und \tty{MOMLINE};} \item{Ausgabem"oglichkeit erweiterter Fehlermeldungen;} \item{Befehle \tty{IFUSED} und \tty{IFNUSED}, um abzufragen, ob ein Symbol bisher benutzt wurde;} \item{Die Environment-Variablen \tty{ASCMD}, \tty{BINDCMD} usw. k"onnen auch einen Dateinamen enthalten, in dem f"ur die Optionen mehr Platz ist;} \item{P2HEX erzeugt nun die von Microchip vorgegebenen Hex-Formate (p4);} \item{mit der Seitenl"angenangabe 0 k"onnen automatische Seitenvorsch"ube im Listing vollst"andig unterdr"uckt werden (p4);} \item{neue Kommandozeilenoption \tty{P}, um die Ausgabe des Makroprozessors in eine Datei zu schreiben (p4);} \item{in der Kommandozeile definierte Symbole d"urfen nun auch mit einem frei w"ahlbaren Wert belegt werden (p5).} \end{itemize}} \item{Version 1.38: \begin{itemize} \item{Umstellung auf Mehrpass-Betrieb. Damit kann AS auch bei Vorw"artsreferenzen immer den optimalen Code erzeugen;} \item{Der 8051-Teil kennt nun auch die Befehle \tty{JMP} und \tty{CALL};} \item{unterst"utzt zus"atzlich die Toshiba TLCS-900-Reihe (p1);} \item{Befehl \tty{ASSUME}, um dem Assembler die Belegung der Segmentregister des 8086 mitzuteilen (p2);} \item{unterst"utzt zus"atzlich die ST6-Reihe von SGS-Thomson (p2);} \item{..sowie die 3201x-Signalprozessoren von Texas Instruments (p2);} \item{Option \tty{F} bei P2HEX, um die automatische Formatwahl "ubersteuern zu k"onnen (p2);} \item{P2BIN kann nun auch durch Angabe von Dollarzeichen Anfang und Ende des Adre"sfensters selbstst"andig festlegen (p2);} \item{Der 8048-Codegenerator kennt nun auch die 8041/42- Befehlserweiterungen(p2);} \item{unterst"utzt zus"atzlich die Zilog Z8-Mikrokontroller(p3).} \end{itemize}} \item{Version 1.39: \begin{itemize} \item{Definitionsm"oglichkeit von Sektionen und lokalen Labels;} \item{Kommandozeilenschalter \tty{h}, um Hexadezimalzahlenausgabe mit Kleinbuchstaben zu erzwingen;} \item{Variable \tty{MOMPASS}, um die Nummer des augenblicklichen Durchganges abfragen zu k"onnen;} \item{Kommandozeilenschalter \tty{t}, um einzelne Teile des Assemblerlistings ausblenden zu k"onnen;} \item{kennt zus"atzlich die L-Variante der TLCS-900-Reihe von Toshiba und die MELPS-7700-Reihe von Mitsubishi (p1);} \item{P2HEX akzeptiert nun auch Dollarzeichen f"ur Start-und Endadresse (p2);} \item{unterst"utzt zus"atzlich die TLCS90-Familie von Toshiba (p2);} \item{P2HEX kann Daten zus"atzlich im Tektronix- und 16-Bit Intel-Hex-Format ausgeben (p2);} \item{bei Adre"s"uberschreitungen gibt P2HEX Warnungen aus (p2);} \item{Include-Datei STDDEF96.INC mit Adre"sdefinitionen f"ur die TLCS-900-Reihe (p3);} \item{Befehl \tty{READ}, um Werte w"ahrend der Assemblierung interaktiv einlesen zu k"onnen (p3);} \item{Fehlermeldungen werden nicht mehr einfach auf die Standardausgabe, sondern auf den von DOS daf"ur vorgesehenen Kanal (STDERR) geschrieben (p3);} \item{Der beim 6811-Teil fehlende \tty{STOP}-Befehl ist nun da (scusi,p3);} \item{unterst"utzt zus"atzlich die $\mu$PD78(C)1x-Familie von NEC (p3);} \item{unterst"utzt zus"atzlich den PIC16C84 von Microchip (p3);} \item{Kommandozeilenschalter \tty{E}, um die Fehlermeldungen in eine Datei umleiten zu k"onnen (p3);} \item{Die Unklarheiten im 78(C)1x-Teil sind beseitigt (p4);} \item{neben dem MELPS-7700 ist nun auch das ,,Vorbild'' 65816 vorhanden (p4);} \item{Die ST6-Pseudoanweisung \tty{ROMWIN} wurde entfernt und mit in den \tty{ASSUME}-Befehl eingegliedert (p4);} \item{unterst"utzt zus"atzlich den 6804 von SGS-Thomson (p4);} \item{durch die \tty{NOEXPORT}-Option in der Makrodefinition kann nun f"ur jedes Makro einzeln festgelegt werden, ob es in der MAC-Datei erscheinen soll oder nicht (p4);} \item{Die Bedeutung von \tty{MACEXP} f"ur Expansionen von Makros hat sich wegen der zus"atzlichen \tty{NOEXPAND}-Option in der Makrodefinition leicht ge"andert (p4);} \item{Durch die \tty{GLOBAL}-Option in der Makrodefinition k"onnen nun zus"atzlich Makros definiert werden, die durch ihren Sektionsnamen eindeutig gekennzeichnet sind (p4).} \end{itemize}} \item{Version 1.40: \begin{itemize} \item{unterst"utzt zus"atzlich den DSP56000 von Motorola;} \item{P2BIN kann nun auch das untere bzw. obere Wort aus 32-Bit-W"ortern abtrennen;} \item{unterst"utzt zus"atzlich die TLCS-870- und TLCS-47-Familie von Toshiba(p1);} \item{mit einem vorangestelltem ! kann man durch Makros ,,verdeckte'' Maschinenbefehle wieder erreichen(p1);} \item{mit der \tty{GLOBAL}-Anweisung lassen sich Symbolnamen nun auch qualifiziert exportieren(p1);} \item{mit der \tty{r}-Option kann man sich nun eine Liste der Stellen erzeugen lassen, die zus"atzliche Durchl"aufe erzwangen(p1);} \item{bei der \tty{E}-Option kann nun die Dateiangabe weggelassen werden, so da"s ein passender Default gew"ahlt wird(p1);} \item{mit der \tty{t}-Option kann nun die Zeilennumerierung im Listing abgeschaltet werden(p1);} \item{Escapesequenzen sind nun auch in in ASCII geschriebenen Integerkonstanten zul"assig(p1);} \item{Mit dem Pseudobefehl \tty{PADDING} kann das Einf"ugen von F"ullbytes im 680x0-Modus ein- und ausgeschaltet werden (p2);} \item{\tty{ALIGN} ist nun f"ur alle Zielplattformen erlaubt (p2);} \item{kennt zus"atzlich die PIC16C64-SFRs (p2);} \item{unterst"utzt zus"atzlich den 8096 von Intel (p2);} \item{Bei \tty{DC} kann zus"atzlich ein Wiederholungsfaktor angegeben werden (r3);} \item{unterst"utzt zus"atzlich die TMS320C2x-Familie von Texas Instruments (Implementierung von Thomas Sailer, ETH Z"urich, r3); P2HEX ist auch entsprechend erweitert;} \item{statt \tty{EQU} darf nun auch einfach ein Gleichheitszeichen benutzt werden (r3);} \item{zur Definition von Aufz"ahlungen zus"atzlich ein \tty{ENUM}-Befehl (r3);} \item{\tty{END} hat jetzt auch eine Wirkung (r3);} \item{zus"atzliche Kommandozeilenoption \tty{n}, um zu Fehlermeldungen zus"atzlich die internen Fehlernummern zu erhalten (r3);} \item{unterst"utzt zus"atzlich die TLCS-9000er von Toshiba (r4)}; \item{unterst"utzt zus"atzlich die TMS370xxx-Reihe von Texas Instuments, wobei als neuer Pseudobefehl \tty{DBIT} hinzukam (r5);} \item{kennt zus"atzlich die DS80C320-SFRs (r5);} \item{der Makroprozessor kann nun auch Includes aus Makros heraus einbinden, wozu das Format von Fehlermeldungen aber leicht ge"andert werden mu"ste. Falls Sie AS2MSG verwenden, ersetzen Sie es unbedingt durch die neue Version! (r5)} \item{unterst"utzt zus"atzlich den 80C166 von Siemens (r5);} \item{zus"atzlich eine \tty{VAL}-Funktion, um Stringausdr"ucke auswerten zu k"onnen (r5);} \item{Mithilfe von in geschweiften Klammern eingeschlossenen Stringvariablen lassen sich nun selber Symbole definieren (r5);} \item{kennt zus"atzlich die Eigenheiten des 80C167 von Siemens (r6);} \item{jetzt gibt es f"ur die MELPS740-Reihe auch die special-page-Adressierung (r6);} \item{mit eckigen Klammern kann man explizit Symbole aus einer bestimmten Sektion ansprechen. Die Hilfskonstruktion mit dem Klammeraffen gibt es nicht mehr (r6)!} \item{kennt zus"atzlich die MELPS-4500-Reihe von Mitsubishi (r7);} \item{kennt zus"atzlich die H8/300 und H8/300H-Prozessoren von Hitachi (r7);} \item{die mit \tty{LISTING} und \tty{MACEXP} gemachten Einstellungen lassen sich nun auch wieder aus gleichnamigen Symbolen auslesen (r7);} \item{kennt zus"atzlich den TMS320C3x von Texas Instruments (r8);} \item{kennt zus"atzlich den SH7000 von Hitachi (r8);} \item{der Z80-Teil wurde um die Unterst"utzung des Z380 erweitert (r9);} \item{der 68K-Teil wurde um die feinen Unterschiede der 683xx-Mikrokontroller erweitert (r9);} \item{ein Label mu"s nun nicht mehr in der ersten Spalte beginnen, wenn man es mit einem Doppelpunkt versieht (r9);} \item{kennt zus"atzlich die 75K0-Reihe von NEC (r9);} \item{mit dem neuen Kommandozeilenschalter o kann der Name der Code-Datei neu festgelegt werden (r9);} \item{der \verb!~~!-Operator ist in der Rangfolge auf einen sinnvolleren Platz gerutscht (r9);} \item{\tty{ASSUME} ber"ucksichtigt f"ur den 6809 jetzt auch das DPR-Register und seine Auswirkungen (pardon, r9);} \item{Der 6809-Teil kennt nun auch die versteckten Erweiterungen des 6309 (r9);} \item{Bin"arkonstanten k"onnen jetzt auch in C-artiger Notation geschrieben werden (r9).} \end{itemize}} \item{Version 1.41: \begin{itemize} \item{"uber das Symbol \tty{MOMSEGMENT} kann der momentan gesetzte Adre"sraum abgefragt werden;} \item{anstelle von \tty{SET} bzw. \tty{EVAL} kann jetzt auch einfach \tty{:=} geschrieben werden;} \item{mit der neuen Kommandozeilenoption \tty{q} kann ein ,,stiller'' Assemblerlauf erzwungen werden;} \item{das Schl"usselwort \tty{PARENT} zum Ansprechen der Vatersektion wurde um \tty{PARENT0...PARENT9} erweitert;} \item{der PowerPC-Teil wurde um die Mikrokontroller-Versionen MPC505 und PPC403 erweitert;} \item{mit \tty{SET} oder \tty{EQU} definierte Symbole k"onnen nun einem bestimmten Adre"sraum zugeordnet werden;} \item{mit \tty{SET} oder \tty{EQU} definierte Symbole k"onnen nun einem bestimmten Adre"sraum zugeordnet werden;} \item{durch das Setzen der Environment-Variablen \tty{USEANSI} kann die Verwendung von ANSI-Bildschirmsteuersequenzen an-und ausgeschaltet werden (r1);} \item{der SH7000-Teil kennt jetzt auch die SH7600-Befehlserweiterungen (und sollte jetzt korrekte Displacements berechnen...) (r1).} \item{im 65XX-Teil wird jetzt zwischen 65C02 und 65SC02 unterschieden (r1);} \item{neben der Variablen \tty{MOMCPU} gibt es jetzt auch den String \tty{MOMCPUNAME}, der den Prozessornamen im Volltext enth"alt (r1).} \item{P2HEX kennt jetzt auch die 32-Bit-Variante des Intel-Hex-Formates (r1);} \item{kennt jetzt auch die Einschr"ankungen des 87C750 (r2);} \item{die Nummern f"ur fatale Fehlermeldungen wurden auf den Bereich ab 10000 verschoben, um Platz f"ur normale Fehlermeldungen zu schaffen (r2);} \item{unbenutzte Symbole werden in der Symboltabelle jetzt mit einem Stern gekennzeichnet (r2);} \item{unterst"utzt zus"atzlich die 29K-Familie von AMD (r2);} \item{unterst"utzt zus"atzlich die M16-Familie von Mitsubishi (r2);} \item{unterst"utzt zus"atzlich die H8/500-Familie von Hitachi (r3);} \item{die Anzahl von Datenbytes, die P2HEX pro Zeile ausgibt, ist jetzt variierbar (r3);} \item{der Pass, ab dem durch die \tty{-r}-Option erzeugte Warnungen ausgegeben werden, ist einstellbar (r3);} \item{der Makroprozessor kennt jetzt ein \tty{WHILE}-Statement, mit dem ein Code-St"uck eine variable Anzahl wiederholt werden kann (r3);} \item{der \tty{PAGE}-Befehl erlaubt es nun auch, die Breite des Ausgabemediums f"urs Listing anzugeben (r3);} \item{Um neue Pseudo-Prozessortypen einf"uhren zu k"onnen, lassen sich jetzt CPU-Aliasse definieren (r3);} \item{unterst"utzt zus"atzlich die MCS/251-Familie von Intel (r3);} \item{bei eingeschalteter Querverweisliste wird bei doppelt definierten Symbolen die Stelle der ersten Definition angezeigt (r3);} \item{unterst"utzt zus"atzlich die TMS320C5x-Familie von Texas Instruments (Implementierung von Thomas Sailer, ETH Z"urich, r3);} \item{die OS/2-Version sollte jetzt auch mit langen Dateinamen klarkommen. Wenn man nicht jeden Mist selber kontrolliert... (r3)} \item{"uber den Befehl \tty{BIGENDIAN} kann im MCS-51/251-Modus jetzt gew"ahlt werden, ob die Ablage von Konstanten im Big- oder Little-Endian-Format erfolgen soll (r3);} \item{es wird beim 680x0 jetzt zwischen dem vollen und eingeschr"ankten MMU-Befehlssatz unterschieden; eine manuelle Umschaltung ist mit dem \tty{FULLPMMU}-Befehl m"oglich (r3);} \item{"uber die neue Kommandozeilenoption \tty{I} kann eine Liste aller eingezogenen Include-Files mit ihrer Verschachtelung ausgegeben werden (r3);} \item{Beim \tty{END}-Statement kann jetzt zus"atzlich ein Einsprungpunkt f"ur das Programm angegeben werden (r3).} \item{unterst"utzt zus"atzlich die 68HC16-Familie von Motorola (r3);} \item{P2HEX und P2BIN erlauben es jetzt, den Inhalt einer Code-Datei adre"sm"a"sig zu verschieben (r4);} \item{einem \tty{SHARED}-Befehl anh"angende Kommentare werden jetzt in die Share-Datei mit "ubertragen (r4);} \item{unterst"utzt zus"atzlich die 68HC12-Familie von Motorola (r4);} \item{unterst"utzt zus"atzlich die XA-Familie von Philips (r4);} \item{unterst"utzt zus"atzlich die 68HC08-Familie von Motorola (r4);} \item{unterst"utzt zus"atzlich die AVR-Familie von Atmel (r4);} \item{aus Kompatibilit"at zum AS11 von Motorola existieren zus"atzlich die Befehle \tty{FCB}, \tty{FDB}, \tty{FCC} und \tty{RMB} (r5);} \item{unterst"utzt zus"atzlich den M16C von Mitsubishi (r5);} \item{unterst"utzt zus"atzlich den COP8 von National Semiconductor (r5);} \item{zwei neue Befehle zur bedingten Assemblierung: \tty{IFB} und \tty{IFNB} (r5);} \item{Mit dem \tty{EXITM}-Befehl ist es nun m"oglich, eine Makroexpansion vorzeitig abzubrechen (r5);} \item{unterst"utzt zus"atzlich den MSP430 von Texas Instruments (r5);} \item{\tty{LISTING} kennt zus"atzlich die Varianten \tty{NOSKIPPED} und \tty{PURECODE}, um nicht assemblierten Code aus dem Listing auszublenden (r5);} \item{unterst"utzt zus"atzlich die 78K0-Familie von NEC (r5);} \item{BIGENDIAN ist jetzt auch im PowerPC-Modus verf"ugbar (r5);} \item{zus"atzlich ein \tty{BINCLUDE}-Befehl, um Bin"ardaten einbinden zu k"onnen (r5);} \item{zus"atzliche TOLOWER- und LOWSTRING-Funktionen, um Gro"s- in Kleinbuchstaben umzuwandeln (r5);} \item{es ist jetzt m"oglich, auch in anderen Segmenten als CODE Daten abzulegen. Das Dateiformat wurde entsprechend erweitert (r5);} \item{der \tty{DS}-Befehl, mit dem man Speicherbereiche reservieren kann, ist jetzt auch im Intel-Modus zul"assig (r5);} \item{Mit der Kommandozeilenoption \tty{U} ist es jetzt m"oglich, AS in einen case-sensitiven Modus umzuschalten, in dem Namen von Symbolen, selbstdefinierten Funktionen, Makros, Makroparametern sowie Sektionen nach Gro"s- und Kleinschreibung unterschieden werden (r5);} \item{\tty{SFRB} ber"ucksichtigt jetzt auch die Bildungsregeln f"ur Bitadressen im RAM-Bereich; werden nicht bitadressierbare Speicherstellen angesprochen, erfolgt eine Warnung (r5);} \item{zus"atzliche Pseudobefehle \tty{PUSHV} und \tty{POPV}, um Symbolwerte tempor"ar zu sichern (r5);} \item{zus"atzliche Funktionen \tty{BITCNT, FIRSTBIT, LASTBIT} und \tty{BITPOS} zur Bitverarbeitung (r5);} \item{bei den CPU32-Prozessoren ist jetzt auch der 68360 ber"ucksichtigt (r5);} \item{unterst"utzt zus"atzlich die ST9-Familie von SGS-Thomson (r6);} \item{unterst"utzt zus"atzlich den SC/MP von National Semiconductor (r6);} \item{unterst"utzt zus"atzlich die TMS70Cxx-Familie von Texas Instruments (r6);} \item{unterst"utzt zus"atzlich die TMS9900-Familie von Texas Instruments (r6);} \item{unterst"utzt zus"atzlich die Befehlssatzerweiterungen des 80296 (r6);} \item{die unterst"utzten Z8-Derivate wurden erweitert (r6);} \item{ber"ucksichtigt zus"atzlich die Maskenfehler des 80C504 von Siemens (r6);} \item{zus"atzliche Registerdefinitionsdatei f"ur die C50x-Prozessoren von Siemens (r6);} \item{unterst"utzt zus"atzlich die ST7-Familie von SGS-Thomson (r6);} \item{die Intel-Pseudobefehle zur Datenablage sind jetzt auch f"ur 65816 bzw. MELPS-7700 zul"assig (r6);} \item{f"ur 65816/MELPS-7700 kann die Adre"sl"ange jetzt durch Pr"afixe explizit festgelegt werden (r6);} \item{unterst"utzt zus"atzlich die 8X30x-Familie von Signetics (r6);} \item{\tty{PADDING} ist nur noch f"ur die 680x0-Familie defaultm"a"sig eingeschaltet (r7);} \item{"uber das neu eingef"uhrte, vordefinierte Symbol \tty{ARCHITECTURE} kann ausgelesen werden, f"ur welche Plattform AS "ubersetzt wurde (r7);} \item{Zus"atzliche Anweisungen \tty{STRUCT} und \tty{ENDSTRUCT} zur Definition von Datenstrukturen (r7);} \item{Hex- und Objekt-Dateien f"ur die AVR-Tools k"onnen jetzt direkt erzeugt werden (r7);} \item{\tty{MOVEC} kennt jetzt auch die 68040-Steuerregister (r7);} \item{zus"atzliche \tty{STRLEN}-Funktion, um die L"ange eines Strings zu ermitteln (r7);} \item{M"oglichkeit zur Definition von Registersymbolen (r7, momentan nur Atmel AVR);} \item{kennt zus"atzlich die undokumentierten 6502-Befehle (r7);} \item{P2HEX und P2BIN k"onnen jetzt optional die Eingabedateien automatisch l"oschen (r7);} \item{P2BIN kann der Ergebnisdatei optional zus"atzlich die Startadresse voranstellen (r7);} \item{unterst"utzt zus"atzlich die ColdFire-Familie von Motorola als Variation des 680x0-Kerns (r7);} \item{\tty{BYT/FCB, ADR/FDB} und \tty{FCC} erlauben jetzt auch den von \tty{DC} her bekannten Wiederholungsfaktor (r7);} \item{unterst"utzt zus"atzlich den M*Core von Motorola (r7);} \item{der SH7000-Teil kennt jetzt auch die SH7700-Befehlserweiterungen (r7);} \item{der 680x0-Teil kennt jetzt auch die zus"atzlichen Befehle des 68040 (r7);} \item{der 56K-Teil kennt jetzt auch die Befehlserweiterungen bis zum 56300 (r7).} \item{Mit der neuen \tty{CODEPAGE}-Anweisung können jetzt auch mehrere Zeichentabellen gleichzeitig verwaltet werden (r8);} \item{Die Argumentvarianten f"ur \tty{CHARSET} wurden erweitert (r8);} \item{Neue String-Funktionen \tty{SUBSTR} und \tty{STRSTR} (r8);} \item{zus"atzliches \tty{IRPC}-Statement im Makroprozessor (r8);} \item{zus"atzlicher {\tt RADIX}-Befehl, um das Default-Zahlensystem f"ur Integer-Konstanten festzulegen (r8);} \item{statt {\tt ELSEIF} darf auch einfach {\tt ELSE} geschrieben werden (r8);} \item{statt $=$ darf als Gleichheitsoperator auch $==$ geschrieben werden (r8);} \item{\tty{BRANCHEXT} erlaubt es beim Philips XA jetzt, die Sprungweite von kurzen Spr"ungen automatisch zu erweitern (r8);} \item{Debug-Ausgaben sind jetzt auch im NoICE-Format m"oglich (r8);} \item{unterst"utzt zus"atzlich die i960-Familie von Intel (r8);} \item{unterst"utzt zus"atzlich die $\mu$PD7720/7725-Signalprozssoren von NEC (r8);} \item{unterst"utzt zus"atzlich den $\mu$PD77230-Signalprozssor von NEC (r8);} \item{unterst"utzt zus"atzlich die SYM53C8xx-SCSI-Prozessoren von Symbios Logic (r8);} \item{unterst"utzt zus"atzlich den 4004 von Intel (r8);} \item{unterst"utzt zus"atzlich die SC14xxx-Serie von National (r8);} \item{unterst"utzt zus"atzlich die Befehlserweiterungen des PPC403GC (r8);} \item{zus"atzliche Kommandozeilenoption {\tt cpu}, um den Zielprozessor-Default zu setzen (r8);} \item{Key-Files k"onnen jetzt auch von der Kommandozeile aus referenziert werden (r8);} \item{zus"atzliche Kommandozeilenoption {\tt shareout}, um die Ausgabedatei f"ur SHARED-Definitionen zu setzen (r8);} \item{neuer Pseudobefehl {\tt WRAPMODE}, um AVR-Prozessoren mit verk"urztem Programmz"ahler zu unterst"utzen (r8);} \item{unterst"utzt zus"atzlich die C20x-Befehlsuntermenge im C5x-Teil (r8);} \item{hexadezimale Adre"angaben der Hilfsprogamme k"onnen jetzt auch in C-Notation gemacht werden (r8);} \item{Das Zahlensystem f"ur Integerergebnisse in \verb!\{...}!- Ausdr"ucken ist jetzt per \tty{OUTRADIX} setzbar (r8);} \item{Die Registersyntax f"ur 4004-Registerpaare wurde korrigiert (r8);} \item{unterst"utzt zus"atzlich die F$^{2}$MC8L-Familie von Fujitsu (r8);} \item{f"ur P2HEX kann jetzt die Minimall"ange f"ur S-Record-Adressen angegeben werden (r8);} \item{unterst"utzt zus"atzlich die ACE-Familie von Fairchild (r8);} \item{{\tt REG} ist jetzt auch f"ur PowerPCs erlaubt (r8);} \item{zus"atzlicher Schalter in P2HEX, um alle Adressen zu verschieben (r8);} \item{Mit dem Schalter \tty{x} kann man jetzt zus"atzlich in einer zweiten Stufe bie betroffene Quellzeile ausgeben (r8).} \end{itemize}} \end{itemize} %%=========================================================================== \cleardoublepage \chapter{Hinweise zum Quellcode von AS} \label{ChapSource} Wie in der Einleitung erw"ahnt, gebe ich nach R"ucksprache den Quellcode von AS heraus. Im folgenden sollen einige Hinweise zu dessen Handhabung gegeben werden. %%--------------------------------------------------------------------------- \section{Verwendete Sprache} Urspr"unglich war AS ein in Turbo-Pascal geschriebenes Programm. F"ur diese Entscheidung gab es Ende der 80er Jahre eine Reihe von Gr"unden: Zum einen war ich damit wesentlich vertrauter als mit jedem C-Compiler, zum anderen waren alle C-Compiler unter DOS verglichen mit der IDE von Turbo-Pascal ziemliche Schnecken. Anfang 1997 zeichnete sich jedoch ab, da"s sich das Blatt gewendet hatte: Zum einen hatte Borland beschlossen, die DOS-Entwickler im Stich zu lassen (nochmals ausdr"ucklich keinen sch"onen Dank, Ihr Pappnasen von Borland!), und Version 7.0 etwas namens 'Delphi' nachfolgen lie"sen, was zwar wohl wunderbar f"ur Windows-Programme geeignet ist, die zu 90\% aus Oberfl"ache und zuf"allig auch ein bi"schen Funktion bestehen, f"ur kommandozeilenorientierte Progamme wie AS aber reichlich unbrauchbar ist. Zum anderen hatte sich bereits vor diesem Zeitpunkt mein betriebssystemm"a"siger Schwerpunkt deutlich in Richtung Unix verschoben, und auf ein Borland-Pascal f"ur Linux h"atte ich wohl beliebig lange warten k"onnen (an alle die, die jetzt sagen, Borland w"urde ja an soetwas neuerdings basteln: Leute, das ist {\em Vapourware}, und glaubt den Firmen nichts, solange Ihr nicht wirklich in den Laden gehen und es kaufen k"onnt!). Von daher war also klar, da"s der Weg in Richtung C gehen mu"ste. Nach der Erfahrung, wohin die Verwendung von Inselsystemen f"uhrt, habe ich bei der Umsetzung auf C Wert auf eine m"oglichst gro"se Portabilit"at gelegt; da AS jedoch z.B. Bin"ardateien in einem bestimmten Format erzeugen mu"s und an einigen Stellen betriebssystemspezifische Funktionen nutzt, gibt es einige Stellen, an denen man anpassen mu"s, wenn man AS zum ersten Mal auf einer neuen Plattform "ubersetzt. AS ist auf einen C-Compiler ausgelegt, der dem ANSI-Standard entspricht; C++ ist ausdr"ucklich nicht erforderlich. Wenn Sie nur einen Compiler nach dem veralteten Kernighan\&Ritchie-Standard besitzen, sollten Sie sich nach einem neuen Compiler umsehen; der ANSI-Standard ist seit 1989 verabschiedet und f"ur jede aktuelle Plattform sollte ein ANSI-Compiler verf"ugbar sein, zur Not, indem man mit dem alten Compiler GNU-C baut. Im Quellcode sind zwar einige Schalter vorhanden, um den Code K\&R-n"aher zu machen, aber dies ist ein nicht offiziell unterst"utztes Feature, das ich nur intern f"ur ein ziemlich antikes Unix benutze. Alles weitere zum 'Thema K\&R' steht in der Datei {\tt README.KR}. Der Sourcenbaum ist durch einige in der Pascal-Version nicht vorhandene Features (z.B. dynamisch ladbare Nachrichtendateien, Testsuite, automatische Generierung der Dokumentation aus {\em einem} Quellformat) deutlich komplizierter geworden. Ich werde versuchen, die Sache Schritt f"ur Schritt aufzudr"oseln: %%--------------------------------------------------------------------------- \section{Abfangen von Systemabh"angigkeiten} Wie ich schon andeutete, ist AS (glaube ich jedenfalls...) auf Plattformunabh"angigkeit und leichte Portierbarkeit getrimmt. Dies bedeutet, da"s man die Platt\-form\-un\-ab\-h"an\-gig\-kei\-ten in m"oglichst wenige Dateien zusammenzieht. Auf diese Dateien werde ich im folgenden eingehen, und dieser Abschnitt steht ganz vorne, weil es sicher eines der wichtigsten ist: Die Generierung aller Komponenten von AS erfolgt "uber ein zentrales {\tt Makefile}. Damit dies funktioniert, mu"s man ihm ein passendes {\tt Makefile.def} anbieten, das die plattformabh"angigen Einstellungen wie z.B. Compilerflags vorgibt. Im Unterverzeichnis {\tt Makefile.def-samples} finden sich eine Reihe von Includes, die f"ur g"angige Plattformen funktionieren (aber nicht zwangsweise optimal sein m"ussen...). Wenn die von Ihnen benutzte Plattform nicht dabei ist, k"onnen Sie die Beispieldatei {\tt Makefile.def.tmpl} als Ausgangspunkt verwenden (und das Ergebnis mir zukommen lassen!). Ein weiterer Anlaufpunkt zum Abfangen von Systemabh"angigkeiten ist die Datei {\tt sysdefs.h}. Praktisch alle Compiler definieren eine Reihe von Pr"aprozessorsymbolen vor, die den benutzten Zielprozessor sowie das benutzte Betriebsystem beschreiben. Auf einer Sun Sparc unter Solaris mit den GNU-Compiler sind dies z.B. die Symbole \verb!__sparc! und \verb!__SVR4!. In {\tt sysdefs.h} werden diese Symbole genutzt, um f"ur die restlichen, systemunabh"angigen Dateien eine einheitliche Ungebung bereitzustellen. Insbesondere betrifft dies Integer-Datentypen einer bekannten L"ange, es kann aber auch die Nach- oder Redefinition von C-Funktionen betreffen, die auf einer bestimmten Plattform nicht oder nicht standardgem"a"s vorhanden sind. Was da so an Sachen anf"allt, liest man am besten selber nach. Generell sind die \verb!#ifdef!-Statements in zwei Ebenen gegliedert: Zuerst wird eine bestimmte Prozessorplattform ausgew"ahlt, dann werden in diesem Abschnitt die Betriebssysteme auseinandersortiert. Wenn Sie AS auf eine neue Plattform portieren, m"ussen Sie zwei f"ur diese Plattform typische Symbole finden und {\tt sysdefs.h} passend erweitern (und wieder bin ich an dem Ergebnis interessiert...). %%--------------------------------------------------------------------------- \section{Systemunabh"angige Dateien} ...stellen den g"o"sten Teil aller Module dar. Alle Funktionen im Detail zu beschreiben, w"urde den Rahmen dieser Beschreibung sprengen (wer hier mehr wissen will, steigt am besten selbst in das Studium der Quellen ein, so katastrophal ist mein Programmierstil nun auch wieder nicht...), deshalb hier nur eine kurze Auflistung, welche Module vorhanden sind und was f"ur Funktionen sie beinhalten: \subsection{Von AS genutzte Module} \subsubsection{as.c} Diese Datei ist die Wurzel von AS: Sie enth"alt die {\em main()}-Funktion von AS, die Verarbeitung aller Kommandozeilenoptionen, die "ubergeordnete Steuerung aller Durchl"aufe durch die Quelldateien sowie Teile des Makroprozessors. \subsubsection{asmallg.c} In diesem Modul werden all die Befehle bearbeitet, die f"ur alle Prozessoren definiert sind, z.B. \tty{EQU} und \tty{ORG}. Hier findet sich auch der \tty{CPU}-Befehl, mit dem zwischen den einzelnen Prozessoren hin- und hergeschaltet wird. \subsubsection{asmcode.c} In diesem Modul befindet sich die Verwaltung der Code-Ausgabedatei. Exportiert wird ein Interface, mit dem sich eine Code-Datei "offnen und schlie"sen l"a"st, und das Routinen zum Einschreiben (und Zur"ucknehmen) von Code anbietet. Eine wichtige Aufgabe dieses Moduls ist die Pufferung des Schreibvorgangs, die die Ausgabegeschwindigkeit erh"oht, indem der erzeugte Code in gr"o"seren Bl"ocken geschrieben wird. \subsubsection{asmdebug.c} Optional kann AS Debug-Informationen f"ur andere Tools wie Simulatoren oder Debugger erzeugen, die einen R"uckbezug auf den Quellcode erlauben, in diesem Modul gesammelt und nach Ende der Assemblierung in einem von mehreren Formaten ausgegeben werden k"onnen. \subsubsection{asmdef.c} Dieses Modul enth"alt lediglich Deklarationen von "uberall ben"otigten Konstanten und gemeinsam benutzten Variablen. \subsubsection{asmfnums.c} Intern vergibt AS f"ur jede benutzte Quelldatei eine fortlaufende Nummer, die zur schnellen Referenzierung benutzt wird. Die Vergabe dieser Nummern und die Umwandlung zwischen Nummer und Dateinamen passiert hier. \subsubsection{asmif.c} Hier befinden sich alle Routinen, die die bedingte Assemblierung steuern. Exportiert wird als wichtigste Variable das Flag \tty{IfAsm}, welches anzeigt, ob Codeerzeugung momentan ein- oder ausgeschaltet ist. \subsubsection{asminclist.c} In diesem Modul ist die Listenstruktur definiert, "uber die AS die Verschachtelung von Include-Dateien im Listing ausgeben kann. \subsubsection{asmitree.c} Wenn man in einer Code-Zeile das benutzende Mnemonic ermitteln will, ist das einfache Durchvergleichen mit allen vorhandenen Befehlen (wie es noch in vielen Codegeneratoren aus Einfachheit und Faulheit passiert) nicht unbedingt die effizienteste Variante. In diesem Modul sind zwei verbesserte Strukturen (Bin"arbaum und Hash-Tabelle) definiert, die eine effizientere Suche erm"oglichen und die einfache lineare Suche nach und nach abl"osen sollen...Priorit"at nach Bedarf... \subsubsection{asmmac.c} In diesem Modul finden sich die Routinen zur Speicherung und Abfrage von Makros. Der eigentliche Makroprozessor befindet sich (wie bereits erw"ahnt) in {\tt as.c}. \subsubsection{asmpars.c} Hier geht es ins Eingemachte: In diesem Modul werden die Symboltabellen (global und lokal) in zwei Bin"arb"aumen verwaltet. Au"serdem findet sich hier eine ziemlich gro"se Prozedur \tty{EvalExpression}, welche einen (Formel-)ausdruck analysiert und auswertet. Die Prozedur liefert das Ergebnis (Integer, Gleitkomma oder String) in einem varianten Record zur"uck. Zur Auswertung von Ausdr"ucken bei der Codeerzeugung sollten allerdings eher die Funktionen \tty{EvalIntExpression, EvalFloatExpression} und \tty{EvalStringExpression} verwendet werden. "Anderungen zum Einf"ugen neuer Prozessoren sind hier nicht erforderlich und sollten auch nur mit "au"serster "Uberlegung erfolgen, da man hier sozusagen an ,,die Wurzel'' von AS greift. \subsubsection{asmsub.c} Hier finden sich gesammelt einige h"aufig gebrauchte Unterroutinen, welche in erster Linie die Bereiche Fehlerbehandlung und 'gehobene' Stringverarbeitung abdecken. \subsubsection{bpemu.c} Wie am Anfang erw"ahnt, war AS urspr"unglich ein in Borland-Pascal geschriebenes Programm. Bei einigen intrinsischen Funktionen des Compilers war es einfacher, diese zu emulieren, anstatt alle betroffenen Stelle im Quellcode zu "andern. Na ja... \subsubsection{chunks.c} Dieses Modul definiert einen Datentyp, mit dem eine Liste von Adre"sbereichen verwaltet werden kann. Diese Funktion wird von AS f"ur die Belegungslisten ben"otigt, au"serdem benutzten P2BIN und P2HEX diese Listen, um vor "Uberlappungen zu warnen. \subsubsection{cmdarg.c} Dieses Modul implementiert den Mechanismus der Kommdozeilenparameter. Es ben"otigt eine Spezifikation der erlaubten Parameter, zerlegt die Kommadozeile und ruft die entsprechenden Callbacks auf. Der Mechanismus leistet im einzelnen folgendes: \begin{itemize} \item{Mitbearbeitung von Optionen in einer Environment-Variablen oder entsprechenden Datei;} \item{R"uckgabe einer Menge, welche die noch nicht bearbeiteten Kommandozeilenparameter beschreibt;} \item{Trenunng von positiven und negativen Schaltern;} \item{Eine Hintert"ur, falls die dar"uberliegende Entwicklungsumgebung die Kommandozeile nur in Gro"s- oder Kleinschreibung "ubergibt.} \end{itemize} Dieses Modul wird nicht nur von AS, sondern auch von den Hilfsprogrammen \tty{BIND, P2HEX und P2BIN} verwendet. \subsubsection{codepseudo.c} Hier finden sich Pseudobefehle, die von mehreren Codegeneratoren verwendet werden. Dies ist einmal die Intel-Gruppe mit der \tty{DB..DT}-Gruppe, zum anderen die Pendants f"ur die 8/16-Bitter von Motorola oder Rockwell. Wer in diesem Bereich um einen Prozessor erweitern will, kann mit einem Aufruf den gr"o"sten Teil der Pseudobefehle erschlagen. \subsubsection{codevars.c} Aus Speicherersparnisgr"unden sind hier einige von diversen Codegeneratoren benutzen Variablen gesammelt. \subsubsection{endian.c} Doch noch ein bi"schen Maschinenabh"angigkeit, jedoch ein Teil, um den man sich nicht zu k"ummern braucht: Ob eine Maschine Little- oder Big-Endianess benutzt, wird in diesem Modul beim Programmstart automatisch bestimmt. Weiterhin wird gepr"uft, ob die in {\tt sysdefs.h} gemachten Typfestlegungen f"ur Integervariablen auch wirklich die korrekten L"angen ergeben. \subsubsection{headids.c} Gesammelt sind hier alle von AS unterst"utzten Zielprozessorfamilien, die daf"ur in Code-Dateien verwendeten Kennzahlen (siehe Kapitel \ref{SectCodeFormat}) sowie das von P2HEX defaultm"a"sig zu verwendende Ausgabeformat. Ziel dieser Tabelle ist es, Das Hinzuf"ugen eines neuen Prozessors m"oglichst zu zentralisieren, d.h. es sind im Gegensatz zu fr"uher keine weiteren Modifikationen an den Quellen der Hilfsprogramme mehr erforderlich. \subsubsection{ioerrs.c} Hier ist die Umwandlung von Fehlernummern in Klartextmeldungen abgelegt. Hoffentlich treffe ich nie auf ein System, auf dem die Nummern nicht als Makros definiert sind, dann kann ich n"amlich dieses Modul komplett umschreiben... \subsubsection{nlmessages.c} Die C-Version von AS liest alle Meldungen zur Laufzeit aus Dateien, nachdem die zu benutzende Sprache ermittelt wurde. Das Format der Nachrichtendateien ist kein einfaches, sondern ein spezielles, kompaktes, vorindiziertes Format, das zur "Ubersetzungszeit von einem Programm namens 'rescomp' (dazu kommen wir noch) erzeugt wird. Dieses Modul ist das Gegenst"uck zu rescomp, die den korrekten Sprachenanteil einer Datei in ein Zeichenfeld einliest und Zugriffsfunktionen anbietet. \subsubsection{nls.c} In diesem Modul wird ermittelt, welche nationalen Einstellungen (Datums- und Zeitformat, L"andercode) zur Laufzeit vorliegen. Das ist leider eine hochgradig systemspezifische Sache, und momentan sind nur drei Methoden definiert: Die von MS-DOS, die von OS/2 und die typische Unix-Methode "uber die {\em locale}-Funktionen. F"ur alle anderen Systeme ist leider \verb!NO_NLS! angesagt... \subsubsection{stdhandl.c} Zum einen ist hier eine spezielle open-Funktion gelandet, die die Sonderstrings {\tt !0...!2} als Dateinamen kennt und daf"ur Duplikate der Standard-Dateihandles {\em stdin, stdout} und {\em stderr} erzeugt, zum anderen wird hier festgestellt, ob die Standardausgabe auf ein Ger"at oder eine Datei umgeleitet wurde. Das bedingt auf nicht-Unix-Systemen leider auch einige Speziall"osungen. \subsubsection{stringlists.c} Dies ist nur ein kleiner ,,Hack'', der Routinen zur Verwaltung von linearen Listen mit Strings als Inhalt definiert, welche z.B. im Makroprozessor von AS gebraucht werden. \subsubsection{strutil.c} Hier sind einige h"aufig genutzte String-Operationen gelandet. \subsubsection{version.c} Die momentan g"ultige Version ist f"ur AS und alle anderen Hilfsprogramme hier zentral gespeichert. \subsubsection{code????.c} Dies Module bilden den Hauptteil der AS-Quellen: jedes Modul beinhaltet den Codegenerator f"ur eine bestimmte Prozessorfamilie. \subsection{Zus"atzliche Module f"ur die Hilfsprogramme} \subsubsection{hex.c} Ein kleines Modul zur Umwandlung von Integerzahlen in Hexadezimaldarstellung. In C nicht mehr unbedingt erforderlich (au"ser zur Wandlung von {\em long long}-Variablen, was leider nicht alle {\tt printf()}'s unterst"utzen), aber es ist im Rahmen der Portierung eben auch stehengeblieben. \subsubsection{p2bin.c} Die Quellen von P2BIN. \subsubsection{p2hex.c} Die Quellen von P2HEX. \subsubsection{pbind.c} Die Quellen von BIND. \subsubsection{plist.c} Die Quellen von PLIST. \subsubsection{toolutils.c} Hier sind gesammelt die Unterroutinen, die von allen Hilfsprogrammen ben"otigt werden, z.B. f"ur das Lesen von Code-Dateien. \section{W"ahrend der Erzeugung von AS gebrauchte Module} \subsubsection{a2k.c} Dies ist ein Minimalfilter, das ANSI-C-Files in Kernighan-Ritchie umwandelt. Um es genau zu sagen: es werden nur die Funktionsk"opfe umgewandelt, und auch nur dann, wenn sie ungef"ahr so formatiert sind, wie es mein Schreibstil eben ist. Es komme also keiner auf die Idee, das w"are ein universeller C-Parser! \subsubsection{addcr.c} Ein kleiner Filter, der bei der Installation auf DOS- oder OS/2-Systemen gebraucht wird. Da DOS und OS/2 den Zeilenvorschub mit CR/LF vornehmen, Unix-Systeme jedoch nur mit LF, werden s"amtliche mitgelieferten Assembler-Includes bei der Installation durch diesen Filter geschickt. \subsubsection{bincmp.c} F"ur DOS und OS/2 "ubernimmt dieses Modul die Funktion die Funktion des {\em cmp}-Befehls, d.h. den bin"aren Vergleich von Dateien w"ahrend des Testlaufes. W"ahrend dies prinzipiell auch mit dem mitgelieferten {\em comp} m"oglich w"are, hat {\em bincmp} keine l"astigen interaktiven Abfragen (bei denen man erst einmal herausfinden mu"s, wie man sie auf allen Betriebssystemversionen abstellt...) \subsubsection{findhyphen.c} Dies ist das Untermodul in {\em tex2doc}, da"s f"ur die Silbentrennung von Worten sorgt. Der verwendete Algorithmus is schamlos von TeX abgekupfert. \subsubsection{grhyph.c} Die Definition der Silbentrennungsregeln f"ur die deutsche Sprache. \subsubsection{rescomp.c} Dies ist der 'Resourcencompiler' von AS, d.h. das Werkzeug, das die lesbaren Dateien mit Stringresourcen in ein schnelles, indiziertes Format umsetzt. \subsubsection{tex2doc.c} Ein Werkzeug, da"s die LaTeX-Dokumentation von AS in ein ASCII-Format umsetzt. \subsubsection{tex2html.c} Ein Werkzeug, da"s die LaTeX-Dokumentation von AS in ein HTML-Dokument umsetzt. \subsubsection{umlaut.c und unumlaut.c} Diese Progr"ammchen besorgen die Wandlung zwischen Sonderzeichenkodierung im ISO-Format (alle AS-Dateien verwenden im Auslieferungszustand die ISO8859-1-Kodierung f"ur Sonderzeichen) und Sonderzeichenkodierung im systemspezifischen Format. Neben einer Plain-ASCII7-Variante sind dies im Augenblick die IBM-Zeichens"atze 437 und 850. \subsubsection{ushyph.c} Die Definition der Silbentrennungsregeln f"ur die englische Sprache. %%--------------------------------------------------------------------------- \section{Generierung der Nachrichtendateien} Wie bereits erw"ahnt, verwendet der C-Quellenbaum von AS ein dynamisches Ladeverfahren f"ur alle (Fehler-)Meldungen. Gegen"uber den Pascal-Quellen, in denen alle Meldungen in einem Include-File geb"undelt waren und so in die Programme hinein"ubersetzt wurden, macht es dieses Verfahren "uberfl"ussig, mehrere sprachliche Varianten von AS zur Verf"ugung zu stellen: es gibt nur noch eine Version, die beim Programmstart die zu benutzende Variante ermittelt und aus den Nachrichtendateien die entsprechende Komponente l"adt. Kurz zur Erinnerung: Unter DOS und OS/2 wird dazu die gew"ahlte {\tt COUNTRY}-Einstellung zu Rate gezogen, unter Unix werden die Environment-Variablen {\tt LC\_MESSAGES, LC\_ALL} und {\tt LANG} befragt. \subsection{Format der Quelldateien} Eine Quelldatei f"ur den Message-Compiler {\em rescomp} hat "ublicherweise die Endung {\tt .res}. Der Message-Compiler erzeugt aus dieser Datei ein oder zwei Dateien: \begin{itemize} \item{eine bin"are Datei, die zur Laufzeit von AS bzw. den Hilfsprogrammen gelesen wird;} \item{optional eine weitere C-Header-Datei, die allen vorhandenen Nachrichten eine Indexnummer zuweist. "Uber diese Indexnummern und eine Indextabelle in der bin"aren Datei kann zur Laufzeit schnell auf einzelne Meldungen zugegriffen werden.} \end{itemize} Die Quelldatei f"ur den Message-Compiler ist eine reine ASCII-Datei, also mit jedem beliebigen Editor bearbeitbar, und besteht aus einer Reihe von Steueranweisungen mit Parametern. Leerzeilen sowie Zeilen, die mit einem Semikolon beginnen, werden ignoriert. Das Inkludieren anderer Dateien ist "uber das {\tt Include}-Statement m"oglich: \begin{verbatim} Include \end{verbatim} Am Anfang jeder Quelldatei m"ussen zwei Statements stehen, die die im folgenden definierten Sprachen beschreiben. Das wichtigere der beiden Statements ist {\tt Langs}, z.B.: \begin{verbatim} Langs DE(049) EN(001,061) \end{verbatim} beschreibt, da"s zwei Sprachen im folgenden definiert werden. Der erste Nachrichtensatz soll benutzt werden, wenn unter Unix die Sprache per Environment-Variablen auf {\tt DE} gestellt wurde bzw. unter DOS bzw. OS/2 der Landescode 049 eingestellt wurde. Der zweite Satz kommt dementsprechend bei den Einstellungen {\tt EN} bzw. 061 oder 001 zum Einsatz. W"ahrend bei den 'Telefonnummern' mehrere Codes auf einen Nachrichtensatz verweisen k"onnen, ist die Zuordnung zu den Unix-Landescodes eineindeutig. Dies ist in der Praxis aber kein Beinbruch, weil die {\tt LANG}-Variablen unter Unix Unterversionen einer Sprache als Anh"angsel beschreiben, z.B. so: \begin{verbatim} de.de de.ch en.us \end{verbatim} AS vergleicht nur den Anfang der Strings und kommt so trotzdem zur richtigen Entscheidung. Das {\tt Default}-Statement gibt vor, welcher Sprachensatz verwendet werden soll, wenn entweder "uberhaupt keine Sprache gesetzt wurde oder eine Kennung verwendet wird, die nicht in der Liste von {\tt Langs} vorhanden ist. Typischerweise ist dies Englisch: \begin{verbatim} Default EN \end{verbatim} Nach diesen beiden Definitionen folgt eine beliebige Menge von {\tt Message}-Statements, d.h. Definitionen von Meldungen: \begin{verbatim} Message ErrName ": Fehler " ": error " \end{verbatim} Wurden {\em n} Sprachen im {\tt Langs}-Statement angek"undigt, so nimmt der Message-Compiler {\bf genau} die folgenden {\em n} Zeilen als die zu speichernden Strings. Es ist also nicht m"oglich, bei einzelnen Nachrichten bestimmte Sprachen fortzulassen, und eine auf die Strings folgende Leerzeile ist keinesfalls als Endemarkierung f"ur die Liste mi"szuverstehen; eingef"ugte Leerzeilen dienen einzig und allein der besseren Lesbarkeit. Was allerdings erlaubt ist, ist, einzelne Meldungen "uber mehrere Zeilen in der Quelldatei zu verteilen; alle Zeilen bis auf die letzte m"ussen dann mit einem Backslash als Fortsetzungszeichen enden: \begin{verbatim} Message TestMessage2 "Dies ist eine" \ "zweizeilige Nachricht" "This is a" \ "two-line message" \end{verbatim} Wie bereits erw"ahnt, handelt es sich bei den Quelldateien um reine ASCII-Dateien; Sonderzeichen k"onnen in den Meldungstexten zwar eingetragen werden (und der Compiler wird sie auch so durchreichen), der gravierende Nachteil ist aber, da"s eine solche Datei nicht mehr voll portabel ist: Wird sie auf ein anderes System gebracht, das z.B. eine andere Kodierung f"ur Umlaute verwendet, bekommt der Anwender zur Laufzeit nur merkw"urdige Zeichen zu sehen...Sonderzeichern sollten daher immer mit Hilfe von speziellen Sequenzen geschrieben werden, die von HTML bzw. SGML entlehnt wurden (siehe Tabelle \ref{TabSpecChars}). Zeilenvorsch"ube k"onnen in eine Zeile wie von C her gewohnt mit \verb!\n! eingebracht werden. \begin{table*}[htb] \begin{center}\begin{tabular}{|l|l|} \hline Sequenz... & ergibt... \\ \hline \hline \verb!ä ö ü! & "a "o "u (Umlaute)\\ \verb!Ä Ö Ü! & "A "O "U \\ \verb!ß! & "s (scharfes s) \\ \verb!à è ì ò ù! & \'a \'e \'i \'o \'u (Accent \\ \verb!À È Ì Ò Ù! & \'A \'E \'I \'O \'U grave) \\ \verb!á é í ó ú! & \`a \`e \`i \`o \`u (Accent \\ \verb!Á É Í Ó Ú! & \`A \`E \`I \`O \`I agiu) \\ \verb!â ê î ô û! & \^a \^e \^i \^o \^u (Accent \\ \verb!Â Ê Î Ô Û! & \^A \^E \^I \^O \^U circonflex) \\ \verb!ç Ç! & \c{c} \c{C}(Cedilla) \\ \verb!ñ Ñ! & \~n \~N \\ \verb!å Å! & \aa \AA \\ \verb!æ &Aelig;! & \ae \AE \\ \verb!¿ ¡! & umgedrehtes ! oder ? \\ \hline \end{tabular}\end{center} \caption{Sonderzeichenschreibweise des {\em rescomp}\label{TabSpecChars}} \end{table*} %%--------------------------------------------------------------------------- \section{Dokumentationserzeugung} In einer Quellcodedistribution von AS ist diese Dokumentation nur als LaTeX-Dokument enthalten. Andere Formate werden aus dieser mit Hilfe von mitgelieferten Werkzeugen automatisch erzeugt. Zum einen reduziert dies den Umfang einer Quellcodedistribution, zum anderen m"ussen "Anderungen nicht an allen Formatversionen eines Dokumentes parallel vorgenommen werden, mit all den Gefahren von Inkonsistenzen. Als Quellformat wurde LaTeX verwendet, weil...weil...weil es eben schon immer vorhanden war. Zudem ist TeX fast beliebig portierbar und pa"st damit recht gut zum Anspruch von AS. Eine Standard-Distribution erlaubt damit eine 'ordentliche' Ausgabe auf so ziemlich jedem Drucker; f"ur eine Konvertierung in die fr"uher immer vorhandene ASCII-Version liegt der Konverter {\em tex2doc} bei; zus"atzlich einen Konverter {\em tex2html}, so da"s man die Anleitung direkt ins Internet stellen kann. Die Erzeugung der Dokumentation wird mit einem schlichten \begin{verbatim} make docs \end{verbatim} angesto"sen; daraufhin werden die beiden erw"ahnten Hilfstools erzeugt, auf die TeX-Dokumentation angewandt und schlu"sendlich wird noch LaTeX selber aufgerufen. Dies nat"urlich f"ur alle Sprachen nacheinander... %%--------------------------------------------------------------------------- \section{Testsuite} Da AS mit bin"aren Daten von genau vorgegebener Struktur umgeht, ist er naturgem"a"s etwas empfindlich f"ur System- und Compilerabh"angigkeiten. Um wenigstens eine gewisse Sicherheit zu geben, da"s alles korrekt durchgelaufen ist, liegt dem Assembler im Unterverzeichnis {\tt tests} eine Menge von Test-Assemblerquellen bei, mit denen man den frisch gebauten Assembler testen kann. Diese Testprogramme sind in erster Linie darauf getrimmt, Fehler in der Umsetzung des Maschinenbefehlssatzes zu finden, die besonders gern bei variierenden Wortl"angen auftreten. Maschinenunabh"angige Features wie der Makroprozessor oder bedingte Assemblierung werden eher beil"aufig getestet, weil ich davon ausgehe, da"s sie "uberall funktionieren, wenn sie bei mir funktionieren... Der Testlauf wird mit einem einfachen {\em make test} angesto"sen. Jedes Testprogramm wird assembliert, in eine Bin"ardatei gewandelt und mit einem Referenz-Image verglichen. Ein Test gilt als bestanden, wenn Referenz und die neu erzeugte Datei Bit f"ur Bit identisch sind. Am Ende wird summarisch die Assemblierungszeit f"ur jeden Test ausgegeben (wer will, kann mit diesen Ergebnissen die Datei {\tt BENCHES} erg"anzen), zusammen mit dem Erfolg oder Mi"serfolg. Jedem Fehler ist auf den Grund zu gehen, selbst wenn er bei einem Zielprozessor auftritt, den Sie nie nutzen werden! Es ist immer m"oglich, da"s dies auf einen Fehler hinweist, der auch bei anderen Zielprozessoren auftritt, nur zuf"allig nicht in den Testf"allen. %%--------------------------------------------------------------------------- \section{Einh"angen eines neuen Zielprozessors} Der mit Abstand h"aufigste Grund, im Quellcode von AS etwas zu ver"andern, d"urfte wohl die Erweiterung um einen neuen Zielprozessor sein. Neben der Erg"anzung der Makefiles um das neue Modul ist lediglich eine Modifikation der Quellen an wenigen Stellen erforderlich, den Rest erledigt das neue Modul, indem es sich in der Liste der Codegeneratoren registriert. Im folgenden will ich kochbuchartig die zum Einh"angen erforderlichen Schritte beschreiben: \subsubsection{Festlegung des Prozessornamens} Der f"ur den Prozessor zu w"ahlende Name mu"s zwei Kriterien erf"ullen: \begin{enumerate} \item{Der Name darf noch nicht von einem anderen Prozessor belegt sein. Beim Aufruf von AS ohne Parameter erh"alt man eine Liste der bereits vorhandenen Namen.} \item{Soll der Prozessorname vollst"andig in der Variablen \tty{MOMCPU} auftauchen, so darf er au"ser am Anfang keine Buchstaben au"serhalb des Bereiches von A..F enthalten. In der Variablen \tty{MOMCPUNAME} liegt aber zur Assemblierzeit immer der volle Name vor. Sonderzeichen sind generell nicht erlaubt, Kleinbuchstaben werden vom CPU-Befehl bei der Eingabe in Gro"sbuchtaben umgewandelt und sind daher auch nicht im Prozessornamen sinnvoll.} \end{enumerate} Der erste Schritt der Registrierung ist die Eintragung des Prozessors oder der Prozessorfamilie in der Datei {\tt headids.c}. Wie bereits erw"ahnt, wird diese Datei von den Hilfsprogrammen mitbenutzt und spezifiziert die einer Prozessorfamilie zugeordnete Kenn-ID in Codedateien sowie das zu verwendende Hex-Format. Bei der Wahl der Kenn-ID w"urde ich mir etwas Absprache w"unschen... \subsubsection{Definition des Codegeneratormoduls} Das Modul, das f"ur den neuen Prozessor zust"andig sein soll, sollte einer gewissen Einheitlichkeit wegen den Namen \tty{code....} tragen, wobei \tty{.....} etwas mit dem Prozessornamen zu tun haben sollte. Den Kopf mit den Includes "ubernimmt man am besten direkt aus einem bereits vorhandenen Codegenerator. Mit Ausnahme einer Initialisierungsfunktion, die zu Anfang der {\tt main()}-Funktion im Modul {\tt as.c} aufgerufen werden mu"s, braucht das neue Modul keinerlei Funktionen oder Variablen zu exportieren, da die ganze Kommunikation zur Laufzeit "uber indirekte Spr"unge abgewickelt wird. Die dazu erforderlichen Registrierungen m"ussen in der Initialisierungsfunktion des Moduls vorgenommen werden, indem f"ur jeden von der Unit zu behandelnden Prozessortyp ein Aufruf der Funktion \tty{AddCPU} erfolgt: \begin{verbatim} CPUxxxx = AddCPU("XXXX", SwitchTo_xxxx); \end{verbatim} \tty{'XXXX'} ist dabei der f"ur den Prozessor festgelegte Name, der sp"ater im Assemblerprogramm verwendet werden mu"s, um AS auf diesen Zielprozessor umzuschalten. \tty{SwitchTo\_xxxx} (im folgenden kurz als ,,Umschalter'' bezeichnet) ist eine parameterlose Prozedur, die von AS aufgerufen wird, sobald auf diesen Prozessor umgeschaltet werden soll. Als Ergebnis liefert \tty{AddCPU} eine Zahlenwert, der als interne ,,Kennung'' f"ur diesen Prozessor fungiert. In der globalen Variablen \tty{MomCPU} wird st"andig die Kennung des momentan gesetzten Zielprozessors mitgef"uhrt. Der von \tty{AddCPU} gelieferte Wert sollte in einer privaten Variable des Typs \tty{CPUVar} (hier \tty{CPUxxxx} genannt) abgelegt werden. Falls ein Codegeneratormodul verschiedene Prozessoren (z.B. einer Familie) verwaltet, kann es so durch Vergleich von \tty{MomCPU} gegen diese Werte feststellen, welche Befehlsuntermenge momentan zugelassen ist. \par Dem Umschalter obliegt es, AS auf den neuen Zielprozessor ,,umzupolen''. Dazu m"ussen im Umschalter einige globale Variablen besetzt werden: \begin{itemize} \item{\tty{ValidSegs} : Nicht alle Prozessoren definieren alle von AS unterst"utzten Adre"sr"aume. Mit dieser Menge legt man fest, welche Untermenge f"ur den jeweiligen Prozessor von \tty{SEGMENT}-Befehl zugelassen wird. Im mindesten mu"s das Code-Segment freigeschaltet werden. Die Gesamtmenge aller vorhandenen Segmenttypen kann in der Datei \tty{fileformat.h} nachgelesen werden (\tty{Seg}.....-Konstanten).} \item{\tty{SegInits} : Dieses Feld speichert die initialen (ohne \tty{ORG}-Befehl) Startadressen in den einzelnen Segmenten. Nur in Ausnahmef"allen (physikalisch "uberlappende, aber logisch getrennte Adre"sr"aume) sind hier andere Werte als 0 sinnvoll.} \item{\tty{Grans} : Hiermit kann f"ur jedes Segment die Gr"o"se des kleinsten adressierbaren Elements in Bytes festgelegt werden, d.h. die Gr"o"se des Elements, f"ur das eine Adresse um eins erh"oht wird. Bei den allermeisten Prozessoren (auch 16 oder 32 Bit) ist dies ein Byte, nur z.B. Signalprozessoren und die PICs fallen aus dem Rahmen.} \item{\tty{ListGrans} : Hiermit kann wieder f"ur alle Segmente getrennt festgelegt werden, in was f"ur Gruppen die Bytes im Assemblerlisting dargestellt werden sollen. Beim 68000 sind z.B. Befehle immer ein mehrfaches von 2 Bytes lang, weshalb die entsprechende Variable auf 2 gesetzt ist.} \item{\tty{SegLimits} : Dieses Feld legt die h"ochste Adresse f"ur jedes Segment fest, z.B. 65535 f"ur einen 16-Bit-Adre"sraum. Dieses Feld braucht nicht ausgef"ullt zu werden, wenn der Codegenerator die {\tt ChkPC}-Methode selber "ubernimmt.} \item{\tty{ConstMode} : Diese Variable kann die Werte \tty{ConstModeIntel}, \tty{ConstModeMoto} oder \tty{ConstModeC} haben und bestimmt, in welcher Form Zahlensysteme bei Integerkonstanten spezifiziert werden sollen (sofern das Programm nicht vom Relaxed-Modus Gebrauch macht).} \item{\tty{PCSymbol} : Diese Variable enth"alt den String, mit dem aus dem Assembler-Programm heraus der momentane Stand des Programmz"ahlers abgefragt werden kann. F"ur Intel-Prozessoren ist dies z.B. ein Dollarzeichen.} \item{\tty{TurnWords} : Falls der Prozessor ein Big-Endian-Prozessor sein sollte und eines der Elemente von \tty{ListGrans} ungleich eins ist, sollte dieses Flag auf True gesetzt werden, um korrekte Code-Dateien zu erhalten.} \item{\tty{SetIsOccupied} : Einige Prozessoren verwenden \tty{SET} als Maschinenbefehl. Ist diese Variable gesetzt, so gibt AS \tty{SET} -Befehle an den Codegenerator weiter und verwendet stattdessen \tty{EVAL}.} \item{\tty{HeaderID} : Dieses Byte enth"alt die Kennung, mit der in der Codedatei die Prozessorfamilie gekennzeichnet wird (siehe Abschnitt \ref{SectCodeFormat}). Um Zweideutigkeiten zu vermeiden, bitte ich, den Wert mit mir abzusprechen. Bis auf weiteres sollten keine Werte au"serhalb des Bereiches \$01..\$7f benutzt werden, diese sind f"ur Sonderzwecke (wie z.B. eine zuk"unftige Erweiterung um einen Linker) reserviert. Auch wenn dieser Wert in den meisten "alteren Codegeneratoren hart gesetzt wird, ist es die heute bevorzugte Methode, den Wert aus {\tt headids.h} per {\tt FindFamilyByName} zu holen.} \item{\tty{NOPCode} : In bestimmten Situationen kann es sein, da"s AS unbenutzte Bereiche im Code mit NOPs auff"ullen mu"s. Diese Variable beinhaltet den dazu erforderlichen Code.} \item{\tty{DivideChars} : Dieser String enth"alt all jene Zeichen, die als Trennzeichen f"ur die Parameter eines Assemblerbefehls zugelassen sind. Nur f"ur extreme Ausrei"ser (wie den DSP56) sollte sich in diesem String etwas anderes finden als ein Komma.} \item{\tty{HasAttrs} : Einige Prozessoren wie die 68k-Reihe teilen einen Maschinenbefehl durch einen Punkt noch weiter in Mnemonic und Attribut auf. Ist dies beim neuen Prozessor auch der Fall, so ist dieses Flag auf True zu setzen. AS liefert dann die Einzelteile in den Variablen \tty{OpPart} und \tty{AttrPart}. Setzt man es dagegen auf False, so bleibt der Befehl in \tty{OpPart} zusammen, und \tty{AttrPart} ist immer leer. Sofern der Prozessor keine Attribute verwendet, sollte man \tty{HasAttrs} auf jeden Fall auf False setzen, da man sich sonst die M"oglichkeit nimmt, Makros mit einem Punkt im Namen (z.B. zur Emulation anderer Assembler) zu definieren.} \item{\tty{AttrChars} : Falls \tty{HasAttrs} gesetzt wurde, m"ussen in diesem String alle Zeichen eingetragen werden, die das Attribut vom Befehl trennen k"onnen. Meist ist dies nur der Punkt.} \end{itemize} Gehen Sie nicht davon aus, da"s eine dieser Variablen einen vordefinierten Wert hat, sondern besetzen Sie \bb{ALLE} Felder neu!! Neben diesen Variablen m"ussen noch einige Funktionszeiger besetzt wird, mit denen der Codegenerator sich in AS einbindet: \begin{itemize} \item{\tty{MakeCode} : Diese Routine wird nach der Zerlegung einer Zeile in Mnemonic und Parameter aufgerufen. Das Mnemonic liegt in der Variablen \tty{OpPart}, die Parameter in dem Feld \tty{ArgStr}. Die Zahl der Parameter kann aus der Variablen \tty{ArgCnt} ausgelesen werden. Das bin"are Ergebnis mu"s in dem Byte-Feld \tty{BAsmCode} abgelegt werden, dessen L"ange in der Variablen \tty{CodeLen}. Falls der Prozessor wortorientiert wie der 68000 oder viele Signalprozessoren ist, kann Feld auch wortweise als \tty{WAsmCode} adressiert werden. F"ur ganz extreme F"alle gibt es auch noch \tty{DAsmCode}... Die Codel"ange wird ebenfalls in solchen Einheiten angegeben.} \item{\tty{SwitchFrom}: Diese parameterlose Prozedur erlaubt dem Codegeneratormodul, noch ,,Aufr"aumarbeiten'' durchzuf"uhren, wenn auf einen anderen Zielprozessor umgeschaltet wird. So kann man an dieser Stelle z.B. Speicher freigeben, der im Umschalter belegt wurde und nur ben"otigt wird, w"ahrend dieses Codegeneratormodul aktiv ist. Im einfachsten Fall zeigt diese Prozedurvariable auf eine leere Prozedur. Ein Beispiel f"ur die Anwendung dieser Prozedur finden Sie im Modul \tty{CODE370}, das seine Codetabellen dynamisch erzeugt und wieder freigibt.} \item{\tty{IsDef} : Bestimmte Prozessoren kennen neben \tty{EQU} noch weitere Pseudobefehle, bei denen ein in der ersten Spalte stehender Symbolname kein Label darstellt, z.B. \tty{BIT} beim 8051. Diese Funktion mu"s TRUE zur"uckliefern, falls ein solcher, zus"atzlicher Befehl vorliegt. Im einfachsten Fall braucht nur FALSE zur"uckgeliefert zu werden.} \end{itemize} Optional kann ein Codegenerator auch noch folgende weitere Funktionszeiger besetzen: \begin{itemize} \item{\tty{ChkPC} : Obwohl AS die Programmz"ahler intern durchg"angig mit 32 oder 64 Bit verwaltet, benutzen die meisten Prozessoren nur einen kleineren Adre"sraum. Diese Funktion liefert AS Informationen, ob der momentane Programmz"ahler den erlaubten Bereich "uberschritten hat. Bei Prozessoren mit mehreren Adre"sr"aumen kann diese Routine nat"urlich deutlich komplizierter ausfallen. Ein Beispiel daf"ur findet sich z.B. im Modul \tty{code16c8x.c}. Falls alles in Ordnung ist, mu"s die Funktion TRUE zur"uckliefern, ansonsten FALSE. Diese Funktion mu"s ein Codegenerator nur implementieren, wenn er das Feld {\tt SegLimits} nicht belegt. Das kann z.B. notwendig werden, wenn der g"ultige Adre"sbereich eines Segments nicht zusammenh"angend ist.} \item{\tty{InternSymbol} : Manche Prozessoren, z.B. solche mit einer Registerbank im internen RAM, defineren diese 'Register' als Symbole vor, und es w"urde wenig Sinn machen, diese in einer separaten Include-Datei mit 256 oder m"oglicherweise noch mehr {\tt EQU}s zu definieren. Mit dieser Funktion erh"alt man Zugang zum Formel- Parser von AS: Sie erh"alt den Ausdruck als ASCII-String, und wenn sie eines der 'eingebauten Symbole' erkennt, besetzt sie die "ubergebene Struktur des Typs {\em TempResult} entsprechend. Falls die "Uberpr"ufung nicht erfolgreich war, mu"s deren Element {\tt Typ} auf {\tt TempNone} gesetzt werden. Die Routine sollte im Falle eines Mi"serfolges {\em keine} Fehlermeldungen ausgeben, weil dies immer noch anderweitig g"ultige Symbole sein k"onnen. Seien Sie extrem vorsichtig mit dieser Routine, da sie einen Eingriff in den Parser darstellt!} \end{itemize} Wer will, kann sich "ubrigens auch mit einem Copyright-Eintrag verewigen, indem er in der Initialisierung des Moduls (bei den \tty{AddCPU}-Befehlen) einen Aufruf der Prozedur \tty{AddCopyright} einf"ugt, in der folgenden Art: \begin{verbatim} AddCopyright("Intel 80986-Codegenerator (C) 2010 Hubert Simpel"); \end{verbatim} Der "ubergebene String wird dann nach dem Programmstart zus"atzlich zu der Standardmeldung ausgegeben. Bei Bedarf kann sich das Modul im Initialisierungsteil noch in die Kette aller Funktionen eintragen, die vor Beginn eines Durchlaufes durch den Quelltext ausgef"uhrt werden. Dies ist z.B. immer dann der Fall, wenn die Code-Erzeugung im Modul abh"angig vom Stand bestimmter, durch Pseudobefehle beeinflu"sbarer Flags ist. Ein h"aufig auftretender Fall ist z.B., da"s ein Prozessor im User- oder Supervisor-Modus arbeiten kann, wobei im User-Modus bestimmte Befehle gesperrt sind. Im Assembler-Quelltext k"onnte dieses Flag, das angibt, in welchem Modus der folgende Code ausgef"uhrt wird, durch einen Pseudobefehl umgeschaltet werden. Es ist aber dann immer noch eine Initialisierung erforderlich, die sicherstellt, da"s in allen Durchl"aufen ein identischer Ausgangszustand vorliegt. Der "uber den Funktionszeiger \tty{InitPassProc} angebotene Haken bietet die M"oglichkeit, derartige Initialisierungen vorzunehmen. Das verwendete Prinzip "ahnelt dabei dem Einh"angen in einen Interruptvektor: In der Initialisierung der Unit wird der alte Wert von \tty{InitPassProc} gesichert. Danach kann \tty{InitPassProc} auf die hinzuzuf"ugende Funktion (parameterlos, kein R"uckgabewert) umgebogen werden. Die neue Routine ruft dann zuerst die alte Initialisierungsroutine auf und f"uhrt danach ihre eigenen Operationen durch. Analog zu \tty{InitPassProc} funktioniert die "uber \tty{CleanUpProc} aufgebaute Funktionskette, die es den Codegeneratoren erlaubt, nach dem Abschlu"s der Assemblierung noch Aufr"aumarbeiten (z.B. das Freigeben von Literaltabellen o."a.) durchzuf"uhren. Dies ist sinnvoll, wenn mehrere Dateien mit einem Aufruf assembliert werden, sonst h"atte man noch ,,M"ull'' aus einem vorigen Lauf in den Tabellen. Momentan nutzt kein Modul diese M"oglichkeit. \subsubsection{Schreiben des Codegenerators selber} Nach diesen Pr"aliminarien ist nun endlich eigene Kreativit"at gefragt: Wie Sie es schaffen, aus dem Mnemonic und den Argumenten die Code-Bytes zu erzeugen, ist weitgehend Ihnen "uberlassen. Zur Verf"ugung stehen daf"ur nat"urlich "uber den Formelparser die Symboltabellen sowie die Routinen aus \tty{asmsub.c} und \tty{asmpars.c}. Ich kann hier nur einige generelle Hinweise geben: \begin{itemize} \item{Versuchen Sie, die Prozessorbefehle in Gruppen aufzusplitten, die gleiche Operanden erwarten und sich nur in einigen Kennbits unterscheiden. Alle argumentlosen Befehle kann man z.B. so in einer Tabelle abhandeln.} \item{Die meisten Prozessoren haben ein festes Repertoire von Adressierungsarten. Verlagern Sie das Parsing eines Adre"sausdrucks in eine getrennte Unterroutine.} \item{Die Routine \tty{WrError} definiert eine Vielzahl von m"oglichen Fehlermeldungen und ist bei Bedarf leicht erweiterbar. Nutzen Sie das! Bei allen Fehler nur lapidar einen ,,Syntaxfehler'' zu melden, n"utzt niemandem!} \end{itemize} Mit Sicherheit wird auch das Studium der vorhandenen Module weiterhelfen. \subsubsection{"Anderungen f"ur die Dienstprogramme} Eine winzige "Anderung ist auch noch an den Quellen der Dienstprogramme n"otig, und zwar in der Routine {\tt Granularity()} in {\tt toolutils.c}: Falls eines der Adre"sr"aume dieses Prozessors eine andere Granularit"at als 1 hat, mu"s dort die Abfrage passend erg"anzt werden, sonst verz"ahlen sich PLIST, P2BIN und P2HEX... %%--------------------------------------------------------------------------- \section{Lokalisierung auf eine neue Sprache} Sie haben Interesse an diesem Thema? Wunderbar! Das ist eine Sache, die von Programmierern gerne au"sen vor gelassen wird, insbesondere, wenn sie aus dem Land der unbegrenzten M"oglichkeiten kommen... Die Lokalisierung auf eine neue Sprache gliedert sich in zwei Teile: Die Anpassung der Programmmeldungen sowie die "Ubersetzung der Anleitung. Letzteres ist sicherlich eine Aufgabe herkulischen Ausma"ses, aber die Anpassung der Programmeldungen solle in ein bis zwei Nachmittagen "uber die B"uhne zu bekommen sein, wenn man sowohl die neue als auch eine der bisher vorhandenen Sprachen gut kennt. Leider ist die "Ubersetzung auch nichts, was man St"uck f"ur St"uck machen kann, denn der Ressourcencompiler kann im Moment nicht mit einer variablen Zahl von Sprachen in den verschiedenen Meldungen umgehen, es hei"st also 'alles oder nichts'. Als erstes erg"anzt man in {\tt header.res} die neue Sprache. Die f"ur die Sprache passende zweibuchstabige Abk"urzung holt man sich vom n"achsten Unix-System (wenn man nicht ohnehin darauf arbeitet...), die internationale Vorwahl aus dem n"achsten DOS-Handbuch. Im zweiten Schritt geht man jetzt durch alle anderen {\tt .res}-Dateien und erg"anzt die {\tt Message}-Statements. Nocheinmal sei darauf hingewiesen, Sonderzeichen in der HTML-artigen Schreibweise und nicht direkt einzusetzen! Wenn dies geschafft ist, kann man mit einem {\em make} alle betroffenen Teile neu bauen und erh"alt danach einen Assembler, der eine Sprache mehr schickt. Bitte nicht vergessen, die Ergebnisse an mich weiterzuleiten, damit mit der n"achsten Release alle etwas davon haben :-) %%=========================================================================== \cleardoublepage \begin{thebibliography}{99} \bibitem{Williams} Steve Williams: \\ {\em 68030 Assembly Language Reference. \/} \\ Addison-Wesley, Reading, Massachusetts, 1989 \bibitem{AMD29K} Advanced Micro Devices: \\ {\em AM29240, AM29245, and AM29243 RISC Microcontrollers. \/} \\ 1993 \bibitem{AtAVR} Atmel Corp.: \\ {\em AVR Enhanced RISC Microcontroller Data Book.\/} \\ May 1996 \bibitem{AVRObj} Atmel Corp.: \\ {\em 8-Bit AVR Assembler and Simulator Object File Formats (Preliminary).\/} \\ (Teil der AVR-Tools-Dokumentation) \bibitem{CMD816} CMD Microcircuits: \\ {\em G65SC802 / G65SC816 CMOS 8/16-Bit Microprocessor Family Data Sheet.\/} \bibitem{CPM68K} Digital Research : \\ {\em CP/M 68K Operating System User's Guide.\/} \\ 1983 \bibitem{Cyrix} Cyrix Corp. : \\ {\em FasMath 83D87 User's Manual.\/} \\ 1990 \bibitem{Dallas320} Dallas Semiconductor: \\ {\em DS80C320 High-Speed Micro User's Guide.\/} \\ Version 1.30, 1/94 \bibitem{Fair1101} Fairchild Semiconductor: \\ {\em ACE1101 Data Sheet.\/} \\ Preliminary, May 1999 \bibitem{Fair1202} Fairchild Semiconductor: \\ {\em ACE1202 Data Sheet.\/} \\ Preliminary, May 1999 \bibitem{Fair8004} Fairchild Semiconductor: \\ {\em ACEx Guide to Developer Tools.\/} AN-8004, Version 1.3 September 1998 \bibitem{FujitsuCD} Fujitsu Limited: \\ {\em June 1998 Semiconductor Data Book.\/} \\ CD00-00981-1E \bibitem{Hit180} Hitachi Ltd. : \\ {\em 8-/16-Bit Microprocessor Data Book.\/} \\ 1986 \bibitem{Hit63} Trevor J.Terrel \& Robert J. Simpson : \\ {\em Understanding HD6301X/03X CMOS Microprocessor Systems. \/} \\ erschienen bei Hitachi \bibitem{HitH8_3} Hitachi Microcomputer: \\ {\em H8/300H Series Programming Manual.\/} \\ (21-032, keine Jahresangabe) \bibitem{SH7000} Hitachi Semiconductor Design \& Development Center: \\ {\em SH Microcomputer Hardware Manual (Preliminary).\/} \bibitem{SH7700} Hitachi Semiconductor and IC Div.: \\ {\em SH7700 Series Programming Manual.\/} \\ 1st Edition, September 1995 \bibitem{HitH8_5} Hitachi Semiconductor and IC Div.: \\ {\em H8/500 Series Programming Manual.} \\ (21-20, 1st Edition Feb. 1989) \bibitem{HitH8_532} Hitachi Ltd.: \\ {\em H8/532 Hardware Manual.} \\ (21-30, keine Jahresangabe) \bibitem{HitH8_534} Hitachi Ltd.: \\ {\em H8/534, H8/536 Hardware Manual.} \\ (21-19A, keine Jahresangabe) \bibitem{PPC403} IBM Corp.: \\ {\em PPC403GA Embedded Controller User's Manual.\/} \\ First Edition, September 1994 \bibitem{IntEmb} Intel Corp. : {\em Embedded Controller Handbook.\/} \\ 1987 \bibitem{IntMic} Intel Corp. : \\ {\em Microprocessor and Peripheral Handbook.\/} \\ Volume I Microprocessor, 1988 \bibitem{Int960} Intel Corp. : \\ {\em 80960SA/SB Reference Manual.\/} \\ 1991 \bibitem{Int196} Intel Corp.: \\ {\em 8XC196NT Microcontroller User's Manual.\/} \\ June 1995 \bibitem{Int251} Intel Corp.: \\ {\em 8XC251SB High Performance CHMOS Single-Chip Microcontroller.\/} \\ Sept. 1995, Order Number 272616-003 \bibitem{Int296} Intel Corp.: \\ {\em 80296SA Microcontroller User's Manual.\/} \\ Sept. 1996 \bibitem{Kaku} Hirotsugu Kakugawa: \\ {\em A memo on the secret features of 6309.} \\ (erh"altlich "uber WWW: \\ http://www.cs.umd.edu/users/fms/comp/CPUs/6309.txt) \bibitem{MicroChip} Microchip Technology Inc.: \\ {\em Microchip Data Book.\/} \\ 1993 Edition \bibitem{Mit41} Mitsubishi Electric: \\ {\em Single-Chip 8-Bit Microcomputers\/} \\ Vol.2, 1987 \bibitem{Mit16} Mitsubishi Electric: \\ {\em Single-Chip 16-Bit Microcomputers.\/} \\ Enlarged edition, 1991 \bibitem{Mit8} Mitsubishi Electric: \\ {\em Single-Chip 8 Bit Microcomputers.\/} \\ Vol.2, 1992 \bibitem{Mit4500} Mitsubishi Electric: \\ {\em M34550Mx-XXXFP Users's Manual.\/} \\ Jan. 1994 \bibitem{MitM16} Mitsubishi Electric: \\ {\em M16 Family Software Manual.\/} \\ First Edition, Sept. 1994 \bibitem{MitM16C} Mitsubishi Electric: \\ {\em M16C Software Manual.\/} \\ First Edition, Rev. C, 1996 \bibitem{Mit30600} Mitsubishi Electric: \\ {\em M30600-XXXFP Data Sheet.\/} \\ First Edition, April 1996 \bibitem{GreenM16} Dokumentation zum M16/M32-Entwicklungspaket von Green Hills Software \bibitem{MotMic} Motorola Inc. : \\ {\em Microprocessor, Microcontroller and Peripheral Data. \/} \\ Vol. I+II, 1988 \bibitem{Mot81} Motorola Inc. : \\ {\em MC68881/882 Floating Point Coprocessor User's Manual. \/} \\ Prentice-Hall, Englewood Cliffs, Second Edition 1989 \bibitem{Mot51} Motorola Inc. : \\ {\em MC68851 Paged Memory Management Unit User's Manual. \/} \\ Prentice-Hall, Englewood Cliffs, Second Edition 1989 \bibitem{Mot32} Motorola Inc.: \\ {\em CPU32 Reference Manual.\/} \\ Rev. 1, 1990 \bibitem{Mot56} Motorola Inc.: \\ {\em DSP56000/DSP56001 Digital Signal Processor User's Manual.\/} \\ Rev. 2, 1990 \bibitem{Mot340} Motorola Inc.: \\ {\em MC68340 Technical Summary.\/} \\ Rev. 2, 1991 \bibitem{Mot16} Motorola Inc.: \\ {\em CPU16 Reference Manual.\/} \\ Rev. 1, 1991 \bibitem{Mot68K} Motorola Inc.: \\ {\em Motorola M68000 Family Programmer's Reference Manual.\/} \\ 1992 \bibitem{Mot332} Motorola Inc.: \\ {\em MC68332 Technical Summary.\/} \\ Rev. 2, 1993 \bibitem{Mot601} Motorola Inc.: \\ {\em PowerPC 601 RISC Microprocessor User's Manual.\/} \\ 1993 \bibitem{Mot505} Motorola Inc.: \\ {\em PowerPC(tm) MPC505 RISC Microcontroller Technical Summary.\/} \\ 1994 \bibitem{Mot12} Motorola Inc.: \\ {\em CPU12 Reference Manual.\/} \\ 1st. edition, 1996 \bibitem{Mot08} Motorola Inc.: \\ {\em CPU08 Reference Manual.\/} \\ Rev. 1 (keine Jahresangabe im PDF-File) \bibitem{Mot360} Motorola Inc.: \\ {\em MC68360 User's Manual.\/} \bibitem{MotCold} Motorola Inc.: \\ {\em MCF 5200 ColdFire Family Programmer's Reference Manual.\/} \\ 1995 \bibitem{MotMCore} Motorola Inc.: \\ {\em M*Core Programmer's Reference Manual.\/} \\ 1997 \bibitem{Mot56300} Motorola Inc.: \\ {\em DSP56300 24-Bit Digital Signal Processor Family Manual.\/} \\ Rev. 0 (keine Jahresangabe im PDF-File) \bibitem{SCMP} National Semiconductor: \\ {\em SC/MP Programmier- und Assembler-Handbuch.\/} \\ Publication Number 4200094A, Aug. 1976 \bibitem{AsmCop} National Semiconductor: \\ {\em COP800 Assembler/Linker/Librarian User's Manual.\/} \\ Customer Order Number COP8-ASMLNK-MAN, NSC Publication Number 424421632-001B, August 1993 \bibitem{Cop87L84} National Semiconductor: \\ {\em COP87L84BC microCMOS One-Time-Programmable (OTP) Microcontroller.} \\ Preliminary, March 1996 \bibitem{Nat14xxx} National Semiconductor: \\ {\em SC14xxx DIP commands Reference guide.} \\ Application Note AN-D-031, Version 0.4, 28.12.1998 \bibitem{NECV} NEC Corp.: \\ {\em $\mu$pD70108 / $\mu$pD70116 / $\mu$pD70208 / $\mu$pD70216 / $\mu$pD72091 Data Book.\/} \\ (keine Jahresangabe) \bibitem{NEC78} NEC Electronics Europe GmbH: \\ {\em User's Manual $\mu$COM-87 AD Family.\/} \\ (keine Jahresangabe) \bibitem{NEC75} NEC Corp.: \\ {\em $\mu$COM-75x Family 4-bit CMOS Microcomputer User's Manual.\/} \\ Vol. I+II (keine Jahresangabe) \bibitem{NECSig} NEC Corp.: \\ {\em Digital Signal Processor Product Description.\/} \\ PDDSP.....067V20 (keine Jahresangabe) \bibitem{NEC78K0} NEC Corp.: \\ {\em $\mu$PD78070A, 78070AY 8-Bit Single-Chip Microcontroller User's Manual.\/} \\ Document No. U10200EJ1V0UM00 (1st edition), August 1995 \bibitem{NEC7814} NEC Corp.: \\ {\em Data Sheet $\mu$PD78014.\/} \bibitem{PhilXA} Philips Semiconductor: \\ {\em 16-bit 80C51XA Microcontrollers (eXtended Architecture).\/} \\ Data Handbook IC25, 1996 \bibitem{SGS04} SGS-Thomson Microelectronics: \\ {\em 8 Bit MCU Families EF6801/04/05 Databook.\/} \\ 1st edition, 1989 \bibitem{SGS62} SGS-Thomson Microelectronics: \\ {\em ST6210/ST6215/ST6220/ST6225 Databook.\/} \\ 1st edition, 1991 \bibitem{ST7Man} SGS-Thomson Microelectronics: \\ {\em ST7 Family Programming Manual.\/} \\ June 1995 \bibitem{SGS9} SGS-Thomson Microelectronics: \\ {\em ST9 Programming Manual.\/} \\ 3rd edition, 1993 \bibitem{Siem166} Siemens AG: \\ {\em SAB80C166/83C166 User's Manual.\/} \\ Edition 6.90 \bibitem{Siem167} Siemens AG: \\ {\em SAB C167 Preliminary User's Manual.\/} \\ Revision 1.0, July 1992 \bibitem{Siem502} Siemens AG: \\ {\em SAB-C502 8-Bit Single-Chip Microcontroller User's Manual.\/} \\ Edition 8.94 \bibitem{Siem501} Siemens AG: \\ {\em SAB-C501 8-Bit Single-Chip Microcontroller User's Manual.\/} \\ Edition 2.96 \bibitem{Siem504} Siemens AG: \\ {\em C504 8-Bit CMOS Microcontroller User's Manual.\/} \\ Edition 5.96 \bibitem{Syb68K} C.Vieillefond: \\ {\em Programmierung des 68000.\/} \\ Sybex-Verlag D"usseldorf, 1985 \bibitem{Sym8xx} Symbios Logic Inc: \\ {\em Symbios Logic PCI-SCSI-I/O Processors Programming Guide.\/} \\ Version 2.0, 1995/96 \bibitem{Ti990} Texas Instruments: \\ {\em Model 990 Computer/TMS9900 Microprocessor Assembly Language Programmer's Guide.\/} \\ 1977, Manual No. 943441-9701 \bibitem{Ti9900} Texas Instruments: \\ {\em TMS9995 16-Bit Microcomputer Preliminary Data Manual.\/} \\ 1981 \bibitem{TiC10} Texas Instruments: \\ {\em First-Generation TMS320 User's Guide.\/} \\ 1988, ISBN 2-86886-024-9 \bibitem{Ti7000} Texas Instruments: \\ {\em TMS7000 family Data Manual.\/} \\ 1991, DB103 \bibitem{TiC30} Texas Instruments: \\ {\em TMS320C3x User's Guide.\/} \\ Revision E, 1991 \bibitem{TiC20} Texas Instruments: \\ {\em TMS320C2x User's Guide.\/} \\ Revision C, Jan. 1993 \bibitem{Ti370} Texas Instruments: \\ {\em TMS370 Family Data Manual.\/} \\ 1994, SPNS014B \bibitem{Ti430FamSoft} Texas Instruments: \\ {\em MSP430 Family Software User's Guide.\/} \\ 1994, SLAUE11 \bibitem{Ti430Met} Texas Instruments: \\ {\em MSP430 Metering Application.\/} \\ 1996, SLAAE10A \bibitem{Ti430FamArch} Texas Instruments: \\ {\em MSP430 Family Architecture User's Guide.\/} \\ 1995, SLAUE10A \bibitem{TiC60} Texas Instruments: \\ {\em TMS320C62xx CPU and Instruction Set Reference Manual.\/} \\ Jan. 1997, SPRU189A \bibitem{TiC20x} Texas Instruments: \\ {\em TMS320C20x User's Guide.\/} \\ April 1999, SPRU127C \bibitem{Tosh90} Toshiba Corp.: \\ {\em 8-Bit Microcontroller TLCS-90 Development System Manual.\/} \\ 1990 \bibitem{Tosh870} Toshiba Corp.: \\ {\em 8-Bit Microcontroller TLCS-870 Series Data Book.\/} \\ 1992 \bibitem{Tosh900} Toshiba Corp.: \\ {\em 16-Bit Microcontroller TLCS-900 Series Users Manual.\/} \\ 1992 \bibitem{Tosh900L} Toshiba Corp.: \\ {\em 16-Bit Microcontroller TLCS-900 Series Data Book: \\ TMP93CM40F/TMP93CM41F.\/} \\ 1993 \bibitem{Tosh47} Toshiba Corp.: \\ {\em 4-Bit Microcontroller TLCS-47E/47/470/470A Development System Manual.\/} \\ 1993 \bibitem{Tosh9000} Toshiba Corp.: \\ {\em TLCS-9000/16 Instruction Set Manual Version 2.2.\/} \\ 10. Feb 1994 \bibitem{Val8X} Valvo GmbH: \\ {\em Bipolare Mikroprozessoren und bipolare LSI-Schaltungen.\/} \\ Datenbuch, 1985, ISBN 3-87095-186-9 \bibitem{Zilog} Datenbl"atter der Firma Zilog zur Z80-Familie \bibitem{ZilZ8} Zilog Inc.: \\ {\em Z8 Microcontrollers Databook.\/} \\ 1992 \bibitem{ZilZ8_2} Zilog Inc.: \\ {\em Discrete Z8 Microcontrollers Databook.} \\ (keine Jahresangabe) \bibitem{ZilZ380} Zilog Inc.: \\ {\em Z380 CPU Central Processing Unit User's Manual.\/} \\ (keine Jahresangabe) \end{thebibliography} \cleardoublepage \printindex \end{document}