Skip navigation

ARES


Page Content:

Multitasking

(P)resümee

Wie auf der Seite Maschinensprache (Instruction Pointer, Multitasking) bereits erklärt wurde, verwendet der Prozessor Register, in denen gespeichert wird, an welcher Adresse der nächste Befehl zu finden ist. Darüberhinaus ist es nicht nur ein einzelnes Register, sondern gleich eine Liste - genannt "Task Queue". Daß bei Core War zwei getrennte Queues benutzt werden, ist für die Erklärungen auf dieser Seite nicht weiter von Bedeutung - am Ende solltest du diese Gegebenheit problemlos verstehen können - wir gehen vorerst davon aus, daß nur ein Programm geladen wird.

Task Queue mit nur einem Prozess

Bei den meisten bisher besprochenen Programmen gibt es nur einen einzelnen Eintrag in der Task Queue. Dieser Eintrag wird vor der Ausführung einer Instruktion in ein internes Prozessor-Register IP ("Instruction Pointer") kopiert, und der Eintrag aus der Queue entfernt (sie ist danach also leer). Dann wird die Instruktion, die sich an der Adresse IP im Core (IP = Zellennummer) befindet, in den Prozessor geladen, analysiert und, falls möglich, ausgeführt. In den meisten Fällen wird daraufhin das IP-Register um Eins erhöht und der neue Wert wird in die Task Queue zurückgeschrieben. Wenn im MARS nur ein Programm aktiv ist, dann beginnt diese Prozedur von vorne, nur wird diesmal der nächste Befehl ausgeführt.

Die Task Queue

funktioniert nach dem FIFO-PrinzipExternal Link, "First in - First out". Damit ist gemeint, daß Einträge von "oben" genommen, neue Einträge aber von unten "nachgeschoben" werden. Der erste Eintrag, der hineinkommt, kommt auch zuerst wieder hinaus. (Im Gegensatz zu FIFO, funktioniert ein Stapel Papier nach dem LIFO-PrinzipExternal Link, "Last In - First Out" - Dort wird das zuletzt hinzugefügte Blatt von oben als erstes wieder entfernt.) Wenn ein Progamm nun 2 Prozesse benutzt, dann befinden sich auch zwei Einträge in der Queue. Diese beiden Einträge tauschen effektiv ihre Plätze in jedem Zyklus. Bei mehreren Einträgen "rollt" die Liste nach oben.

Vor der Ausführung eines Befehls wird also der "topmost entry" aus der Task Queue extrahiert, während alle Elemente darunter nach oben "nachrutschen". Nach Verwendung dieses extrahierten Wertes als IP wird der IP+1 unten an die Queue angefügt. Diese Reihenfolge ist besonders wichtig, wenn du z. B. "Papers" schreiben möchtest, für andere Programme mag es nicht von Bedeutung sein, wie z. B. dem "Dual-Task-Scanner":

Dual-Task-Scanner

Zunächst möchte ich einen Core-Clear, der in zwei Richtungen gleichzeitig arbeitet, vorstellen:
  ;core clear in two directions
bomb
cptr DAT #4000, #4000 Ziel-Pointer für die Angriffe

cloop MOV bomb, >cptr Angriff via B-value, Post-Inkrement
MOV bomb, {cptr Angriff via A-value, Pre-Dekrement
JMP cloop
Die Adress Modes > und { funktionieren zum Teil genauso wie @: Sie benutzen den Wert der angesprochenen DAT-Zelle als Pointer für den Speicherzugriff mittels MOV. Zusätzlich wird der Wert des DAT vor/nach dem Zugriff verändert; > bewirkt, daß der B-Wert des DAT nach dem Zugriff um Eins vergrößert wird, wogegen { bewirkt, daß der A-Wert als Pointer benuzt und vor dem Zugriff um Eins verkleinert wird. Die Zahlen in dem DAT-Befehl verändern sich in jedem Schleifendurchlauf um Eins. Bei der erstmaligen Ausführung des JMP beinhaltet cptr die Werte #3999, #4001, dann #3998, #4002, usw. Dieses Programm schreibt also DAT-Bomben "um" die Position +4000 herum.

Der folgende Scanner "splittet" sich auf zwei Prozesse auf, wobei ein Prozess nach dem Gegner sucht, während der andere den doppelten "Core Clear" durchführt. Sobald der Scanner eine Zelle findet, in der nicht Null gespeichert ist, überträgt er diese Adresse in den DAT des Coreclear, damit dieser die entdeckte Stelle angreift:
         SPL     cloop             Neuen Prozess in die Task Queue eintragen

;scanner
sloop ADD #9, sptr sptr um 9 erhöhen
JMZ.F sloop, @sptr Befindet sich etwas an der Zieladresse?
found MOV sptr, cptr Ja: Adresse in den DAT des anderen Prozesses kopieren
MOV.ba sptr, cptr Ebenfalls in den A-value übertragen
ADD #100, sptr 100 Zellen dahinter weiterscannen
sptr JMP sloop, #1000 B-value ist frei und wird als "scan-pointer" benutzt

;core clear in two directions
bomb
cptr DAT #4000, #4000 Ziel-Pointer für die Angriffe

cloop MOV bomb, >cptr Angriff via B-value
MOV bomb, {cptr Angriff via A-value
JMP cloop

Papier und Seide

Papers sind Programme, die sich selbst replizieren. Das bedeutet, daß sie den eigenen Programmcode an eine andere Stelle des Speichers kopieren und dann dort hin springen. Silk-Style Papers sind besondere Replikatoren, die einen Trick benutzen, um besonders schnell zu laufen: Sie tragen die Adresse des neuen Prozesses schon vor dem Kopieren der eigentlichen Instruktionen in die Task Queue ein. Die Funktionsweise solltest du Schrittweise mit ARES beobachten, um zu begreifen, wie ein Silk funktioniert:
  boot  SPL   1             Zweiten Prozess erzeugen 

silk SPL +10, #0 Zweimal SPL +10
MOV >-1, }-1 Zwei Zellen kopieren
Dieses Programm funktioniert, weil die neuen Prozesseinträge unten an der Task Queue eingefügt werden! Hier ist also die Reihenfolge der Tasks wichtig. Damit dieses Programm nicht nur sich selbst kopieren, sondern auch weitere Befehle "mit sich führen" kann, müssen genausoviele Prozesse erzeugt werden, wie Instruktionen repliziert werden sollen:
  boot  SPL   2               Drei Prozesse erzeugen
SPL 1

silk SPL +10, #0 Dreimal SPL +10
MOV >-1, }-1 Drei Zellen kopieren
imp MOV imp, imp+1 Jede Kopie startet einen Imp
Wenn so ein Programm mit 4 oder mehr Prozessen arbeiten soll, dann ist das erzeugen der Prozesse etwas schwieriger, denn der erste SPL +10 Befehl darf erst ausgeführt werden, wenn bereits alle Prozesse erzeugt wurden. Viel Spaß beim Tüfteln!

Ein (englisches) Tutorial zu Silk und PaperExternal Link geht näher auf diese schon recht fortgeschrittene Programmiertechnik ein.

Kampfprogramme

Content Management:

μCMS α1.6