Als typischer Vertreter einer einfachen Registermaschine hat die Minimaschine einen Akkumulator, der bei Rechenoperationen vor der jeweiligen Operation den ersten Operanden und nach Ausführung der Operation das Ergebnis beinhaltet. Bei Speicheroperationen ist er Ziel oder Quelle. Entsprechend ist die Maschine als Ein-Adress-Maschine konzipiert, d. h. die Befehle haben einen Adressteil (Speicheradresse oder direkt verwendete Zahl); bei speziellen Befehlen wird der Adressteil nicht benutzt.
Der Assembler erlaubt sowohl absolute Adressierung, d. h. Angabe betroffener Speicherzellen als konkrete Zahlenwerte, als auch symbolische Adressierung. Dabei wird als Adressteil eine Marke (Bezeichner) angegeben; diese Marke ist an anderer Stelle (Programm oder Daten) vereinbart. Der Assembler berechnet dann die Adresse automatisch.
Bei indirekter Adressierung in der Form (<Adresse>) ist die Operandenadresse der Wert, der in der mit <Adresse> bezeichneten Speicherzelle enthalten ist.
Durch das Einschalten der Erweiterungen werden neben dem Stackpointerregister und zusätzlichen Befehlen auch weitere Adressierungsarten um Zugriff auf auf dem Stack gespeicherte Werte ermöglicht.
Assemblerprogramme haben einen sehr einfach strukturierten Aufbau. Ein Assemblerprogramm besteht aus einer Folge von Befehlszeilen. Jede Befehlszeile besteht aus einer optionalen Marke, dem Befehl und einem optionalen (vom Befehl abhängenden) Adressteil. Leere Zeilen oder Zeilen, die nur eine Marke enthalten, sind ebenfalls möglich.
Das Zeichen "#" leitet einen Kommentar ein. Kommentare gehen grundsätzlich bis zum Ende der Zeile.
# Algorithmus, um ein Produkt mittels wiederholter Addition zu berechen. LOADI 0 STORE Produkt # Ergebnis vorbesetzen Start: # Start der Wiederholung LOAD Faktor1 JMPNP Ende # Beenden, wenn der Zähler kleiner als 0 geworden ist SUBI 1 # Zähler erniedrigen STORE Faktor1 LOAD Produkt ADD Faktor2 STORE Produkt # Ergebnis erhöhen JMP Start Ende: HOLD # Maschine anhalten # Datenteil Faktor1: WORD 5 # Der erste Faktor dient als Zähler für die Wiederholung der Addition Faktor2: WORD 4 # Der zweite Faktor wird fortwährend addiert Produkt: WORD 0 # Platz für das Ergebnis
In EBNF lässt sich die Syntax der Assemblersprache kurz zusammenfassen. Die Erweiterungen sind kursiv dargestellt.
Programm = {Zeile} . Zeile = [Markenvereinbarung] [Befehl] . Markenvereinbarung = Marke ":" . Marke = ( "A" .. "Z" | "a" .. "z" ) { "A" .. "Z" | "a" .. "z" | "0" .. "9" | "_" | "$" } . Befehl = Operation [ Adresse | "(" Adresse ")" | $Adresse | Adresse(SP) | @Adresse(SP) | $Adresse(SP) ]. Operation = OperationGroß | OperationKlein . OperationGroß = "HOLD" | "RESET" | "NOOP" | "ADD" | "SUB" | "MUL" | "DIV" | "AND" | "OR" | "XOR" | "NOT" | "SHL" | "SHR" | "SHRA" | "MOD" | "CMP" | "LOAD" | "STORE" | "JMPP" | "JMPNN" | "JMPN" | "JMPNP" | "JMPZ" | "JMPNZ" | "JMPV" | "JMP" | "ADDI" | "SUBI" | "MULI" | "DIVI" | "MODI" | "CMPI" | "LOADI" | "ANDI" | "ORI" | "XORI" | "SHLI" | "SHRI" | "SHRAI" | "JSR" | "RTS" | "PUSH" | "POP" | "RSV" | "REL" | "WORD" . OperationKlein = "hold" | "reset" | "noop" | "add" | "sub" | "mul | "div" | "and" | "or | "xor | "not | "shl | "shr | "shra" | "mod" | "cmp | "load | "store" | "jmpp" | "jmpnn" | "jmpn | "jmpnp" | "jmpz" | "jmpnz" | "jmpv" | "jmp | "addi" | "subi" | "muli" | "divi" | "modi" | "cmpi" | "loadi" | "andi" | "ori" | "xori" | "shli" | "shri" | "shrai" | "jsr" | "rts" | "push" | "pop" | "rsv" | "rel" | "word" . Adresse = Marke | Zahl | HexZahl . HexZahl = "0" ("x" | "X" ) ( "0" .. "9" | "A" .. "F" | "a" .. "f" ) { "0" .. "9" | "A" .. "F" | "a" .. "f" } . Zahl = ( "0" .. "9" ) { "0" .. "9" } .
Die mit "#" eingeleiteten Kommentare treten im Syntaxdiagramm nicht auf, da sie entsprechend den Leerzeichen, Tabulatoren oder Zeilenwechseln bereits bei der Zerlegung des Quelltextes in Terminalsymbole abgearbeitet werden.
Die folgende Tabelle beschreibt die Befehle der Minimaschine geordnet nach Funktionsgruppen. Wiedergegeben sind nur die großgeschriebenen Varianten der Befehlsmnemonics.
Speicherbefehle | |
LOAD adresse | Lädt den Wert von der angegebenen Adresse in den Akkumulator. |
LOADI zahl | Lädt die angegebenen Zahl in den Akkumulator, negative Werte sind möglich, Adressen sind nicht zulässig. |
STORE adresse | Speichert den Wert im Akkumulator an der angegebenen Adresse. |
Arithmetikbefehle | |
ADD adresse | Addiert den Wert von der angegebenen Adresse zum Akkumulator. |
SUB adresse | Subtrahiert den Wert der angegebenen Adresse vom Akkumulator. |
MUL adresse | Multipliziert den Wert von der angegebenen Adresse zum Akkumulator. |
DIV adresse | Dividiert den Wert im Akkumulator durch den Wert der angegebenen Adresse. |
MOD adresse | Dividiert den Wert im Akkumulator durch den Wert der angegebenen Adresse und speichert den Rest im Akkumulator. |
CMP adresse | Vergleicht den Wert der angegebenen Adresse mit dem Akkumulator und setzt Null- und Negativflag entsprechend. |
ADDI zahl | Addiert den angegebenen Wert zum Akkumulator. |
SUBI zahl | Subtrahiert den angegebenen Wert vom Akkumulator. |
MULI zahl | Multipliziert den angegebenen Wert zum Akkumulator. |
DIVI zahl | Dividiert den Wert im Akkumulator durch den angegebenen Wert. |
MODI zahl | Dividiert den Wert im Akkumulator durch den angegebenen Wert und speichert den Rest im Akkumulator. |
CMPI zahl | Vergleicht den angegebenen Wert mit dem Akkumulator und setzt Null- und Negativflag entsprechend. |
Bitmanipulationsbefehle | |
AND adresse | Bitweise logische Und-Verknüpfung des Werts der angegebenen Adresse mit dem Akkumulator. |
OR adresse | Bitweise logische Oder-Verknüpfung des Werts der angegebenen Adresse mit dem Akkumulator. |
XOR adresse | Bitweise logische Exklusiv-Oder-Verknüpfung des Werts der angegebenen Adresse mit dem Akkumulator. |
NOT | Bitweise logische Invertierung des Werts im Akkumulator. |
SHL adresse | Die Bitfolge im Akkumulator wird um die unter der angegebenen Adresse gespeicherten Anzahl Bits nach links geschoben. Frei werdende Bits werden mit 0-Werten belegt. |
SHR adresse | Die Bitfolge im Akkumulator wird um die unter der angegebenen Adresse gespeicherten Anzahl Bits nach rechts geschoben. Frei werdende Bits werden mit 0-Werten belegt. |
SHRA adresse | Die Bitfolge im Akkumulator wird um die unter der angegebenen Adresse gespeicherten Anzahl Bits nach rechts geschoben. Frei werdende Bits werden mit dem ursprünglich vordersten Bit belegt (Vorzeichenerhalt). |
ANDI zahl | Bitweise logische Und-Verknüpfung der angegebenen Zahl mit dem Akkumulator. |
ORI zahl | Bitweise logische Oder-Verknüpfung der angegebenen Zahl mit dem Akkumulator. |
XORI zahl | Bitweise logische Exklusiv-Oder-Verknüpfung der angegebenen Zahl mit dem Akkumulator. |
SHLI zahl | Die Bitfolge im Akkumulator wird um die angegebene Anzahl Bits nach links geschoben. Frei werdende Bits werden mit 0-Werten belegt. |
SHRI zahl | Die Bitfolge im Akkumulator wird um die angegebene Anzahl Bits nach rechts geschoben. Frei werdende Bits werden mit 0-Werten belegt. |
SHRAI zahl | Die Bitfolge im Akkumulator wird um die angegebene Anzahl Bits nach rechts geschoben. Frei werdende Bits werden mit dem ursprünglich vordersten Bit belegt (Vorzeichenerhalt). |
Sprungbefehle | |
JMPP adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation positiv (> 0) war, d. h. weder N noch Z-Flag sind gesetzt. |
JMPNN adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht negativ (≥ 0) war, d. h. das N-Flag ist nicht gesetzt. |
JMPN adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation negativ (< 0) war, d. h. das N-Flag ist gesetzt. |
JMPNP adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht positiv (≤ 0) war, d. h. das N-Flag oder das Z-Flag ist gesetzt. |
JMPZ adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation null (= 0) war, d. h. das Z-Flag ist gesetzt. |
JMPNZ adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht null (≠ 0) war, d. h. das Z-Flag ist nicht gesetzt. |
JMPV adresse | Springt zur angegebenen Adresse, wenn die letzte Operation einen Überlauf verursacht hat, d. h. das V-Flag ist gesetzt. |
JMP adresse | Springt zur angegebenen Adresse. |
Alternative Notation der Sprungbefehle | |
JGT adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation positiv (> 0) war, d. h. weder N noch Z-Flag sind gesetzt. |
JGE adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht negativ (≥ 0) war, d. h. das N-Flag ist nicht gesetzt. |
JLT adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation negativ (< 0) war, d. h. das N-Flag ist gesetzt. |
JLE adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht positiv (≤ 0) war, d. h. das N-Flag oder das Z-Flag ist gesetzt. |
JEQ adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation null (= 0) war, d. h. das Z-Flag ist gesetzt. |
JNE adresse | Springt zur angegebenen Adresse, wenn das Ergebnis der letzen Operation nicht null (≠ 0) war, d. h. das Z-Flag ist nicht gesetzt. |
JOV adresse | Springt zur angegebenen Adresse, wenn die letzte Operation einen Überlauf verursacht hat, d. h. das V-Flag ist gesetzt. |
Sonstige Befehle | |
HOLD | Hält den Prozessor an. Dieser Befehl hat keine Adresse. |
RESET | Setzt den Prozessor auf den Startzustand zurück. Dieser Befehl hat keine Adresse. |
NOOP | Tut einfach nichts (NO OPeration). Dieser Befehl hat keine Adresse. |
Den Stackpointer verändernde Befehle | |
JSR | Springt zu der angegebenen Adresse und speichert den Folge-PC auf dem Stack (Unterprogrammaufruf). Der Stackpointer wird dazu um 1 erniedrigt. |
RTS | Springt zu der Adresse in der Speicherzelle, auf dei der Stackpointer zeigt (Unterprogamrücksprung). Der Stackpointer wird anschließend um 1 erhöht. |
PUSH | Erniedrigt den Stackpointer um 1 und speichert den Akkumulatorwert an der nun durch den Stackpointer gegebenen Adresse. |
POP | Lädt den Inhalt der durch den Stackpointer gegebenen Adresse in den Akkumulator und erhöht den Stackpointer um 1. |
RSV | Erniedrigt den Stackpointer um den im Adressteil gegebenen Wert (Platz reservieren). |
REL | Erhöht den Stackpointer um den im Adressteil gegebenen Wert (Platz freigeben). |
CALL | Alternative Notation zu JSR. |
RETURN | Alternative Notation zu RTS. |
Speicherorganisation | |
WORD zahl | Besetzt eine Speicherzelle mit der angegebenen Zahl, negative Werte sind möglich. |