Unterschiedliche Darstellung der Toy-Befehle |
||
Binär | Hexadezimal | Assembler |
0000 xxxx xxxx xxxx xxxx | $0yyy | STO z |
0001 xxxx xxxx xxxx xxxx | $1yyy | LDA z |
0010 xxxx xxxx xxxx xxxx | $2yyy | BRZ z |
0011 xxxx xxxx xxxx xxxx | $3yyy | ADD z |
0100 xxxx xxxx xxxx xxxx | $4yyy | SUB z |
0101 xxxx xxxx xxxx xxxx | $5yyy | OR z |
0110 xxxx xxxx xxxx xxxx | $6yyy | AND z |
0111 xxxx xxxx xxxx xxxx | $7yyy | XOR z |
1000 xxxx xxxx xxxx xxxx | $8yyy | NOT |
1001 xxxx xxxx xxxx xxxx | $9yyy | INC |
1010 xxxx xxxx xxxx xxxx | $Ayyy | DEC |
1011 xxxx xxxx xxxx xxxx | $Byyy | ZRO |
1100 xxxx xxxx xxxx xxxx | $Cyyy | NOP |
1101 xxxx xxxx xxxx xxxx | $Dyyy | NOP |
1110 xxxx xxxx xxxx xxxx | $Eyyy | NOP |
1111 xxxx xxxx xxxx xxxx | $Fyyy | NOP |
Es gibt vier unterschiedliche Möglichkeiten ein Toy-Programm zu schreiben: Die Befehle können sowohl in binärer und in hexadezimaler Schreibweise, als auch in Assembler (= Mnemonic, vgl. Tabelle Befehlssatz des ToyProcessors") kodiert werden. Außerdem gibt es noch die Möglichkeit Pseudo-C-Code zu verfassen.
Die Tabelle "Unterschiedliche Darstellung der Toy-Befehle" umfasst die Binär-, Hexadezimal- und Assemblervarianten. Die "xxxxxxxxxxxx" kodieren die Adresse für den jeweiligen OP-Code in binär, "yyy" stehen für die Adresse in hexadezimal und "z" gibt die Adresse als Dezimalzahl an.
Wir werden nun das Programmieren mit den Toy-Befehlen an einigen Beispielen üben. Am Ende dieses Absatzes werden wir dann noch auf die Einschränkungen des Pseudo-C-Codes eingehen.
Format: Das Toy-Programm sollte in einem simplen Texteditor geschrieben werden. Die Textdatei sollte die Endung *.toy bekommen.
Code: Die einzelnen Befehle werden alle untereinander in jeweils neue Zeilen geschrieben. In den RAM werden sie in der gleichen Reihenfolge geschrieben, angefangen bei der nullten Speicherzelle. Wie man der Tabelle "Unterschiedliche Darstellung der Toy-Befehle" entnehmen kann, sind die verschiedenen Varianten (binär, hexadezimal und Assembler) äquivalent, daher können diese im Source-Code gemischt werden. Beispielsweise liefern somit die folgenden drei Toy-Programme zum Subtrahieren der Werte aus RAM[11] und RAM[22] dasselbe Ergebnis:
Binär | Hexadezimal | Assembler | Gemischt |
0001 0000 0000 1011 | $100B | LDA 11 | 0001 0000 0000 1011 |
0100 0000 0001 0110 | $4016 | SUB 22 | $4016 |
0000 0000 0000 1011 | $000B | STO 11 | STO 11 |
RAM-Settings: Um mit konkreten Werten zu rechnen, können diese direkt in den RAM geschrieben und die RAM-Adresse für die jeweiligen Rechenoperationen benutzt werden. Angenommen, wir würden bei unserem Beispiel gerne 42 von 84 abziehen, so sähe das ganze wie in der folgenden Tabelle aus: Die ersten zwei Zeilen des jeweiligen Programms setzen RAM[11]=84 und RAM[22]=42, das Ergebnis wird wie oben in RAM[11] gespeichert. Die einzige Einschränkung bezüglich RAM-Setting ist, dass Werte nur in Speicherzellen geschrieben werden dürfen, welche eine höhere Nummer als die Anzahl an OP-Codes im Toy-Programm haben. Es wäre hier also nicht erlaubt gewesen, die Speicherzellen 0, 1 oder 2 zu beschreiben, da das Toy-Programm insgesamt 3 OP-Codes beinhaltet.
Binär | Hexadezimal | Assembler | Gemischt |
: 0000 0000 0000 1011 : 0000 0000 0101 0100 | : $00B : $054 | : 11 : 84 | : $00B : $054 |
: 0000 0000 0000 1011 : 0000 0000 0101 0100 | : $016 : $02A | : 22 : 42 | : 22 : 42 |
0001 0000 0000 1011 | $100B | LDA 11 | 0001 0000 0000 1011 |
0100 0000 0001 0110 | $4016 | SUB 22 | $4016 |
0000 0000 0000 1011 | $000B | STO 11 | STO 11 |
Endlosschleife: Um zu verdeutlichen, dass ein Prozessor niemals aufhört zu arbeiten, muss jedes Toy-Programm in einer Endlosschleife enden. Dies kann durch das Hinzufügen eines "ZRO" (= Setze den ACCU auf Null) und eines "BRZ <einen Befehl davor>" (= Springe zum Befehl davor, d.h. zu ZRO, falls der ACCU Null ist) am Ende des Toy-Programms erreicht werden.
Binär | Hexadezimal | Assembler | Gemischt |
: 0000 0000 0000 1011 : 0000 0000 0101 0100 | : $00B : $054 | : 11 : 84 | : $00B : $054 |
: 0000 0000 0000 1011 : 0000 0000 0101 0100 | : $016 : $02A | : 22 : 42 | : 22 : 42 |
0001 0000 0000 1011 | $100B | LDA 11 | 0001 0000 0000 1011 |
0100 0000 0001 0110 | $4016 | SUB 22 | $4016 |
0000 0000 0000 1011 | $000B | STO 11 | STO 11 |
1011 0000 0000 0000 | $B000 | ZRO | 1011 0000 0000 0000 |
0010 0000 0000 0011 | $2003 | BRZ 3 | $2003 |
Kommentare: Kommentare können mit "#" gesetzt werden. Wir kommentieren hier nun zur Veranschaulichung die Assembler-Variante unteres Toy-Programms - für die anderen Varianten funktioniert das Kommentieren analog:
Variablen: Im Assemblercode können anstatt RAM-Settings auch Variablen deklariert werden. Diese werden dann vom ToyProcessor automatisch in Speicherzellen nach den OP-Codes geschrieben. Variablen werden wie folgt deklariert: "<Variablenname> = <Wert>". Variablennamen dürfen aus Groß- und Kleinbuchstaben, sowie Zahlen bestehen, müssen jedoch mit einem Buchstaben beginnen und aus mindestens 3 Zeichen bestehen. Die zugewiesenen Werte dürfen Binär-, Dezimal- oder Hexadezimalzahlen sein. Sollten RAM-Settings und Variablendeklarationen gleichzeitig in einem Toy-Programm vorkommen, so ist darauf zu achten, dass die Variablen direkt hinter dem Programm abgelegt werden. Ist das Programm z.B. 3 Zeilen lang (Adresse 0-2) und man nutzt 2 Variablen, so ist der nächste freie Speicherbereich bei Adresse 5. Des Weiteren sollte der Assembler mit Variablen und später auch Labels nicht mehr mit binärem oder hexadezimalem Code gemischt werden. Sollte man dennoch mischen wollen, so ist auf den Speicherbereich der Variablen zu achten. Hier das obige Beispiel mit Variablendeklarationen anstatt den RAM-Settings:
Labels: Labels dienen als Anhaltspunkte, wohin ein Sprungbefehl im Code zurückkehren muss. Labels können also anstatt der RAM-Adresse des Befehls, zu dem zurückgesprungen werden soll, angegeben werden. Labels werden im Stil von: "<Labelname>:" deklariert. Labelnamen dürfen Groß- und Kleinbuchstaben und Zahlen enthalten, müssen aber auch mit einem Buchstaben beginnen und aus mindestens 3 Zeichen bestehen. Sollte man vorhaben, Code zu mischen (nicht empfehlenswert), so ist darauf zu achten, dass ein Label auf die Adresse direkt hinter dem Label zeigt, sprich die nächste Anweisung. Labels werden nicht nicht als Anweisung gezählt. Unsere Endlosschleife könnten wir mit Hilfe von Labels also wie folgt gestalten: