JTCEMU-Assembler-Syntax


1. Allgemeine Syntax

1.1. Groß- und Kleinschreibung

Der Assembler unterscheidet bei Marken die Groß- und Kleinschreibung, außer Sie haben die Assembler-Option Groß- und Kleinschreibung bei Marken ignorieren angeklickt. Bei der Mnemonik, den Pseudobefehlen und den Assembler-Direktiven ist die Groß-/Kleinschreibung egal.

1.2. Aufbau einer Assembler-Quelltextzeile

Die allgemeine Syntax einer Quelltextzeile lautet:

[Marke] [Befehl] [Kommentar]


In eckigen Klammern stehende Teile sind optional, d.h., eine Zeile kann auch nur aus einer Marke, einem Befehl oder einem Kommentar bestehen oder auch leer sein. Vor und hinter den einzelnen Teilen können beliebig viele Leerzeichen und Tabulatoren stehen.

Eine Marke muss mit einem Doppelpunkt abgeschlossen werden. Anderenfalls wird sie als Befehl gewertet. Einzige Ausnahme ist der Pseudobefehl .equ, bei dem die Marke auch ohne Doppelpunkt angegeben werden kann.

Ein Befehl kann folgenden Aufbau haben:

1.3. Marken

Marken haben einen numerischen 16-Bit-Wert und werden definiert, indem sie am Anfang einer Assembler-Zeile stehen und mit einem Doppelpunkt abgeschlossen sind oder der Pseudobefehl .equ folgt. Bei .equ erhält die Marke den Wert des hinter des Befehls stehenden Ausdrucks, anderenfalls den Wert der aktuellen Adresse. Marken, die auf letzter Art und Weise angelegt werden, nennt man auch Adressmarken. Pro Quelltextzeile kann nur eine Marke definiert werden.

Marken können als Sprungziele oder in numerischen Ausdrücken verwendet werden.

Marken können Buchstaben, Ziffern und den Unterstrich enthalten. Allerdings darf eine Ziffer nicht am Anfang der Marke stehen.

Achtung! Der Assembler legt zur Unterstützung der bedingten Assemblierung automatisch immer die Marke __JTCEMU__ mit dem Wert %FFFF (alle Bits gesetzt) an.

1.4. Kommentare

Kommentare beginnen mit einem Semikolon, einem Ausrufezeichen oder zwei Schrägstrichen (zwei Slash-Zeichen) und gehen bis zum Ende der Quelltextzeile:

  ; Kommentar
  ! Kommentar
  // Kommentar


Alles ab dem Ausrufezeichen, dem Semikolon oder den zwei Slashs bis zum Ende der Zeile wird als Kommentar gewertet und vom Assembler nicht ausgewertet. Dies gilt jedoch nicht, wenn die betreffenden Zeichen in einem Zeichenliteral oder einer Zeichenkette stehen. In dem Fall sind die betreffenden Zeichen Teil des Literals und leiten keinen Kommentar ein.

2. CPU-Befehle

Die Mnemonik der Z8-CPU-Befehle sowie die Syntax der zugehörigen Argumente entspricht den Angaben in [1].

2.1. Registernamen

Arbeitsregister (Working Register) beginnen mit einem R, gefolgt von der Nummer 0 bis 15 (z.B. R0). Arbeitsdoppelregister beginnen mit Doppel-R, gefolgt von einer geraden Nummer 0 bis 14 (z.B. RR2).

Reguläre Register (General Purpose Register, Ports und Steuerregister) werden mit ihrer Registernummer angesprochen. Die Ports (Register 0 bis 3) und die Steuerregister (Register 240 bis 255 bzw. %F0 bis %FF) haben zusätzlich einen Namen. Bei diesen Registern kann sowohl die Registernummer als auch der Registername verwendet werden:

Registernummer Registername
Dezimal Hexadezimal
0 %00 P0
1 %01 P1
2 %02 P2
3 %03 P3
240 %F0 SIO
241 %F1 TMR
242 %F2 T1
243 %F3 PRE1
244 %F4 T0
245 %F5 PRE0
246 %F6 P2M
247 %F7 P3M
248 %F8 P01M
249 %F9 IPR
250 %FA IRQ
251 %FB IMR
252 %FC FLAGS
253 %FD PR
254 %FE SPH
255 %FF SPL

Das Doppelregister für den externen Stack Pointer (254 / 255 bzw. %FE / %FF) trägt den Namen SP.

Die Registernamen sind reservierte Schlüsselwörter und können nicht als Marken verwendet werden. Die Groß-/Kleinschreibung der Registernamen ist egal.

3. Pseudobefehle

Der Assembler versteht folgende Pseudobefehle:

