Die Geschichte von Mel

Aus: usenet: utastro!nather, May 21, 1983.

Ein weiterer Artikel zur *Macho*artigkeit der Programmierung, ein klarer und ungeschminkter Text:

Real Programmers schreiben in FORTRAN.

Heute, in einer Zeit des light Biers, der Taschenrechner und der “benutzerfreundlichen” Programmierung, mag es anders sein, aber in den guten alten Tage, als der Begriff “Software” sich noch seltsam anhörte und echte Computer noch aus Trommeln und Vakuumröhren bestanden, da schrieben echte Programmierer Maschinenkode. Kein FORTRAN, kein RATFOR, nicht einmal Assembler. Maschinenkode, rohe, ungeschmückte, unverständliche hexadezimale Zahlen. Direkt!

Eine ganze Generation von Programmierern ist nun groß geworden, die diese phantastische Vergangenheit vergessen hat. Ich fühle mich verpfichtet dieses Vergessen zu verhindern und kann das am besten, indem ich beschreibe, wie ein echter Programmierer Kode schrieb. Ich nenne ihn Mel, denn das war sein Name.

Ich traf Mel das erste Mal, als ich begann für die Royal McBee Computer Corp. zu arbeiten, eine mittlerweile aufgegeben Abteilung der Schreibmaschinenfirma. Sie stellte damals den LGP-30 her, ein kleiner, billiger (nach damaligen Maßstäben) Trommelspeichercomputer und hatten gerade angefangen den RPC-4000, ein stark verbesserten, größeren und schnellerer -- Trommelspeichercomputer herzustellen. Dieser Rechner war trotz allem zu teuer und schlecht (Weswegen man heute weder den Rechner noch die Firma mehr kennt).

Ich war angestellt, um einen Fortrancompiler für diesen Rechner zu schreiben und Mel sollte mich in die Wunder des Computers einführen. Mel hielt nichts von Compilern.

“Wenn ein Programm seinen eigenen Kode nicht ändern kann,” fragte er mich, “Wozu ist es dann gut?”

Mel hatte, hexadezimal, das bekannteste Programm geschrieben, das der Firma gehöhrte. Es lief auf der LGP-30 und spiele mit potentiellen Kunden auf Computershows Black Jack. Der Effekt war immer dramatisch: Die LGP-30 Bude wurde auf jeder Show aufgebaut und die Händler von IBM standen darum und unterhielten sich mit dem Programm. Ob diese Aktion jemals dazu führte, dass Computer verkauft wurden, war nie Gegenstand unserer Diskussionen.

Mels Job bestand nun darin, dass er das Black Jack Programm für die RPC-4000 Maschine neu schreiben sollte (Portierung, was ist das?). Der neue Computer hatte ein Eins-Plus-Eins Adressschema, bei der jede Maschinenanweisung neben der Kodierung des Befehls und den Adressen für die Operanden auch noch eine weitere Adresse besass, die angab, wo innerhalb des Trommelspeichers sich der nächste Befehl befand. In modernen Worten folgte jeder Einzelanweisung ein GO TO! (Mach DAS mal in Pascal!)

Mel liebte die RPC-4000, denn er konnte seinen Kode optimieren. Dies bedeutete, dass er die Befehle so im Trommelspeicher plazierte, dass immer dann, wenn eine abgearbeitet war, die nächste sofort an der Position des Lesekopfes stand und direkt ausgeführt werden konnte. Es gab dafür zwar ein Programm, ein &dlquo;optimierender Assembler&drquo;, aber Mel vermied es damit zu arbeiten.

“Du weißt nie, wo dies Programm die Daten hinlegt”, erklährte er, &dlquo;du brauchst daher seperate Konstanten.”

Es brauchte einige Zeit, bis ich diese Bemerkung verstand. Da Mel alle numerischen Äquivalente des Befehlskodes auswendig kannte und er ihnen selber die Adresse in der Trommel gegeben hatte, konnte er diesen Befehlskode an anderer Stelle als numerische Konstante nutzen. Er konnte also z.B. eine Additionsinstruktion später dazu nutzen, dass damit multipliziert wurde, wenn sie denn den richtigen numerischen Wert hatte. Sein Kode war für andere nur sehr schwer zu ändern.

Ich verglich Mels handoptimierte Programme mit dem Kode, den der optimierende Assembler herausgab; Mels Programm liefen immer schneller. Das lag daran, dass es das “Top-Down”-Modell in der Programmierung noch ncith gab und Mel es auch nicht genutzt hätte. Er schrieb immer die innersten Teile seines Programms zuerst, damit er ihnen den optimalen Platz in der Trommel anweisen konnte. Der optimierende Assembler war dazu natürlich nicht smart genug.

Mel schrieb nie Loops, um einige Zeit vergehen zu lassen, auch dann nicht, wenn der dumme Drucker einfach etwas Zeit zwischen den Buchstaben, die er drucken sollte, brauchte. Statt dessen plazierte er die Instruktion, die als nächste bearbeitet werden sollte so im Trommelspeicher, dass der Lesekopf gerade daran vorbei war, wenn sie gebraucht wurde. Die Trommel musste dann eine komplette Umdrehung machen, bevor sie wieder zu der Instruktion kam. Er erfand herrliche Ausdrücke für dieses Vorgehen. Obwohl Begriffe wie “Optimum” eigentlich ein absoluter Begriff ist, wie z.B. auch “Einzig” wurde es allgemeine sprachliche Praxis diesen Begriff relativ zu gebrauchen. “Nicht ganz Optimum” oder “Suboptimum” oder “Nicht sehr Optimum”. Mel nannte die Positionen mit dem größten Zeitverbrauch in der Trommel “Höchstes Pessimum”

