11793 lines
524 KiB
TeX
11793 lines
524 KiB
TeX
%%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-<version>.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<72>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 <Datei>
|
||
\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 @<Datei> ....
|
||
\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[:]]<Befehl>[.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}
|
||
[<n>] <Zeile>/<Adresse> <Code> <Quelle>
|
||
\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 <Maske>
|
||
\end{verbatim}
|
||
werden die in \verb!<Maske>! 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 <Symbolname> (=<Wert>,<Datei>/<Zeile>):
|
||
Datei <Datei 1>:
|
||
<n1>[(m1)] ..... <nk>[(mk)]
|
||
.
|
||
.
|
||
Datei <Datei l>:
|
||
<n1>[(m1)] ..... <nk>[(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}
|
||
[-]<Vorkommastellen>[.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 <Var})}
|
||
\item{Entfernen Sie diese vermaledeite, verfluchte Vorw"artsreferenz und
|
||
setzen Sie die \tty{EQU}-Anweisung nach vorne, wo sie hingeh"ort
|
||
(OK, ich beruhige mich ja schon wieder...)}
|
||
\item{F"ur ganz Unentwegte: Benutzten Sie die \tty{-Y}-Option, so da"s AS die
|
||
Fehlermeldung beim Erkennen der Adre"sverschiebung nachtr"aglich
|
||
verwirft. Nicht sch"on, aber...}
|
||
\end{enumerate}
|
||
Noch ein Hinweis zum \tty{EQU}-Befehl: Da AS nicht wissen kann, in welchem
|
||
Zusammenhang ein mit \tty{EQU} definiertes Symbol sp"ater verwendet wird,
|
||
wird ein \tty{EQU} mit Vorw"artsreferenzen im ersten Pass "uberhaupt nicht
|
||
durchgef"uhrt. Wird das mit \tty{EQU} definierte Symbol also im zweiten
|
||
Pass vorw"arts referenziert:
|
||
\begin{verbatim}
|
||
move.l #sym2,d0
|
||
sym2 equ sym1+5
|
||
sym1 equ 0
|
||
\end{verbatim}
|
||
so handelt man sich im zweiten Pass eine Fehlermeldung wegen eines
|
||
undefinerten Symbols ein...aber warum machen Leute eigentlich solche
|
||
Dinge ???
|
||
|
||
Zugegeben, das war ein ziemlich l"anglicher Ausflug, aber es mu"ste einfach
|
||
einmal sein. Was sollte man als Erkenntnis aus diesem Abschnitt mitnehmen?
|
||
\begin{enumerate}
|
||
\item{AS versucht immer, den k"urzestm"oglichen Code zu erzeugen. Dazu
|
||
ben"otigt er eine endliche Zahl von Durchl"aufen. Wenn man ihn
|
||
nicht gerade knebelt, kennt AS keine R"ucksichten...}
|
||
\item{Wenn sinnvoll und m"oglich, Sprung- und Adre"sl"angen explizit
|
||
vorgeben. Man kann damit u.U. die Anzahl der Durchl"aufe deutlich
|
||
reduzieren.}
|
||
\item{Vorw"artsreferenzen auf das allern"otigste beschr"anken. Man
|
||
erleichtert sich und AS das Leben damit erheblich!}
|
||
\end{enumerate}
|
||
|
||
%%---------------------------------------------------------------------------
|
||
|
||
\section{Registersymbole}
|
||
\label{SectRegSyms} \ttindex{Registersymbole}
|
||
|
||
{\em G"ultigkeit: PowerPC, M-Core, 4004, 80C16x, AVR}
|
||
|
||
Manchmal ist es erw"unscht, nicht nur einer Speicheradresse oder einer
|
||
Konstanten, sondern auch einem Register einen symbolischen Namen zuzuweisen,
|
||
um seine Funktion in einem bestimmten Programmabschnitt zu verdeutlichen.
|
||
Dies ist bei Prozessoren, die die Register schlicht als einen weiteren
|
||
Adre"sraum behandeln, recht problemlos, da als Register damit auch
|
||
Zahlenausdr"ucke erlaubt sind und man solche Symbole mit schlichten
|
||
\tty{EQU}s definieren kann (z.B. bei MCS-96 oder TMS7000). Bei den
|
||
allermeisten Prozessoren jedoch sind Registernamen festgelegte Literale, und
|
||
AS behandelt sie aus Geschwindigkeitsgr"unden gesondert, so da"s ein besonderer
|
||
Mechanismus vonn"oten ist, um symbolische Register zu definieren. Ein Registersymbol
|
||
wird "ublicherweise durch die \tty{REG}-Anweisung definiert und hat ansonsten
|
||
die gleiche Form wie eine \tty{EQU}-Definition. Sie unterliegt jedoch einer
|
||
Reihe von Einschr"ankungen: Zum einen ist ein Registersymbol eine reine 'as is'
|
||
gespeicherte Zeichenkette, die auch nur in dieser Form verwendet werden kann.
|
||
Es ist also z.B. keine Arithmetik m"oglich, um aus einem Register den Nachfolger
|
||
zu berechnen, etwa so:
|
||
\begin{verbatim}
|
||
myreg reg r17 ; Definition Registersymbol
|
||
addi myreg+1,3 ; geht nicht!
|
||
\end{verbatim}
|
||
Zum anderen mu"s ein Registersymbol vor seiner ersten Nutzung definiert
|
||
werden; eine Vorw"artsreferenz w"urde dazu f"uhren, da"s AS bei nicht gefundenem
|
||
Registersymbol eine Vorw"artsreferenz auf eine Speicherstelle vermutet, und bei
|
||
den meisten Prozessoren sind die Nutzungsm"oglichkeiten f"ur Speicherstellen als
|
||
Operanden deutlich eingeschr"ankter als f"ur Register, so da"s es mit ziemlicher
|
||
Sicherheit Fehler hagelt...
|
||
|
||
Registersymbole sind analog zu normalen Symbolen lokal zu Sektionen,
|
||
und es ist auch durch Anh"angen eines in eckige Klammern gesetzten Sektionsnamens
|
||
m"oglich, auf ein Registersymbol aus einer bestimmten Sektion zuzugreifen.
|
||
Aufgrund der fehlenden M"oglichkeit zur Vorw"artsreferenz gibt es aber keine
|
||
Entsprechung zur \tty{FORWARD}-Direktive, und da Registersymbole im allgemeinen
|
||
nur in einem sehr eng umschr"ankten Kontext eine Bedeutung haben, ist ein Export
|
||
per \tty{PUBLIC} oder \tty{GLOBAL} auch nicht vorgesehen.
|
||
|
||
Sind in einem Kontext ein normales als auch ein Registersymbol gleichen Namens
|
||
bekannt, so wird immer das Registersymbol vorgezogen. Dies ist aber nicht der
|
||
Fall, wenn der Name nicht alleine, sondern eingebunden in einen Ausdruck
|
||
steht (dazu reichen Klammern!), dann wird das normale Symbol benutzt.
|
||
|
||
%%---------------------------------------------------------------------------
|
||
|
||
\section{Sharefile}
|
||
\label{ChapShareMain} \ttindex{SHARED}
|
||
|
||
Diese Funktion ist ein Abfallprodukt aus den reinen 68000er-Vorg"angern
|
||
von AS, da sie vielleicht doch der (die?!) eine oder andere gebrauchen
|
||
k"onnte, habe ich sie dringelassen. Grundproblem ist es, an bestimmte
|
||
beim Assemblieren entstehende Symbole heranzukommen, weil man evtl. mit
|
||
diesen Adre"sinformationen auf den Speicher des Zielsystems zugreifen
|
||
m"ochte. Der Assembler erlaubt es, mit Hilfe des \tty{SHARED}-Pseudobefehles
|
||
(siehe dort) Symbolwerte extern zur Verf"ugung zu stellen. Zu diesem
|
||
Zweck erstellt der Assembler im zweiten Pass eine Textdatei mit den
|
||
gew"unschten Symbolen und ihren Werten, die mittels Include in ein
|
||
Hochsprachen-oder weiteres Assemblerprogramm eingebunden werden k"onnen.
|
||
Das Format der Textdatei (C, Pascal oder Assembler) wird durch die
|
||
Kommandozeilenschalter \tty{p}, \tty{c} oder \tty{a} festgelegt.
|
||
\par
|
||
\bb{ACHTUNG!} Ist keiner dieser Schalter angegeben, so wird auch keine
|
||
Datei erzeugt, egal ob sich \tty{SHARED}-Befehle im Quelltext finden oder
|
||
nicht!
|
||
\par
|
||
AS pr"uft beim Anlegen der Share-Datei nicht, ob bereits eine Datei gleichen
|
||
Namens existiert, eine solche wird ggfs. einfach "uberschrieben. Eine
|
||
Abfrage halte ich nicht f"ur sinnvoll, da AS dann bei jedem Lauf fragen
|
||
w"urde, ob er die alte Version der Share-Datei "uberschreiben darf, und das
|
||
w"are doch sehr l"astig...
|
||
|
||
%%---------------------------------------------------------------------------
|
||
|
||
\section{Prozessor-Aliasse}
|
||
\label{SectAlias}
|
||
|
||
Mit Varianten g"angiger Mikrocontroller-Familien ist es wie mit
|
||
Kaninchen: Sie vermehren sich schneller, als man mit der Versorgung
|
||
hinterherkommen kann. Im Zuge der Entwicklung von Prozessorkernen als
|
||
Bausteine f"ur ASICs und von Controller-Familien mit vom Kunden w"ahlbarer
|
||
Peripherie wird die Zahl von Controller-Varianten, die sich von einem
|
||
bekannten Typ nur in einigen Peripherie-Details unterscheiden, immer
|
||
gr"o"ser. Die Unterscheidung der einzelnen Typen ist aber trotz meist
|
||
identischer Prozessorkernes wichtig, um z.B. in den Includefiles den
|
||
korrekten Satz von Peripherieregistern einzublenden. Bisher habe ich
|
||
mich zwar immer bem"uht, die wichtigsten Vertreter einer Familie in AS
|
||
einzubauen (und werde das auch weiter tun), aber manchmal l"auft mir
|
||
die Entwicklung einfach auf und davon...es mu"ste also ein Mechanismus
|
||
her, mit dem man die Liste der unterscheidbaren Prozessortypen selbst
|
||
erweitern kann.
|
||
\par
|
||
Das Ergebnis davon sind Prozessor-Aliasse: Mit der Kommandozeilenoption \tty{alias}
|
||
kann man einen neuen Prozessortyp definieren, der im Befehlssatz einem
|
||
anderen, in AS fest eingebauten Typ entspricht. Bei Benutzung dieses
|
||
Typs im \tty{CPU}-Befehl wird sich AS also wie beim ,,Original'' verhalten,
|
||
mit einem Unterschied: Die Variablen \tty{MOMCPU} bzw. \tty{MOMCPUNAME}
|
||
werden auf den Namen des Alias gesetzt, wodurch der neue Name zur
|
||
Unterscheidung z.B. in Includefiles dienen kann.
|
||
\par
|
||
Die Definition dieser Aliasse wurde aus zwei Gr"unden mit
|
||
Kommandozeilenoptionen anstatt Pseudobefehlen vorgenommen: zum einen
|
||
w"are es ohnehin nicht m"oglich gewesen, die Definition der Aliasse
|
||
zusammen mit den Registerdefinitionen in eine Include-Datei zu legen, denn
|
||
in einem Programm, das so eine Datei benutzen wollte, m"u"ste sie ja sowohl
|
||
vor als auch nach dem \tty{CPU}-Befehl in der Hauptdatei eingebunden
|
||
werden - eine Vorstellung, die irgendwo zwischen unelegant und unm"oglich
|
||
liegt. Zum zweiten erm"oglicht diese Implementierung, die Definition der
|
||
neuen Typen in eine Datei zu legen, die "uber die \tty{ASCMD}-Variable beim
|
||
Start automatisch ausgef"uhrt wird, ohne das sich das Programm darum
|
||
k"ummern m"u"ste.
|
||
|
||
%%===========================================================================
|
||
|
||
\cleardoublepage
|
||
\chapter{Pseudobefehle}
|
||
|
||
Nicht f"ur alle Prozessoren sind alle Pseudobefehle definiert. Vor
|
||
der Beschreibung eines Befehls ist deshalb jeweils vermerkt, f"ur
|
||
welche Prozessortypen dieser Befehl erlaubt ist.
|
||
|
||
%%---------------------------------------------------------------------------
|
||
|
||
\section{Definitionen}
|
||
|
||
%%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
\subsection{SET und EQU}
|
||
\ttindex{SET}\ttindex{EQU}
|
||
|
||
{\em G"ultigkeit: alle Prozessoren}
|
||
|
||
\tty{SET} und \tty{EQU} erlauben die Definition typenloser Konstanten, d.h. sie
|
||
werden keinem Segment zugeordnet und ihre Verwendung erzeugt in keinem
|
||
Fall eine Warnung wegen Segmentverquickung. W"ahrend \tty{EQU} Konstanten
|
||
definiert, die nicht wieder (mit \tty{EQU}) ge"andert werden k"onnen, erlaubt
|
||
\tty{SET} die Definition von Variablen, die sich w"ahrend des Assemblerlaufes
|
||
ver"andern lassen. Dies ist n"utzlich z.B. bei der Allokation von
|
||
Resourcen \`a la Interruptvektoren, wie im folgenden Beispiel:
|
||
\begin{verbatim}
|
||
VecCnt SET 0 ; irgendwo am Anfang
|
||
...
|
||
DefVec MACRO Name ; einen neuen Vektor belegen
|
||
Name EQU VecCnt
|
||
VecCnt SET VecCnt+4
|
||
ENDM
|
||
...
|
||
DefVec Vec1 ; ergibt Vec1=0
|
||
DefVec Vec2 ; ergibt Vec2=4
|
||
\end{verbatim}
|
||
Intern werden Konstanten und Variablen identisch gespeichert, der
|
||
einzige Unterschied ist, da"s sie mit \tty{SET} umdefiniert werden
|
||
k"onnen und mit \tty{EQU} nicht. Es ist daher m"oglich, ein Symbol
|
||
mit \tty{EQU} zu definieren und es mit \tty{SET} zu "andern, auch
|
||
wenn das nicht der Sinn der Sache ist. Aus einem weiteren Grund
|
||
sollte man davon sogar explizit die Finger lassen: Im Gegensatz zu
|
||
\tty{SET} pr"uft \tty{EQU}, ob der neu zugewiesene Wert sich von
|
||
einem evtl. bisher existierenden unterscheidet. Da sich dieser f"ur
|
||
mit \tty{EQU} definierte Konstanten nicht "andern sollte, vermutet
|
||
AS einen Phasenfehler und legt einen weiteren Pass ein...w"urde man
|
||
in obigem Beispiel z.B. die Initialisierung des Z"ahlers mit \tty{EQU}
|
||
durchf"uhren, so w"urde AS sich zwar nicht beschweren, da eine einmalige
|
||
Neuzuweisung pro Pass erlaubt ist (bei $n$ Durchg"angen kommt man nun
|
||
einmal $n$-mal an dieser Stelle vorbei), aber endlos neue Passes ansto"sen,
|
||
da der Initialwert des Z"ahlers immer vom Endwert verschieden ist.
|
||
\par
|
||
Mit \tty{EQU/SET} lassen sich Konstanten aller Typen definieren, z.B.
|
||
\begin{verbatim}
|
||
IntZwei EQU 2
|
||
FloatZwei EQU 2.0
|
||
\end{verbatim}
|
||
Einige Prozessoren besitzen leider bereits selber einen \tty{SET}-Befehl.
|
||
Bei diesen mu"s \tty{EVAL} anstelle von \tty{SET} verwendet werden.
|
||
\par
|
||
Anstelle von \tty{EQU} darf auch einfach ein Gleichheitszeichen geschrieben
|
||
werden, analog kann man anstelle von \tty{SET} bzw. \tty{EVAL}
|
||
einfach \tty{:=} schreiben.
|
||
\par
|
||
Defaultm"a"sig sind mit \tty{SET} oder \tty{EQU} definierte Symbole
|
||
typenlos, optional kann jedoch als zweites Argument ein Segmentname
|
||
(\tty{CODE, DATA, IDATA, XDATA, YDATA, BITDATA, IO oder REG}) oder
|
||
\tty{MOMSEGMENT} f"ur das aktuell gesetzte Segment angegeben werden,
|
||
um das Symbol einem bestimmten Adre"sraum zuordnen. AS ber"ucksichtigt
|
||
dabei nicht, ob der benutzte Adre"sraum bei dem aktuell gesetzten
|
||
Zielprozessor auch vorhanden ist!
|
||
|
||
%%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
\subsection{SFR und SFRB}
|
||
\ttindex{SFR}\ttindex{SFRB}
|
||
|
||
{\em G"ultigkeit: diverse, SFRB nur MCS-51}
|
||
|
||
Diese Befehle funktionieren wie \tty{EQU}, nur sind die damit definierten
|
||
Symbole dem direkt adressierbaren Datensegment zugeordnet, d.h. sie
|
||
dienen bevorzugt zur Definition von RAM-Zellen und (wie der Name
|
||
ahnen l"a"st) im Datenbereich eingeblendeten Hardwareregistern. Der
|
||
dabei zugelassene Wertebereich ist identisch mit dem bei \tty{ORG} f"ur
|
||
das \tty{DATA}-Segment zugelassenen (s. Abschnitt \ref{SectORG}).
|
||
\tty{SFR} und \tty{SFRB} unterscheiden sich darin, da"s \tty{SFRB}
|
||
das Register als bitadressierbar kennzeichnet, weshalb AS zus"atzlich 8
|
||
Symbole erzeugt, die dem Bitsegment zugeordnet werden und die Namen
|
||
\tty{xx.0} bis \tty{xx.7} tragen, z.B.
|
||
\begin{verbatim}
|
||
PSW SFR 0d0h ; ergibt PSW = D0H (Datensegment)
|
||
|
||
PSW SFRB 0d0h ; zusaetzlich PSW.0 = D0H (Bit)
|
||
; bis PSW.7 = D7H (Bit)
|
||
\end{verbatim}
|
||
Da beim 80C251 grunds"atzlich alle SFRs ohne zus"atzliche Bit-Symbole
|
||
bitadressierbar sind, ist der \tty{SFRB}-Befehl f"ur ihn auch nicht mehr
|
||
definiert; die Bits \tty{PSW.0} bis \tty{PSW.7} sind automatisch vorhanden.
|
||
\par
|
||
AS "uberpr"uft bei der Definition eines bitadressierbaren Registers mit
|
||
\tty{SFRB}, ob die Speicherstelle "uberhaupt bitadressierbar ist (Bereich
|
||
20h..3fh bzw. 80h, 88h, 90h, 98h...0f8h). Ist sie es nicht, so wird eine
|
||
Warnung ausgegeben; die dann erzeugten Bit-Symbole sind undefiniert.
|
||
|
||
|
||
%%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
\subsection{XSFR und YSFR}
|
||
\ttindex{XSFR}\ttindex{YSFR}
|
||
|
||
{\em G"ultigkeit: DSP56xxx}
|
||
|
||
Auch der DSP56000 hat einige Peripherieregister memory-mapped im
|
||
Speicher liegen, die Sache wird jedoch dadurch komplizierter, da"s
|
||
es zwei Datenbereiche gibt, den X-und Y-Bereich. Diese Architektur
|
||
erlaubt einerseits zwar einen h"oheren Parallelit"atsgrad, zwingt
|
||
jedoch andererseits dazu, den normalen \tty{SFR}-Befehl in die beiden
|
||
oben genannten Varianten aufzuspalten. Sie verhalten sich identisch zu
|
||
\tty{SFR}, nur da"s \tty{XSFR} ein Symbol im X-Adre"sraum definiert
|
||
und \tty{YSFR} entsprechend eines im Y-Adre"sraum. Der erlaubte
|
||
Wertebereich ist 0..\$ffff.
|
||
|
||
%%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
||
\subsection{LABEL}
|
||
\ttindex{LABEL}
|
||
|
||
{\em G"ultigkeit: alle Prozessoren}
|
||
|
||
Die Funktion des \tty{LABEL}-Befehls ist identisch zu \tty{EQU}, nur
|
||
wird das Symbol nicht typenlos, sondern erh"alt das Attribut ,,Code''.
|
||
\tty{LABEL} wird genau f"ur einen Zweck ben"otigt: Labels in Makros
|
||
sind normalerweise lokal, also nicht au"serhalb des Makros zugreifbar.
|
||
Mit einem \tty{EQU}-Befehl kann man sich zwar aus der Aff"are ziehen,
|
||
die Formulierung
|
||
\begin{verbatim}
|
||
<Name> 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<65>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 <20>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 <Adresse>
|
||
\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 $<Anzahl>$
|
||
}\end{quote}
|
||
ist eine Kurzschreibweise f"ur
|
||
\begin{quote}{\tt
|
||
DB $<Anzahl>$ 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}
|
||
<Name> MACRO [Parameterliste]
|
||
<Befehle>
|
||
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}
|
||
<Name> 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}
|
||
<Name> FUNCTION <Arg>,..,<Arg>,<Ausdruck>
|
||
\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 <Ausdruck 1>
|
||
<Block 1>
|
||
ELSEIF <Ausdruck 2>
|
||
<Block 2>
|
||
(evtl. weitere ELSEIFs)
|
||
ELSEIF
|
||
<Block n>
|
||
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 <Ausdruck>
|
||
...
|
||
CASE <Wert 1>
|
||
...
|
||
<Block 1>
|
||
...
|
||
CASE <Wert 2>
|
||
...
|
||
<Block 2>
|
||
...
|
||
(weitere CASE-Konstrukte)
|
||
...
|
||
CASE <Wert n-1>
|
||
...
|
||
<Block n-1>
|
||
...
|
||
ELSECASE
|
||
...
|
||
<Block n>
|
||
...
|
||
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 <String>
|
||
\end{verbatim}
|
||
die Zeichenfolge angibt, die vor Listingbeginn an das Ausgabeger"at
|
||
geschickt werden soll und mit
|
||
\begin{verbatim}
|
||
PRTEXIT <String>
|
||
\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}
|
||
<Unterprogrammname>_<Symbolname>
|
||
\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}
|
||
...
|
||
<anderer Code>
|
||
...
|
||
SECTION <Sektionsname>
|
||
...
|
||
<Code in der Sektion>
|
||
...
|
||
ENDSECTION [Sektionsname]
|
||
...
|
||
<anderer Code>
|
||
...
|
||
\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 <Name>
|
||
\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 <Name>:<Sektion>
|
||
\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: .
|
||
<Code>
|
||
..
|
||
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 <Pfadliste>
|
||
\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 <Datei>
|
||
\end{verbatim}
|
||
In dieser Form wird die Datei komplett eingebunden.
|
||
\begin{verbatim}
|
||
BINCLUDE <Datei>,<Offset>
|
||
\end{verbatim}
|
||
In dieser Form wird der Inhalt der Datei ab \verb!<Offset>! bis zum Ende
|
||
der Datei eingebunden.
|
||
\begin{verbatim}
|
||
BINCLUDE <Datei>,<Offset>,<Len>
|
||
\end{verbatim}
|
||
In dieser Form werden \verb!<Len>! Bytes ab Offset \verb!<Offset>! 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: ..
|
||
<das eigentliche Programm>
|
||
..
|
||
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{\#<Konstante>}), 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 <Prozessortyp>
|
||
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} $<Daten>$ & \tty{DD} $<Daten>$ & Speicher in Langworten belegen \\
|
||
\hline
|
||
\tty{DSB} $<Zahl>$ & \tty{DB} $<Zahl>$ \tty{DUP} (?) & Speicher byteweise reservieren \\
|
||
\hline
|
||
\tty{DSW} $<Zahl>$ & \tty{DW} $<Zahl>$ \tty{DUP} (?) & Speicher wortweise reservieren \\
|
||
\hline
|
||
\tty{DSD} $<Zahl>$ & \tty{DD} $<Zahl>$ \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 <Adr15..8>
|
||
MOWF 3
|
||
LCALL <Adr0..7>
|
||
\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}
|
||
<Name> 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!<Kommandozeile>! & 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}
|
||
<Zeilennummer>:<Adresse>
|
||
\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 <Segmentname>
|
||
\end{verbatim}
|
||
bzw.
|
||
\begin{verbatim}
|
||
File <Dateiname>
|
||
\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 <Segmentname> .
|
||
\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 <Quelldatei(en)> <Zieldatei> [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 <Quellname> <Zielname> -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 <Startadresse>-<Endadresse>
|
||
\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 <Quelldatei> eprom1 -f $31 -r $0000-$1fff
|
||
p2hex <Quelldatei> eprom2 -f $31 -r $2000-$3fff
|
||
p2hex <Quelldatei> eprom3 -f $31 -r $4000-$5fff
|
||
p2hex <Quelldatei> 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 <Wert>
|
||
\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 <Start>-<Ende>
|
||
\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 <Adresse> ,
|
||
\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 <Anzahl>
|
||
\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 <Name>
|
||
\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 <Datei>
|
||
\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}
|
||
|