Computerprogramm und Programmiersprache
In dem Essay über Keller&Schleifen hatte ich - vor langer Zeit - versucht, einige Basisbegriffe um Computerprogramme und -programmierung wie Stack, Funktion etc. zu erklären, um dem Begriff der Rekursion näher zu rücken. Dieser Text ist in die Jahre gekommen und „klingt” mittlerweile reichlich komisch (was auch und gerade am sprachlichen Gestus liegt). Einige Grundbegriffe will ich noch einmal neu verhandeln, gerade auch, weil sie für eine kontruktivistische Sicht der Dinge ein hervorragendes Feld zum Erproben der Begriffe bieten.
Rolf Todesco schreibt:
Differenztheoretisch bezeichne ich als Computer-Programm eine "Difference" zwischen einem Text […] und einer Instanz des Programm-Objektes, das den schaltsinnmässigen Zustand des mit dem Programm gesteuerten Automaten bestimmt. Ein Computerprogramm ist differentiell ein spezieller Text.
Diese Definition geht von einem abstrakten Automaten aus, der zunächst als Black-Box erscheint, und durch die Instantiierung eines Programmtextes im Hauptspeicher gesteuert wird. Technisch gesehen, kann ich diese Abstraktion so stehen lassen, wobei aber einige interessante Übergänge verloren gehen.
Aus der Sicht des Programmierers ist ein Programm der Sourcecode, an dem er arbeitet. Das ist die textuelle Seite des Programms (dazu später mehr).
Für den Automaten spielt das keine Rolle, weil er nur aufgrund des aus dem Sourcecode generierten Binärcodes funktioniert.[1] Dieser binäre Code liegt als Programmdatei auf der Festplatte, und wird von einem Loader des Betriebssystems in den Hauptspeicher kopiert. Danach wird der Programmcounter des Prozessors auf den Beginn der Adresse des Codes im Speicher gesetzt. Ab dort wird der Speicher als Abfolge von Maschinenbefehlen interpretiert und abgearbeitet.[2] - Dabei findet man eine ganze Reihe rekursiver und selbstbezüglicher Eigenheiten.
Zunächst ist alles, was man auf einem Computer findet, immer nur Eines: Blöcke von Zahlen. Die Differenz zwischen den unterschiedlichen Datenformaten ist auf Maschinenebene völlig unerheblich - eine Textdatei, eine Bild-, Video-, Audio- oder auch Programmdatei sind in einem Editor, der sie als (hexadezimale oder binäre) Zahlen anzeigt, nicht unterscheidbar. Dasselbe gilt für den Unterschied zwischen Festplatte und Speicher: die Dateien, die man in das eine oder andere Medium kopiert, sind identisch (lediglich die Zugriffszeiten auf den Hauptspeicher sind deutlich kürzer als die auf die Festplatte).
Die entscheidende Differenz ist hier diejenige, die man von außen definiert und in das Computersystem als Programm hineinträgt: der Unterschied zwischen Daten und Programmen wird durch ein Programm gemacht.[3][4] Der Computer wird im Zweifelsfall versuchen, eine Foto-Datei als Programm auszuführen - es ist ein Programm, das die Informationen darüber enthält, an welchen Merkmalen man eine ausführbare Programmdatei erkennt (an den drei Zeichen am Ende des Dateinamens etwa), und entsprechend verfährt.
Innerhalb des Programmablaufs findet man diesen Unterschied als Differenz zwischen Daten und Anweisungen gleichsam gespiegelt wieder. Auch hier wird die Differenz dadurch deutlich, daß eine Anweisung erkennt, ob sie sich auf Daten bezieht, oder tatsächlich eine Anweisung im Sinne der Veränderung der Prozessorlogik darstellt. Der Prozessor „sieht sich” eine Zahl „an”, und „entscheidet”, was sie „bedeutet”. Er führt die Anweisung aus, der Programmcounter wird hochgezählt, und die nächste Zahl aus dem Speicher wird gelesen. Dabei gibt es neben jenen Anweisungen, die den Zustand des Prozessors selber verändern, solche, die Daten holen, oder diese verändern. Das kann wiederum selbstbezüglich geschehen: die Daten, die geholt oder verändert werden, können nicht nur von außerhalb, sondern sogar aus dem Programmcode selber stammen. Man kann ein Programm schreiben, das sich im Ablauf selber umprogrammiert (sog. selbstmodifizierende Programme - „gut” programmierte Viren bedienen sich dieser Technik). - Das ist nur ein knapper Überblick, der nicht den Anspruch hat, die Zusammenhänge komplett aufzurollen, sondern nur eine Ahnung vom Grad der Verzahnung zwischen Datenzustand und Programmlogik geben soll.
Der Unterschied zwischen Daten und Programmen wird von Programmen gemacht, was sich auf der Mikroebene des Prozessors wiederholt: der Unterschied zwischen Daten und Anweisungen wird durch Anweisungen vollzogen.
- [1] Dabei spielt es keine Rolle, ob das erst zur Laufzeit durch einen Interpreter geschieht, oder ob bereits im Vorfeld Binärcode von einem Compiler produziert wurde.
- [2] Zumindest ist dies dann der Fall, wenn man ein Compilat startet. Ein vom Interpreter gesteuertes Programm ist deutlich komplexer (und auch langsamer), weil immer wieder einzelne Schnipsel generiert und beim Prozessor angemeldet werden müssen.
- [3] Das erinnert mich unwillkürlich an Luhmann-Sprech: „Als Differenz ist die Differenz eine Einheit”.
- [4] Sehr aufschlußreich ist an dieser Stelle die Analyse des Bootvorgangs, den „ersten Schritten”, die ein Computersystem nach dem Einschalten macht, wenn noch kein Programm geladen ist, das irgendwelche Unterschiede machen könnte.