Befehl Synonyme Bedeutung
.align ALIGN Aktuelle Adresse ausrichten
.binclude BINCLUDE Einbinden einer Binärdatei
.cpu CPU Angabe des Prozessortyps
.db .byte
.db.b
.defb
DB
DB.B
DEFB
Datenbytes erzeugen
.ds .ds.b
.defs
DS
DS.B
DEFS
Speicherbereich reservieren
.ds.w DS.W Speicherbereich in Anzahl Datenwörtern reservieren
.dw .db.b
.defb
.word
DB
DB.B
DEFB
Datenbytes erzeugen
.end END Ende des Quelltextes bzw. der Quelltextdatei
.ent .entry
ENT
Eintrittspunkt (Startpunkt) des Programms
.equ .equal
EQU
Anlegen einer Marke mit einem vorgegebenen Wert
.error ERROR Ausgabe eines Fehlers
.include INCLUDE Einbinden einer Quelltextdatei
.org ORG Programmzähler (Adresse) auf den angegebenen Wert setzen
.title TITLE Titel oder Bezeichnung des Programms
.warning WARNING Ausgabe einer Warnung
.warnoff WARNOFF Ausgabe von Warnungen unterdrücken
.warnon WARNON Ausgabe von Warnungen ermöglichen

Anstelle des in der ersten Spalte angegebenen Befehlsnamens können auch uneingeschräkt die Synonyme in der zweiten Spalte verwendet werden. Die Groß-/Kleinschreibung spielt bei den Namen der Pseudobefehle keine Rolle.

Aus Gründen der Kompatibilität zu anderen Z8-Assemblern werden noch weitere Pseudobefehle verstanden, die hier jedoch keine Wirkung haben.

3.1. Pseudobefehl .align

Syntax:
  .align <Zahlenliteral>
  .align <Zahlenliteral>,<Ausdruck>

Mit .align richtet man die aktuelle Adresse auf eine Zweierpotenz aus, also z.B. 2, 4, 8, 16, ... Entspricht die aktuelle Adresse keiner Zweierpotenz, werden soviele %FF-Bytes eingefügt, bis das der Fall ist.

Beispiel:
  .org %8000
  .db 1
  .align %100
  ;Aktuelle Adresse ist jetzt %8100.


Soll mit einem anderen Byte anstatt %FF aufgefüllt werden, können Sie dieses als weiteres Argument angeben:
  .org %8000
  .db 1
  .align 4,0  ;Es werden 3 Nullbytes eingefuegt.

3.2. Pseudobefehl .binclude

Der Befehl fügt die angegebene Datei unverändert, d.h. in binärer Form, an der aktuellen Stelle in den erzeugten Programmcode ein. Der Dateiname ist in einfachen oder doppelten Hochkommas einzuschließen und kann ohne oder mit Pfad angegeben werden, wobei sowohl ein absoluter als auch ein relativer Pfad erlaubt sind. Die Pfadangabe muss den Regeln des Betriebssystems entsprechen. Unabhängig davon kann aber ein relativer Pfad auch in einer betriebssystemunabhängigen Form (also auch unter Windows) mit einem Slash (/) als Pfadtrennzeichen angegeben werden.

Beispiel mit absoluter Pfadangabe unter Linux/Unix:
  .binclude "/home/users/myuser/fonts/zeichensatz.bin"

Beispiel mit absoluter Pfadangabe unter Windows:
  .binclude "C:\Users\myuser\fonts\zeichensatz.bin"

Beispiel mit relativer und betriebssystemunabhängiger Pfadangabe:
  .binclude "../fonts/zeichensatz.bin"

Beispiel ohne Pfadangabe:
  .binclude "zeichensatz.bin"

3.3. Pseudobefehl .cpu

Mit .cpu wird der Prozessortyp angegeben, für den der Assembler Programmcode erzeugen soll. Folgende Prozessortypen (Schlüsselwörter) werden unterstützt:
   U881  U882  U883  U884  U886   Z8   Z8601  Z8603   Z8611  Z8612  Z8613   Z8671   Z8681  Z8682  Z86C04  Z86C08  Z86C93  Z86E04  Z86E08

Beispiel:
  .cpu Z8601

Die Auswirkung des Pseudobefehls ist, dass der Assembler nur solche CPU-Befehle und Registernummern zulässt, die in dem angegebenen Prozessortyp auch vorhanden sind. Enthält das Assembler-Programm keinen .cpu-Befehl, gibt der Assembler Warnungen an den Stellen aus, bei denen CPU-Befehle oder Registernummern verwendet werden, die nicht in allen Z8-Typen vorhanden sind.

Mit dem Prozessortyp Z8 werden alle CPU-Eigenschaften aktiviert, d.h., bei diesem Prozessortyp werden keine CPU-relevanten Warnungen oder Fehler ausgegeben.

3.4. Pseudobefehl .db