Nachdem das Black-Jack-Programm fertig war und es auch lief (“Sogar die Initialisierungsroutine ist optimiert”, sagte er stolz) kam vom Marketing ein Änderungswunsch. Das Programm nutzte einen eleganten (optimierten) Algorithmus zur Erzeugung von Zufallszahlen, um die Karten zu mischen und vom Deck auszuteilen. Manche aus der Marketingabteilung meinten nun, das Programm sei zu fair, da manchmal auch der Kunde verlor. Sie wollten, dass Mel das Programm so modifizierte, dass es mit einer Eingabe an der Konsole so geändert werden konnte, dass sich die Chancen verschoben und der Kunde gewann.

Mel stutzte. Er fühlte, dass dies in höchstem Maße unehrenhaft und, wenn er es umsetzen würde, seiner persönlichen Integrität als Programmierer abträglich sein würde. Er lehnte also ab. Der Chef der Marketingabteilung sprach mit Mel und markierte den gorßen Boss. Schließlich gab Mel nach und willigte ein den Kode zu ändern. Allerdings drehte er die Sache herum. Jedesmal, wenn nun der Kopf betätigt wurde, änderte das Programm die Vorgehensweise und gewann immer! Mel freute sich darüber und nannte sein Vorgehen in höchsten Maße ethisch und lehnte es kathegorisch ab es wieder zu ändern.

Nachdem Mel die Firma verlassen musste, sprach mich der Big Boss an und fragte mich, ob ich mir den Kode ansehen könne, den Test finden könne und ihn so umbauen, dass er in gewünschter Art und Weise lief. Etwas widerwillig versprach ich mir die Sache anzusehen. Das Nachvollziehen von Mels Kode wurde ein Abenteuer.

Ich habe des öfteren gefühlt, dass Programmieren eine Ausdrucksform ist, deren wahrer Wert nur dann erkannt werden kann, wenn jemand von der gleichen Art sich damit beschäftigt. Es gibt liebliche Lösungen und brilliante Coups, die versteckt vor meschlichen Augen und der Administration, ihr Dasein fristen; versteckt alleine durch die Natur der Sache. Man kann viel über ein Individuum lernen, wenn man sich seinen Kode ansieht, auch wenn er hexadezimal ist. Mel war meiner Meinung nach ein verkanntes Genie.

Den wohl grössten Schock bekam ich, als ich eine Schleife ohne Test fand. Gar keinen Test. Überhaupt keinen. Der gesunde Menschenverstand sagte mir, dass es sich um eine Endlosschleife handeln musste. Ein Programmteil, in dem der Computer für immer um sich selbst drehen musste. Die Programmkontrolle führte auch in diese Schleife hinein, aber eben auch genau so wieder hinaus. Ich brauchte zwei Wochen, um zu verstehen, wie Mel das gemacht hatte.

Der RPC-4000 hatte ein relativ modernes Feature, ein sogenanntes Indexregister. Es erlaubte dem Programmierer eine Programmschleife zu schreiben, das eine indizierte Instruktion beinhaltete. Bei jedem Schleifendurchlauf wurde der Inhalt des Indexregisters zu der Adresse des Befehls addiert, so dass so eine ganze Reihe von Daten abgearbeitet werden konnte. Man musste nur das Indexregister bei jedem Durchlauf entsprechend erhöhen. Mel nutzte das nie!

Statt dessen lud er die Instruktion in ein CPU-Register, addierte Eins und schrieb es wieder zurück. Dann lies er den modifizierten Befehl im CPU-Register ausführen. Die Schleife war so geschrieben, dass die zusätzliche Zeit berücksichtigt worden war und nach Beendigung dieses Befehls sich der nächste sofort unter dem Lesekopf des Trommelspeichers befand. Aber immer noch hatte ich keinen Test in der Schleife gefunden.

Der entscheidende Schritt kam, als ich sah, dass das Indexregisterbit, das zwischen Befehl und Adresse stand, auf 1 gesetzt war. Aber Mel nutzte das Indexregister doch gar nicht und ließ es immer auf Null. Als ich erkannte, was er gemacht hatte, war es, als wenn das Licht der Erkenntnis mich fast blendete.

Er hatte die Daten am oberen Ende des Speichers positioniert, an den grössten Adressen, welche die Maschine ansprechen konnte. Nachdem nun das letzte Datum abgearbeitet war, erzeugte die erneute Addition einen Overflow und änderte damit den Befehlsteil des Registers in einen Sprungbefehl. Dazu musste er nur sicherstellen, dass der nächste Befehl an der Adresse Null stand.

Ich bin mit Mel nicht in Kontakt geblieben und ich weiß daher auch nicht, ob er die Veränderungen, die der Programmierung seit diesen Tagen widerfahren sind, mitgemacht hat. Ich bevorzuge mir vorzustellen, dass dies nicht der Fall ist. Auf jeden Fall, war ich damals so überzeugt von seiner Arbeit, dass ich dem Boss sagte, dass ich den Test nicht finden kann. Er erschien nicht sonderlich überrascht.

Als ich die Firma verließ arbeitete das Black-Jack-Programm jedenfalls immer noch so, dass es gewann, wenn man die entsprechende Taste drückte.