Skip navigation

ARES


Page Content:

Schleifen und Bedingungen

Programmschleifen

Eine immer wieder anzutreffende Programmiertechnik ist das Bilden von sogenannten Programmschleifen. Damit ist gemeint, daß ein Teil des Programmes immer wieder ausgeführt wird. Am Ende der Schleife ist normalerweise ein Befehl zum Sprung an den Anfang zu finden. Ein (eher sinnloses) Beispiel ist das folgende Codefragment; es addiert den Wert 5 zu einer "Variablen", ohne jemals damit aufzuhören (Man spricht von einer Endlosschleife):
  ADD   #5,   +2    Addiere 5 zu dem Wert, der in dem DAT gespeichert ist
JMP -1 Nächster Befehl soll wieder der ADD sein
DAT #0 Platzhalter, "Variable"

Sprungmarken

Damit man nicht ständig mit den reinen Zahlen arbeiten muß, darf man den einzelnen Anweisungen Namen ("Labels") geben. Dadurch wird der Programmcode besser lesbar, und man kann leicht weitere Befehle einfügen, ohne die Zahlen von Hand anpassen zu müssen. Das obige Beispiel sieht mit Labels (Sprungmarken) wie folgt aus:
  loop  ADD   #5,   A   Addiere den Wert 5
JMP loop Nächster Befehl soll wieder der ADD sein
A DAT #0 Platzhalter, "Variable"
In BASIC würde man dieses Programm so schreiben:
  10 LET A = 0 
20 LET A = A + 5
30 GOTO 20
und in JavaScript:
  var A = 0;      Variable deklarieren und mit 0 vorbelegen

while (true) Wiederholen, solange der Ausdruck "Wahr" ergibt (Endlosschleife)
{
A += 5; Inhalt der Variable um 5 erhöhen
}

Bedingte Sprünge

Damit man einem Programm "Intelligenz" einhauchen kann, muß man ihm die Fähigkeit verleihen, Entscheidungen zu treffen. Dazu muß man angeben, was geprüft werden soll, und was bei einem entsprechenden Ergebnis geschehen soll. Normalerweise sind das Programmsprünge, wie mit JMP, die an eine Bedingung geknüpft werden. Redcode kenn z. B. den Befehl JMN ("Jump if Non-Zero"), der wie ein gewöhnlicher JMP funktioniert, jedoch nur, wenn der zweite Wert, den man angeben muß, Null ist. Das folgende Programm durchläuft die Schleife zehn mal, bevor das Programm fortgesetzt wird:
  loop        SUB   #5,   countdown    Zähler um 5 verkleinern
JMN loop, countdown Mit Null vergleichen. Sprung bei Nicht-Null
... Fortsetzung
countdown DAT #50
Dieses Programm würde in BASIC so geschrieben werden:
  10 LET A = 50 
20 A = A - 5
30 IF A <> 0 THEN GOTO 20
40 ...
und in Pascal:
  var A : integer = 50;    Ganzzahlige Variable deklarieren und mit 50 vorbelegen

repeat
A := A - 5; Inhalt der Variable um 5 verringern
until (A = 0); Wiederholen, solange A ungleich 0 ist
...
Der Befehl JMZ ist nur in bestimmten Fällen einsetzbar. In manchen Fällen wird man den Befehl CMP (Compare) benutzen wollen. Der Erweiterte Befehlssatz von pmars erlaubt eine andere Schreibweise für diesen Befehl, nämlich SEQ (Skip on Equal). SEQ beschreibt etwas besser, wie der Befehl funktioniert: Zuerst wird ein Vergleich durchgeführt. Waren die verglichenen Werte identisch, dann wird der nächste Befehl übersprungen. Waren die Werte ungleich, wird nichts übersprungen - der Befehl hat einfach keinen weitern Effekt:
  start     CMP   A,   B      Nächsten Befehl überspringen, wenn a = b
skipequal JMP differs
JMP wasequal
A DAT #a Die Zahlen in diesen beiden DAT-...
B DAT #b ...-Instruktionen werden verglichen

differs ... do this, if a ≠ b

wasequal ... do this, if a = b
In JavaScript würde man das so anschreiben:
  if (A == B) 
{
// do this, if A = B
}
else
{
// do that, if A ≠ B
}
Das Countdown-Beispiel von oben kann man natürlich auch mit CMP programmieren. In diesem Fall ist die Verwendung von CMP allerdings nicht sinnvoll, weil das Programm daurch einen Befehl länger ist und entsprechend mehr Rechenzeit verbraucht:
  loop    SUB   #5,   A       Wert in A um 5 verkleinern
CMP A, #0 Nächsten Befehl überspringen, wenn 0
skip JMP loop Ungleich: Schleife wiederholen
exit ... Fortsetzung hier nach 30 Zyklen
A DAT #50
Warum sind es 30 Zyklen?

Redcode bietet noch weitere bedingte Sprungbefehle: JMZ (Jump if Zero) und SLT (Skip less than). Diese beiden Befehle sollten inzwischen selbsterklärend sein, sie funktionieren analog zu den Befehlen JMN bzw. SEQ. Im ICWS-94 Draft ist noch ein besonderer bedingter Sprungbefehle definiert: DJN (Decrement and Jump, if NOT Zero). Zuerst wird die zu prüfende Zahl um eins verkleinert (dekrementiert), und dann auf Null getestet. DJN funktioniert quasi wie die Befehle SUB #1, A und JMN loop, A in Kombination. Ein Beispiel wird es klar machen:
  loop   ...                Inhalt der Schleife
DJN loop, A A vermindern und auf Null prüfen
... Wurde A = 0, dann gehts hier weiter
A DAT #a
Mit DJN kann man sehr schön und einfach festlegen, wie oft eine Schleife durchlaufen werden soll. Es ist sogar möglich, den Wert a direkt in dem DJN-Befehl abzulegen, indem man nicht, wie oben, eine relative Adresse angibt, sondern eine unmittelbare:
  DJN   loop,   #10    10 Mal nach loop springen

Mathematik

Content Management:

μCMS α1.6