Mit diesem Befehl werden Datenbytes an der aktuellen Stelle im Programmcode erzeugt. Der Pseudobefehl kann beliebig viele Argumente haben, die durch Komma zu trennen sind. Ein Argument kann entweder ein Numerischer Ausdruck oder eine Zeichenkette sein.

Beispiele:
  ABC  .equ
 .db
 .db
 12
 3*ABC
 "Ein Text",%0D,%0A,0

 ;ein Byte mit dem Wert %24 (dezimal 36)
 ;C-String

3.4.1. Zeichenketten

Eine Zeichenkette ist eine Aneinanderreihung von Textzeichen, die in einfachen oder doppelten Hochkommas eingeschlossen sind. Die numerischen Codes der Textzeichen müssen im 8-Bit-Bereich liegen.

Der Zeichensatz des Texteditors, mit dem das Assembler-Programm geschrieben wird, kann sich von dem des Zielsystems, d.h., auf dem das übersetzte Assembler-Programm ausgeführt wird, unterscheiden (und wird sich meistens auch unterscheiden). Aus diesem Grund sollten nur ASCII-Zeichen in Zeichenketten geschrieben werden. Nicht-ASCII-Zeichen lassen sich bei .db als separates Argument mit ihrem numerischen Wert angeben (siehe Beispiel weiter oben).

Es besteht auch die Möglichkeit, bestimmte Zeichen oder beliebige Zeichencodes direkt in der Zeichenkette anzugeben. Dafür gibt es spezielle Zeichensequenzen, die mit einem Prozenzeichen beginnen:

Zeichensequenz Erzeuger Zeichencode Bedeutung
%T
%t
9 Tabulator
%L
%l
10 Line Feed
%P
%p
12 Form Feed
%R
%r
13 Carrige Return
%% 37 Prozentzeichen
%Q
%q
39 Einfaches Anführungszeichen

Als weitere Möglichkeit kann man hinter dem Prozentzeichen mit zwei Hexadezimalziffern den Zeichencode angeben.

Beispiele:
  .db  "Text 1"
  .db  'Text 2'
  .db  'Zeile 1%R%LZeile 2'
  .db  'Das Prozentzeichen: %%'
  .db  'Das Escape-Zeichen: %1B'


Hinweis: Die mit dem Prozentzeichen beginnenden speziellen Zeichensequenzen entsprechen denen in [1].

3.5. Pseudobefehl .ds

Dieser Befehl reserviert Speicher, z.B. für Variablen. Der Befehl kann beliebig viele, durch Komma getrennte Argumente haben, wobei jedes Argument ein numerischer Ausdruck sein muss, der die Anzahl der zu reservierenden Bytes angibt. Die Adresse wird entsprechend weitergezählt.

Steht der Befehl (auch mehrfach hintereinander) am Anfang oder am Ende des Quelltextes, wird kein Programmcode erzeugt. Steht der Befehl dagegebn mittendrin, d.h. davor und danach stehen Programmcode erzeugende Befehle, dann werden für den reservierten Speicherbereich %FF-Bytes (Z8-NOP-Befehle) erzeugt.

Beispiel:
  .ds  3*4,6  ;18 Bytes reservieren

3.6. Pseudobefehl .ds.w

Der Befehl entspricht dem Pseudobefehl .ds nur mit dem Unterschied, dass der Speicher nicht in Anzahl Bytes sondern in Anzahl Datenwörter reserviert wird. Verglichen mit dem .ds-Befehl werden also genau doppelt soviele Bytes reserviert.

  .ds.w  1  ;2 Bytes reservieren

3.7. Pseudobefehl .dw

Mit diesem Befehl werden Datenwörter (16 Bit bzw. 2 Bytes) an der aktuellen Stelle im Programmcode erzeugt. Das höherwertige Byte steht vor dem niederwertigen.

Der Pseudobefehl kann beliebig viele Argumente haben, die durch Komma zu trennen sind. Jedes Argument muss ein numerischer Ausdruck sein.

Beispiel einer Adresstabelle mit Zeigern auf einzelne Routinen:
  addr_tab: .dw addr1, addr2, addr3   ;Tabelle
...:
  addr1: ...:   ;Routine 1
ret:
  addr2: ...:   ;Routine 2
ret:

3.8. Pseudobefehl .end

Dieser Befehl markiert das Ende des Assembler-Quelltextes bzw. der Quelltextdatei, d.h. alle weiteren Zeilen des Quelltextes bzw. der aktuellen Quelltextdatei werden ignoriert. Steht der Befehl in einer mit INCLUDE eingebundenen Datei, wird diese eingebundene Datei beendet und der Assembler setzt mit der nächsten Zeile hinter dem zugehörigen INCLUDE-Befehl fort.

