Erweiterte DCPU-16 ASM Programmierung

Thema heute:

Erweiterte DCPU-16 ASM Programmierung

Bisher haben wir nur ein einfaches, lineares Programm geschrieben, was ein paar Werte zuweist…
Für ein HelloWorld mag es genügen, ambitionierte Programmierer werden aber sicherlich etwas komplexere Strukturen missen.
Wirklich komplex wird es heute (noch) nicht (für alle), da ich die Tutorials zur DCPU-16 aber auch für leute Schreibe, die sich sonst nicht sehr viel mit Programmierung Beschäftigen, gehen wir Schrittweise vor.

Wir werden zunächst den kompletten Befehlssatz der DCPU-16 kennen lernen:

Basic opcodes: (4 bits)
0x0: non-basic instruction - see below
0x1: SET a, b - sets a to b
0x2: ADD a, b - sets a to a+b, sets O to 0x0001 if there's an overflow, 0x0 otherwise
0x3: SUB a, b - sets a to a-b, sets O to 0xffff if there's an underflow, 0x0 otherwise
0x4: MUL a, b - sets a to a*b, sets O to ((a*b)>>16)&0xffff
0x5: DIV a, b - sets a to a/b, sets O to ((a<<16)/b)&0xffff. if b==0, sets a and O to 0 instead.
0x6: MOD a, b - sets a to a%b. if b==0, sets a to 0 instead.
0x7: SHL a, b - sets a to a<<b, sets O to ((a<<b)>>16)&0xffff
0x8: SHR a, b - sets a to a>>b, sets O to ((a<<16)>>b)&0xffff
0x9: AND a, b - sets a to a&b
0xa: BOR a, b - sets a to a|b
0xb: XOR a, b - sets a to a^b
0xc: IFE a, b - performs next instruction only if a==b
0xd: IFN a, b - performs next instruction only if a!=b
0xe: IFG a, b - performs next instruction only if a>b
0xf: IFB a, b - performs next instruction only if (a&b)!=0

SET kennen wir schon: es weist A den wert B zu.
ADD addiert, SUB subtrahiert, MUL multipliziert und DIV dividiert.
MOD ist der Modulo, welchen wir schon aus „Grundlagen zum Dualsysten (Binärsystem)“ kennen.
SHL, SHR, AND, BOW, XOR sind logische Bitoperatoren (Shift Left/Right, AND, OR, XOR)
IFE prüft auf Gleichheit, IFN prüft auf Ungleichheit, IFG prüft ob a>b, IFB prüft Werte auf 0

Die While-Schleife

Mit diesen Operatoren sind wir in der Lage, verschiedene Lösungen zu realisieren.
So können wir etwa eine While-Schleife nur durch Wahrheitsabfragen und Sprüngen realisieren:

while(A<5)
{
A++;
}

Die Schleife lässt sich rein logisch auch folgendermaßen beschreiben:

Abfrage: Ist A kleiner als 5? <=> Ist 5 größer als A?
Ja: A++, Gehe zur Abfrage
Nein: Fortfahren

Dieses Beispiel mag vielleicht banal sein, zeigt aber sehr gut, wie nun der entsprechende Assembler Code aussehen kann:

:ABFRAGE IFG 5, A
SET PC, JA
SET PC, NEIN
:JA ADD A, 1
SET PC, ABFRAGE
:NEIN SET PC, 0xFF

Erklärung:

Wir wissen bereits, dass das Register PC immer auf die Adresse des Befehls zeigt, welcher als nächstes ausgeführt wird.
Eine Abfrage funktioniert so: Ist die Bedingung erfüllt (true), wird der Befehl direkt nach der Abfrage ausgeführt (PC + 1).
Ist die Bedingung nicht erfüllt (false), wird der zweite Befehl nach der Abfrage ausgeführt (PC + 2).
Wir können PC auch im laufenden Programm manipulieren, und dem Programm so sagen, was es als nächstes tun soll. Das erlaubt es uns, den Programmcode nicht nur linear von oben nach unten abzuarbeiten, sondern an verschiedene Stellen zu springen.
Diese Stellen können wir ganz einfach mit Labels kennzeichnen. :NAME deklariert ein solches Label, im Programm verweist die Konstante NAME nun auf die Adresse, die durch die Deklaration festgelegt wurde.
Keine Angst, es hört sich vielleicht kompliziert an, aber es ist sehr Simpel:
Beispiel: Anstatt zu sagen „Gehe zur 0x028f-sten Straße“, sagen wir „Gehe zur NAME Straße“.
Das hat den Vorteil, dass man sich keine komplexen Zahlen merken muss. Außerdem könnte ja inzwischen eine neue Straße gebaut werden, wodurch sich die Nummern aller folgenden Straßen ändern.
Man muss nur wissen, „wo“ die Straße ist. Und das erledigt der Assembler für uns. Wird der Programmcode Assembliert, legt der Assembler fest, welche Adresse jedes Label hat. Er ist quasi „das GPS“ welches im Programm bekannt gibt, wo welche Straße (welches Label) ist.
Wir könnten natürlich auch direkt auf die Adresse Verweisen, jedoch wird der Code durch Labels viel übersichtlicher, erklärbar, und somit besser lesbar.