Hinter dem Befehl END kann opional eine Bezeichnung angegeben werden, die jedoch keine Bedeutung hat.

Beispiel:
  .title Testprogramm
  ...  ;eigentliches Assembler-Programm
  .end Testprogramm
  --- Ab hier wird alles ignoriert. ---


3.9. Pseudobefehl .ent

Der Befehl hat keine Argumente und markiert die Stelle, an der das Assembler-Programm gestartet wird. Der Befehl hat nur eine Wirkung, wenn der Assembler den erzeugten Programmcode in eine Datei schreibt und das Format dieser Datei eine Startadresse unterstützt. In dem Fall wird die Adresse, an der der .ent-Befehl steht, als Startadresse in die Datei geschrieben, anderenfalls steht keine Startadresse in der Datei.

3.10. Pseudobefehl .equ

Dieser Befehl legt die links stehende Marke mit dem rechts stehenden Wert an. Die Marke muss in dem Fall nicht zwingend mit einem Doppelpunkt abgeschlossen sein.

Beispiele:
  ABC
  DEF:
 .equ
 .equ
 12
 %34

Der rechts stehende Ausdruck kann auch Marken enthalten, die erst weiter hinten im Assembler-Programm angelegt werden (sogenannte Vorwärtsreferenzen). In dem Fall wird der Wert der Marke erst dann berechnet, wenn er benötigt wird.

Beispiel:
  STR_LEN
  M1:
  M2:
 .equ
 .db
 .db
 M2-M1
 'Ein String'
 0

Achtung! Wird eine Marke mit Vorwärtsreferenz in den Pseudobefehlen .ds oder .org oder in bestimmten Fällen bei der bedingten Assemblierung verwendet, meldet der Assembler einen Fehler, da hier der Wert der Marke schon zum Zeitpunkt der Befehlsverarbeitung benötigt wird und nicht erst später "nachgereicht" werden kann.

Achtung! Wenn zwei Marken sich direkt oder indirekt gegenseitig referenzieren, können die Werte dieser Marken nicht berechnet werden. In dem Fall meldet der Assembler einen Fehler mit "nicht auflösbaren Vorwärtsreferenzen", sobald der Wert der Marke benötigt wird.

3.11. Pseudobefehl .error

Mit .error kann man wärend des Assemblierens einen Fehler ausgeben.

Beispiele:
  .error  'Das ist eine Fehlermeldung'
  .error  "Fehler !!!"


3.12. Pseudobefehl .include

Mit .include wird eine weitere Assembler-Quelltextdatei eingebunden. Der Assembler verarbeitet die eingebundene Datei und setzt dann mit der nächsten Zeile des Haupt-Quelltextes fort. Geschachtelte .include-Befehle sind nicht möglich, d.h., in der der eingebundenen Datei darf kein .include-Befehl vorkommen.

Bzgl. des Dateinamens der eingebundenen Datei gilt das gleiche wie bei .binclude.

Mit dem .include.Befehl ist es möglich, in mehreren Assembler-Programmen benötigte gleiche Quelltextteile in separate Dateien auslagern und dann in den einzelnen Programmen an den benötigten Stellen einfach einzubinden.

Beispiel:
  .include  'bibliothek.asm'

3.13. Pseudobefehl .org

Mit .org wird der Programmzähler auf den angegebenen Wert, d.h. auf eine bestimmte Adresse gesetzt. Üblicherweise beginnt jedes Assembler-Programm mit einem .org-Befehl, der die Anfangsadresse des Programms angibt.

Beispiel:
  .org  %E000

Der .org-Befehl kann im Programm mehrfach vorkommen, allerdings kann die Adresse nicht vor die aktualle Position gesetzt werden. Durch mehrfache .org-Befehle auftretende Lücken im erzeugten Programmcode werden mit %FF-Bytes (Z8-NOP-Befehl) gefüllt.

3.14. Pseudobefehl .title

Mit .title gibt man dem Assmbler-Programm einen Titel bzw. eine Bezeichnung. Der Befehl hat nur eine Wirkung, wenn der Assembler den erzeugten Programmcode in eine Datei schreibt und das Format dieser Datei eine Bezeichnung unterstützt. In dem Fall wird der Titel als Bezeichnung in die Datei geschrieben.

Wenn der Titel Leereichen oder Tabulatoren enthält, muss er in einfachen oder doppelten Hochkommas geschrieben werden.

Beispiele:
  .title  Mein_Programm
  .title  'Mein Programm'
  .title  "Mein Programm"


Achtung! Mehrfache .title-Befehle sind nicht erlaubt.

3.15. Pseudobefehl .warning

Mit .warning kann man während des Assemblierens eine Warnung ausgeben.

Beispiel:
  .warning  "Das ist eine Warnung"


Achtung! Warnungen werden nur im zweiten Assembler-Lauf ausgegeben. Wenn im ersten Assembler-Lauf Fehler auftreten und somit kein zweiter Assembler-Lauf stattfindet, erfolgt auch keine Ausgabe von Warnungen.

Achtung! Warnungen werden nur dann ausgegeben, wenn diese nicht mit .warnoff unterdrückt werden bzw. mit .warnon wieder aktiviert wurden.

3.16. Pseudobefehl .warnoff

Mit .warnoff wird die Ausgabe von Warnungen deaktiviert.

3.17. Pseudobefehl .warnon

Mit .warnon wird die Ausgabe von Warnungen aktiviert, d.h. es hebt ein vorheriges .warnoff auf.

4. Numerische Ausdrücke

Numerische Ausdrücke kommen überall dort zur Anwendung, wo ein numerischer Wert benötigt wird. In dem Assemblerbefehl

  LD %20,#123

sind sowohl der Teil %20 als auch auch der Teil 123 numerische Ausdrücke, und zwar konkret Zahlenliterale (Hexadezimalzahl und Dezimalzahl). Numerische Ausdrücke können aber auch komplexer sein und zusätzlich Operatoren, Zeichenliterale und Marken enthalten. Außerdem können numerische Ausdrücke mit runden Klammern beliebig geschachtelt werden.

Numerische Ausdrücke werden vorzeichenlos mit 16 Bit ohne Überlaufprüfung berechnet. Wenn eine Subtraktion ein negatives Ergebnlis liefert, werden die unteren 16 Bit des Ergebnisses als nicht-negative (also Null oder positive) 16-Bit-Zahl gewertet.

Die Syntax der numerischen Ausdrücke ist kompatibel zu der in [1].

4.1. Zahlenliterale

Zahlenliterale beginnen mit einer Ziffer oder einem Prozentzeichen. Für Binär- und Hexadezimalzahlen sind jeweils zwei verschiedene Syntaxvarianten möglich.

4.1.1. Dezimalzahlen

Dezimalzahlen bestehen nur aus Ziffern und haben kein vorangestelltes Prozentzeichen und auch keinen nachfolgenden Erkennungsbuchstaben.

Beispiele:
  0
  12
  345


4.1.2. Hexadezimalzahlen

Hexadezimalzahlen beginnen entweder mit einem Prozentzeichen, gefolgt von der eigentlichen Hexadezimalzahl oder sie beginnen mit einer Ziffer und enden mit dem Buchstaben H bzw. h.

Beispiele:
  %41
  %A
  %E000
  00H
  0Ah
  0E000H


4.1.3. Binärzahlen

Binärzahlen beginnen entweder mit %(2) gefolgt von der eigentlichen Binärzahl oder sie beginnen mit einer Ziffer und enden mit dem Buchstaben B bzw. b.

Beispiele:
  %(2)101
  %(2)0110
  101B
  0110b


Achtung! Beginnt eine Binärzahl mit 0 oder 1 und es folgt hinter der Binärzahl ein großes oder kleines H, dann wird diese Zahl als Hexadezimalzahl erkannt.

Beispiel:
  101Bh  ;Das ist eine Hexadezimalzahl!

4.1.4. Oktalzahlen

Oktalzahlen beginnen mit %(8) gefolgt von der eigentlichen Oktalzahl.

Beispiel:
  %(8)707
  %(8)1357


4.2. Zeichenliterale

Ein Zeichenliteral ist ein in einfachen Hochkommas eingeschlossenes Zeichen, z.B. 'A'. Ein Zeichenliteral kann innerhalb eines numerischen Ausdrucks verwendet werden und liefert den numerischen Wert des Zeichencodes.

Achtung! Aufgrund unterschiedlicher Zeichensätze zwischen Texteditor und Zielsystem sollten nur ASCII-Zeichen in Zeichenliteralen verwendet werden.

4.3. Unäre Operatoren

Unäre Operatoren wirken auf den nachfolgenden Ausdruck.

OperatorBeschreibung
+ Positives Vorzeichen: Der nachfolgende Wert wird nicht verändert.
- Negatives Vorzeichen: Der nachfolgende Wert wird mathematisch negiert.
Achtung! Aufgrund der vorzeichenlosen Berechnung ist das Ergebnis niemals negativ.
-1 ergibt %FFFF bzw. 65535.
NOT
LNOT
Logical NOT: Der nachfolgende Wert wird bitweise negiert


4.4. Operatoren mit zwei Operanden

Binäre Operatoren stehen zwischen zwei Ausdrücken.
OperatorBeschreibung
+Addition
- Subtraktion
Achtung! Aufgrund der vorzeichenlosen Berechnung ist das Ergebnis niemals negativ.
1 - 3 ergibt %FFFE bzw. 65534.
*Multiplikation
/Division
MOD Modulo - Rest der Division
AND
LAND
Logical AND: bitweise UND-Verknüpfung
OR
LOR
Logical OR: bitweise Inklusiv-ODER-Verknüpfung
XOR
LXOR
Logical XOR: bitweise Exklusiv-ODER-Verknüpfung
SHL links schieben
Der links vom Operator stehende Wert wird um soviele Bits nach links geschoben, wie der Wert rechts vom Operator angibt. Nach der Operation ist das unterste Bit immer 0.
SHR links schieben
Der links vom Operator stehende Wert wird um soviele Bits nach rechts geschoben, wie der Wert rechts vom Operator angibt. Nach der Operation ist das oberste Bit immer 0.
< Vergleich auf kleiner als
Ist der erste Wert kleiner als der zweite, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.
<= Vergleich auf kleiner oder gleich
Ist der erste Wert kleiner oder gleich dem zweiten, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.
> Vergleich auf größer als
Ist der erste Wert größer als der zweite, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.
>= Vergleich auf größer oder gleich
Ist der erste Wert größer oder gleich dem zweiten, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.
= Vergleich auf Gleichheit
Ist der erste Wert gleich dem zweiten, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.
<> Vergleich auf Ungleichheit
Ist der erste Wert ungleich dem zweiten, ergibt das den Wert %FFFF (alle Bits gesetzt), anderenfalls 0.

4.5. Aktuelle Adresse

Die aktuelle Adresse wird durch das $-Zeichen repräsentiert. Wenn Sie also in einem Ausdruck den Wert des Programm Counters (Register PC) zu Beginn der aktuellen Assembler-Zeile benötigen, schreiben Sie dafür das Zeichen: $

4.6. Zugriff auf höher- bzw. niederwertiges Byte

Bei CPU-Befehlen mit einem 8-Bit-Direktwert kann durch Angabe des Schlüsselwortes HIGH oder HI bzw. LOW oder LO hinter dem Doppelkreuz festgelegt werden, dass nur der Wert des höher- bzw. niederwertiges Bytes des nachfolgenden Ausdrucks verwendet werden soll. Die Schlüsselwörter können auch klein geschrieben werden.

Beispiele (Ausdrücke mit Marken):
  LD %23,#HI abc*3
  LD %24,#high M_ADDR
  LD %24,#lo M_ADDR
  LD %24,#LOW ABC SHL 4


4.7. Vorrangregeln

Wenn in einem numerischen Ausdruck mehrere Operatoren vorkommen, dann berechnet der Assembler die Teilausdrücke zuerst, deren Operatorn eine höhere Bindungskraft haben. Bei gleicher Bindungskraft werden die Operatoren von links nach rechts berechnet. Die Berechnungsreihenfolge kann durch Setzen von runden Klammern geändert werden. Diese haben die höchste Bindungskraft.

Unäre Operatoren haben eine höhere Bindungskraft als Operatoren mit zwei Operanden. Die Tabelle zeigt die Bindungskraft der einzelnen Operatoren. Innerhalb einer Tabellenzeile ist die Bindungskraft gleich, d.h., diese Operatoren werden von links nach rechts abgearbeitet.

BindungskraftZugehörige Operatoren
am höchsten + (Vorzeichen)
- (Vorzeichen)
NOT
LNOT
* (Multiplikation)
/ (Division)
AND
LAND

MOD
SHL
SHR
+ (Addition)
- (Subtraktion)
OR
LOR

XOR
LXOR
am niedrigsten =
<>
<=
<
>=
>

4.8. Grammatik

Folgende Grammatik beschreibt die Syntax der Ausdrücke:

Direktwert:
  # Ausdruck
  #HI Ausdruck
  #HIGH Ausdruck
  #LO Ausdruck
  #LOW Ausdruck

Ausdruck:
  Additionsausdruck
  Ausdruck = Additionsausdruck
  Ausdruck <> Additionsausdruck
  Ausdruck <= Additionsausdruck
  Ausdruck < Additionsausdruck
  Ausdruck >= Additionsausdruck
  Ausdruck > Additionsausdruck

Additionsausdruck:
  Multiplikationsausdruck
  Additionsausdruck + Multiplikationsausdruck
  Additionsausdruck - Multiplikationsausdruck
  Additionsausdruck LOR Multiplikationsausdruck
  Additionsausdruck LXOR Multiplikationsausdruck
  Additionsausdruck OR Multiplikationsausdruck
  Additionsausdruck XOR Multiplikationsausdruck