Dieses Beispiel könntet ihr auch auf dcpubin.com assemblieren und durchlaufen lassen, A wird bis 5 hochgezählt.

For-Schleife

Die For-Schleife ist fast das gleiche wie eine While-Schleife, mit einer Ausnahme: Die Laufvariable. Das können wir am obrigen Beispiel sehr gut erkennen. Man könnte den Code auch so ausdrücken:

for(A=0;A<5;A++);

Hier wird auch nur die Laufvariable A bis 5 hochgezählt. Es gibt jedoch feine Unterschiede:
Das Hochzählen (manipulieren) der Laufvariable ist eine unabhängige Funktion. Egal was im Körper der Schleife getan wird, am Ende wird immer die Anweisung im Schleifenkopf ausgeführt.
Beispiel:

for(A=0;A<5;A++){
B = B * A;
}

Als ASM Code könnte das so aussehen:

SET B, 1
SET A, 0
:KOPFPRF IFG 5, A
SET PC, KOERPER
SET PC, 0xFF
:KOERPER MUL B, A
SET PC, KOPFFKT
:KOPFFKT ADD A, 1
SET PC, KOPFPRF

Erklärung:

Befehl(e) Bedeutung
SET B, 1 A immer mit 0 Multiplizieren macht wenig Sinn
SET A, 0 A=0 (Deklaration der Laufvariable im Schleifenkopf)
:KOPFPRF IFG 5, A
SET PC, KOERPER
SET PC, 0xFF
Prüfanweisung im Schleifenkopf: Ist A<5, wird mit dem Schleifenkörpfer fortgefahren, ist A>=5, wird die Schleife beendet
:KOERPER MUL B, A
SET PC, KOPFFKT
Funktion des Schleifenkörpers: B = B*A, danach wird mit der Zählervariablenmanipulation (Schleifenkopf) fortgefahren
:KOPFFKT ADD A, 1
SET PC, KOPFPRF
Manipulation der Zählervariable: A++, Danach wird mit der Prüfanweisung im Schleifenkopf fortgefahren

Es wird schon etwas komplexer. Ist man mit dem Verhalten einer For-Schleife bekannt, ist dies aber auch keine Hexerei:
Als erstes wird die Laufvariable A definiert
Es wird Geprüft, ob A<5 ist
Falls ja: Schleifenkörper ausführen, Laufvariable manipuliert, zur Prüfung springen.
Falls nein, wird die Schleife beendet.

Heute haben wir einiges geschafft

Wir beherrschen die arithmetischen Funktionen
Wir können Werte Vergleichen
Wir können zu verschiedenen Anweisungen springen (Funktionen)
All das ermöglicht es uns, Schleifen zu bilden!

Ich belasse es heute dabei, es liegt nun an euch, den Stoff zu lernen.
Ja, leider fällt nur sehr wenigen Menschen das Wissen in die Wiege, der Rest muss in den sauren Apfel beißen und Lernen. Sonst wird das nichts.

Ihr könnt gerne folgendes Programm von mir analysieren und nachbauen:
http://www.dcpubin.com/pe0hs20W1
(Der Name verrät ja schon einiges, außerdem habe ich Kommentare hinzugefügt).
Sehr sehr gerne könnt ihr auch eure eigenen Programme hier in die Kommentare posten. Egal welches Programm, postet es, Feedback ist immer gut!

Viel Spaß mit dem neu erlernten Wissen.
MfG
Damon

Dieser Eintrag wurde veröffentlicht in 0x10c und getagged , , .
Bookmarken: Permanent-Link Schreibe einen Kommentar oder hinterlasse einen Trackback: Trackback-URL.
Achtung: Wordpress interpretiert bestimmte Zeichenfolgen als Markup und verändert diese. Nutzt für Programmcode lieber Gist oder PasteBin-Services und verlinkt die Code-Schnipsel.

Post a Comment

Ihre E-Mail wird niemals veröffentlicht oder verteilt. Benötigte Felder sind mit * markiert

*
*

Du kannst diese HTML Tags und Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>