Multiplikationsausdruck:
  Unärer_Ausdruck
  Multiplikationsausdruck: * Unärer_Ausdruck
  Multiplikationsausdruck: / Unärer_Ausdruck
  Multiplikationsausdruck: AND Unärer_Ausdruck
  Multiplikationsausdruck: LAND Unärer_Ausdruck
  Multiplikationsausdruck: MOD Unärer_Ausdruck
  Multiplikationsausdruck: SHL Unärer_Ausdruck
  Multiplikationsausdruck: SHR Unärer_Ausdruck

Unärer_Ausdruck:
  Primärausdruck
  + Primärausdruck
  - Primärausdruck
  NOT Primärausdruck
  LNOT Primärausdruck
  ( Ausdruck )

Primärausdruck:
  $
  Marke
  Zahl
  ' 8-Bit-Zeichen '

Zahl:
  Dezimalzahl
  Hexadezimalzahl
  Binärzahl
  Oktalzahl

Dezimalzahl:
  <Folge von Dezimalziffern>

Dezimalziffer:
  <Ziffer 0...9>

Hexadezimalzahl:
  Dezimalziffer H
  Dezimalziffer <Folge von Hexadezimalziffern> H
  % <Folge von Hexadezimalziffern>

Hexadezimalziffer:
  <Ziffer 0...9 oder Buchstabe A...F>

Binärzahl:
  <Folge von Binärziffern> B
  %(2)<Folge von Binärziffern>

Binärziffer:
  <Ziffer 0 oder 1>

Oktalzahl:
  %(8) <Folge von Oktalziffern>

Oktalziffer:
  <Ziffer 0...7>

5. Assembler-Direktiven und bedingte Assemblierung

Unter bedingter Assemblierung versteht man, dass Teile des Quelltextes nur dann assembliert werden, wenn eine bestimmte Bedingung erfüllt ist.

Ein der bedingten Assemblierung unterliegender Quelltextabschnitt beginnt mit einer $IF-, $IFFALSE- $IFDEF- oder $IFNDEF-Direktive und endet mit einer $ENDIF-Direktive. Opional können dazwischen $ELSE-Direktiven (auch mehrere) vorkommen, die den Assemblierungsstatus jedesmal umkehren.

Die Tabelle zeigt die Assembler-Direktiven für bedingte Assemblierung. Die in spitzen Klammern stehenden Teile sowie drei Punkte sind entsprechend zu ersetzen. Die in eckigen Klammern stehenden Teile sind optional und können weggelassen werden.

Direktive/SyntaxSynonyme
$IF <Marke> [$THEN]
$IF <Ausdruck> [$THEN]
.if ... [.then]
IF ... [THEN]
$IFTRUE ... [$THEN]
.iftrue ... [.then]
IFTRUE ... [THEN]
$IFFALSE <Marke> [$THEN]
$IFFALSE <Ausdruck> [$THEN]
.iffalse ... [.then]
IFFALSE ... [THEN]
$IFDEF <Marke> [$THEN] .ifdef ... [.then]
IFDEF ... [THEN]
$IFNDEF <Marke> [$THEN] .ifndef ... [.then]
IFNDEF ... [THEN]
$ELSE .else
ELSE
$ENDIF [<Bezeichnung>] $FI [<Bezeichnung>]
.endif [<Bezeichnung>]
ENDIF [<Bezeichnung>]
$EVEN .even
EVEN

Anstelle der Schlüselwörter aus der ersten Tabellenspalte können auch die zugehörigen Synonyme aus der zweiten Spalte verwendet werden. Die Groß-/Kleinschreibung der Schlüselwörter ist egal.

Achtung! Wenn in Assembler-Direktiven für die bedingte Assemblierung Marken verwendet werden und der numerische Wert dieser Marken ausgewertet wird, dann müssen die Marken in dem Augenblick, wenn der Assembler die Direktive verarbeitet, die Werte der Marken auch berechnet werden können, d.h., diese Marken dürfen keine Vorwärtsreferenzen enthalten. Anderenfalls meldet der Assembler einen Fehler.

Es gibt auch Assembler-Direktiven, die nur das Vorhandensein einer Marke prüfen. Bei diesen Assembler-Direktiven können die Marken auch Vorwärtsreferenzen enthalten.

5.1. Assembler-Direktive $IF

Syntax:
  $IF <Marke>
  $IF <Marke> $THEN
  $IF <Ausdruck>
  $IF <Ausdruck> $THEN

Wird nur eine einzelne Marke angegeben, dann wird der nachfolgende Quelltextabschnitt assembliert, wenn die Marke existiert und einen Wert ungleich 0 hat.
Existiert die Marke nicht oder sie hat den numerischen Wert 0, dann wir der nachfolgende Quelltextabschnitt nicht assembliert. Existiert die Marke, dann muss auch deren numerischer Wert berechnet werden können.

Die zweite Syntaxvariante testet auf einen Ausdruck, der nicht nur aus einer Marke besteht. In dieser Variante müssen alle im Ausdruck vorkommenden Marken vorhanden sein und deren Werte auch berechnet werden können. Der nachfolgende Quelltextabschnitt wird dann assembliert, wenn der Wert des Ausdrucks ungleich 0 ist.


Das Schlüsselwort $THEN ist optional und kann weggelassen werden. Es wird aus Gründen der Kompatibilität zur Syntax in [1], unterstützt.

5.2. Assembler-Direktive $IFFALSE

Syntax:
  $IFFALSE <Marke>
  $IFFALSE <Marke> $THEN
  $IFFALSE <Ausdruck>
  $IFFALSE <Ausdruck> $THEN

$IFFALSE ist die Umkehrung der $IF-Direktive, d.h. die $IF-Direktive nach dem ersten $ELSE. Der nachfolgende Quelltextabschnitt wird assembliert, wenn die Marke nicht existiert oder den Wert 0 hat oder der numerische Ausdruck den Wert 0 hat.

5.3. Assembler-Direktive $IFDEF

Syntax:
  $IFDEF <Marke>
  $IFDEF <Marke> $THEN

Der nachfolgende Quelltextabschnitt wird assembliert, wenn die angegebene Marke existiert. Der Wert der Marke spielt keine Rolle.

5.4. Assembler-Direktive $IFNDEF

Syntax:
  $IFNDEF <Marke>
  $IFNDEF <Marke> $THEN

Dies ist die Umkehrung der $IFDEF-Direktive. Der nachfolgende Quelltextabschnitt wird somit assembliert, wenn die angegebene Marke nicht existiert. Der Wert der Marke spielt keine Rolle.

5.5. Assembler-Direktive $ELSEIF

Syntax:
  $ELSEIF <Marke>
  $ELSEIF <Marke> $THEN
  $ELSEIF <Ausdruck>
  $ELSEIF <Ausdruck> $THEN

$ELSEIF kann nach einer der oben beschriebenen $IF-Direktiven stehen und ermöglicht einen weiter Zweig der bedingten Assemblierung. Wurde der Abschnitt der $IF-Direktive nicht assembliert, dann wird die $ELSEIF-Direktive geprüft. Bzgl. der Bedingung gilt das gleiche wie bei der $IFFALSE-Direktive. Es können beliebig viele $ELSEIF-Direktiven angegebene werden.

5.6. Assembler-Direktive $ELSE

Syntax:
  $ELSE

$ELSE kann nach einer der oben beschriebenen $IF-Direktiven oder der $ELSEIF-Direktive stehen und kehrt den Assemblierungsstatus um, d.h., wurde der Abschnitt vor $ELSE assembliert, dann wird der nachfolgende Abschnitt nicht assembliert. Das gleiche gilt umgekehrt: Wurde davor nicht assembliert, dann wird danach assembliert. Es können beliebig viele $ELSE-Direktiven angegebene werden.

5.7. Assembler-Direktive $ENDIF

Syntax:
  $ENDIF
  $ENDIF <Bezeichnung>

Die $ENDIF-Direktive beendet den Abschnitt der bedingten Assembliuerung. Optional kann hinter $ENDIF ein Wort angegeben werden, welches eine Info für den Programmierer ist und vom Assembler ignoriert wird.

5.8. Beispiel für bedingte Assemblierung

  .db 'Dieses Programm wurde mit'
$IFDEF __JTCEMU__
  .db ' dem JTCEMU-'
$ELSE
  .db ' einem unbekannten '
$ENDIF
  .db 'Assembler assembliert.'

Hinweis: Die Assembler-Direktiven für bedingte Assemblierung können in sich geschachtelt werden und sind weitgehend kompatibel zu denen in [1].

5.9. Assembler-Direktive $EVEN

Syntax:
  $EVEN

Die $EVEN-Direktive setzt die aktuelle Adresse auf einen geraden Wert. Dazu wird ggf. ein %FF-Byte eingefügt.

Die Wirkung der $EVEN-Direktive kann man auch mit dem Pseudobefehl .align erreichen.

6. Assembler-Direktiven und Pseudobefehle ohne Wirkung

Nachfolgende Assembler-Direktiven und Pseudobefehle werden aus Gründen der Kompatibilität zu anderen Z8-Assemblern verstanden, entfalten in diesem Assembler jedoch keine Wirkung. Diese Befehle einschließlich eventueller Argumente werden einfach überlesen:

Befehl Synonyme
.assume ASSUME
.globals GLOBALS
.listing LISTING
$LISTING
.listoff LISTOFF
$LISTOFF
.liston LISTON
$LISTON
.page PAGE
$PAGE
.newpage NEWPAGE
$NEWPAGE

7. Literatur
[1] Zilog Inc.: Z8 PLZ/ASM Assembly Language Programming Manual, Campbell, California, USA, December 1980