un

guest
1 / ?
back to lessons

Programmieren in absoluter Binärcode

Die ersten Programmierer schrieben in absoluter Binärcode: Jede Anweisung und jede Adresse in rohen Binärdigits. Eine einzelne Anweisung könnte wie 01100101 00001010 - Anweisungscode und Speicheradresse in Binär aussehen.

Das Spaghetticode-Problem

Wenn ein Fehler eine neue Anweisung erforderte, standen die Programmierer vor einem Dilemma. Einfügen an der Stelle bedeutete, dass jede folgende Anweisungsadresse um eine Einheit verschoben wurde - was bedeutete, dass der Programmierer alle Adressbezugs in der gesamten Anwendung aktualisieren musste. Katastrophal.

Die Lösung: Ersetzen Sie die Anweisung direkt vor der Einfärbungspunkt mit einem Sprung auf leeren Speicher. An dieser leeren Stelle: Schreiben Sie die überschriebene Anweisung, fügen Sie die neuen Anweisungen hinzu und springen Sie zurück. Wenn Fehler im Korrekturmodus auftraten, wenden Sie denselben Trick erneut an, indem Sie anderen leeren Speicher verwenden.

Ergebnis: Der Ausführungspfad durch die Anwendung sprang zu scheinbar zufälligen Speicherbereichen. Hamming nannte dies "einen Topf Spaghetti." Der Steuereingangspfad, der auf Papier gezeichnet wurde, sah genau wie verknäultes Spaghetti aus.

Die Fluchtrouten

Zwei unmittelbare Verbesserungen: Oktal-Notation (Gruppierung der Binärdigits in Gruppen von 3) und Hexadezimal (Gruppierung von 4, wobei A-F für Werte über 9 verwendet werden). Diese reduzierten die Fehler beim Schreiben, lösten aber das grundlegende Adressproblem nicht.

Symbolische Assemblage (z.B. IBMs SAP - Symbolic Assembly Program - und SOAP - Symbolic Optimizing Assembly Program auf dem IBM 650) ermöglichte es den Programmierern, Anweisungsnamen (ADD, MOVE) und symbolische Adressbezeichner statt Binär zu verwenden. Der Assembler übersetzte in Binär bei Eingabezeit, verwaltete automatisch die Adresszuweisungen.

SOAP führte außerdem eine zusätzliche Optimierung durch: Es ordnete Anweisungen auf dem rotierenden Trommel so an, dass die nächste Anweisung direkt beim Lesekopf ankam, sobald die vorherige abgeschlossen war - Mindestlatenz-Coding. SOAP kompilierte sich sogar selbst: Programm A wurde als Daten verarbeitet, um B zu erzeugen, B wurde mit A ausgeführt, um zu messen, wie sich die Selbstkompilierung verbesserte.

Parse Tree & Language Hierarchy

Bibliotheken und umlegbare Code

Hamming stellte fest, dass die Idee von wiederverwendbarem Software (mathematische Bibliotheken) sehr früh kam - Babbage hatte sie konzipiert. Das Problem: Eine absolutadressierte Bibliothek erforderte, dass jede Routine immer die gleichen Speicherplätze belegt. Wenn die gesamte Bibliothek zu groß wurde, konkurrierten Programme um die gleichen Adressen.

Die Lösung: verlegbare Code. Der Assembler generiert Anweisungen, die den Speicher relativ beziehen - Abstände von einer Basisadresse - anstelle absoluter Adressen. Ein Linker löst die endgültigen Adressen bei der Ladenzeit.

Von Neumanns unveröffentlichte Berichte (weit verbreitet) beschrieben die notwendigen Programmiertricks. Das erste veröffentlichte Programmierbuch (Wilkes, Wheeler & Gill, EDSAC, 1951) kodifizierte diese Techniken.

Erkläre, warum absolutadressierte Bibliotheken ein Skalierungsproblem schufen und wie umlegbarer Code dies löste. Welche spezifische Eigenschaft von absoluten Adressen führte zum Kollisionsproblem und was bedeutet "umlegbar" technisch?

Die Sprachdesign-Gabel

FORTRAN (1957, IBM) und ALGOL (1958, internationale Komitee) repräsentieren zwei Designphilosophien, die radikal unterschiedliche Ergebnisse hervorbrachten.

FORTRAN

John Backus leitete das FORTRAN (FORmula TRANslation)-Projekt bei IBM. Das Designziel: Die Sprache so einfach für Wissenschaftler und Ingenieure zu verwenden. FORTRAN akzeptierte mathematische Notation, die für seine Benutzer natürlich fühlte: A = B + C * D anstelle von ADD B, C; STORE T; MULTIPLY T, D; STORE A.

FORTRAN hat 60+ Jahre überdauert. Es wird weiterhin in der wissenschaftlichen Berechnung, der Fluidynamik, dem Klimamodellierung und der computacionalen Physik eingesetzt. Hamming betrachtete diese Haltbarkeit als Beweis eines erfolgreichen Designs.

ALGOL

ALGOL (ALGOrithmic Language) wurde von einem Komitee von Logikern und Computeringenieuren entwickelt, die nach mathematischer Strenge strebten: ein logisch sauberes, formell definierbares Sprach. Die Backus-Naur-Form (BNF) zur Beschreibung von Grammatiken wurde zur Spezifikation von ALGOL erfunden.

ALGOL ist in der Praxis gescheitert. Trotz seiner logischen Eleganz und seiner immensen Einfluss auf die nachfolgende Sprachentwicklung (Pascal, C und fast jedes moderne Sprach basiert auf den Grammatikkonzepten von ALGOL) wurde ALGOL selbst nie weit verbreitet. Hamming's Urteil: logisch entworfen, menschenunzugänglich.

Die Hierarchie der Sprachen

Hamming beschrieb eine natürliche Hierarchie von Maschinensprache über Assembler, höherstufige Sprachen und letztendlich eine 'problemorientierte Sprache', die nahe an die Art und Weise der Betrachtung des Problemgebiets der Praktiker ist. Jeder Level fügt Lesbarkeit für den Menschen hinzu, wobei die Effizienz für die Maschine verloren geht.

Hamming's Vier Kriterien für die Sprachentwicklung

Hamming zog aus dem Vergleich von FORTRAN und ALGOL vier Kriterien für ein erfolgreiches Programmiersprachen ab:

1. Leicht zu lernen - Ein Anfänger kann schnell produktiv werden

2. Leicht zu verwenden - Routinetätigkeiten erfordern keine Zeremonie

3. Leicht zu debuggen - Fehler erzeugen sinnvolle, lokalisierbare Nachrichten

4. Leicht zur Verwendung von Unterprogrammen - Wiederverwendung und Abstraktion erfordern keine heldenhafte Anstrengung

Er fügte eine strukturelle Beobachtung hinzu: Die menschliche Sprache enthält etwa 60% Redundanz; die Schriftsprache etwa 40%. Sprachen mit geringer Redundanz (wie APL) erzeugen elegante Einzeiler, die Experten schön finden und Anfänger dunkel finden - und die versteckten Fehler enthalten, wenn eine einzelne Zeichenbedeutung verändert wird.

Die Implikation: Eine Sprache, die für logische Eleganz entworfen ist, optimiert die falsche Leserin. Der Programmierer ist ein Mensch; Menschen benötigen Redundanz, um Fehler zu erkennen und Absichten zu kommunizieren.

Wenden Sie Hamming's vier Kriterien auf eine Programmiersprache an, die Sie gut kennen. Bewerten Sie jedes Kriterium 1-5 (5 = ausgezeichnet). Identifizieren Sie dann das Kriterium, das am besten verbessert würde - und erklären Sie, was eine bestimmte Änderung aussehen würde.

Psychologische vs. logische Programmiersprachen-Designs

Hamming kehrte zum FORTRAN/ALGOL-Gegensatz als Lektion in institutionelle und menschliche Dynamik zurück, nicht nur in der Sprachdesign.

FORTRAN wurde psychologisch entworfen - für die Menschen, die es verwenden würden, insbesondere Wissenschaftler, die in mathematischer Notation dachten. ALGOL wurde logisch entworfen - für formelle Korrektheit und theoretische Eleganz.

Das Paradox, das Hamming identifizierte: eine logisch korrekte Sprache, die von Menschen abgelehnt wird, scheitert; eine pragmatisch entworfene Sprache, die von Menschen angenommen wird, hat Erfolg, selbst wenn sie logisch verworren ist.

Er nannte APL als das extreme Beispiel: logisch elegant, in einer Zeile ausdrückbar, mit einem eigenen Satz von Sonderzeichen. Experten liebten es. Normale Programmierer fanden es unleserlich. Eine einzelne Zeichenänderung konnte die Bedeutung eines Programms stillschweigend verändern. APL hat eine kleine, treue Gemeinde und praktisch keinen breitenwirksamen Einsatz.

Die menschliche Redundanzargument: Sprechsprache ist etwa 60% redundant (wiederholte Kontexte, klärende Wörter, vorhersehbare Struktur). Schriftsprache etwa 40% redundant. Diese Redundanz dient der Fehlererkennung - Menschen sind unzuverlässig, daher hat sich die Sprache entwickelt, um genügend wiederholte Informationen zu tragen, um Fehler zu erkennen und zu korrigieren. Eine niedrig-redundante Sprache entfernt diesen Sicherheitsnetz.

Die Compiler-Hierarchie

Hamming beschrieb die Schichten von Compilern/Interpretern: Ein Programm kann eine höherstufige Sprache lesen und sie in eine niedrigerstufige umwandeln. Stapeln Sie diese Schichten - jede übersetzt eine Ebene tiefer. Am oberen Ende: Eine domänenbezogene Sprache, die Experten in einem Bereich (Biologie, Finanzen, Physik) natürlich schreiben. Am unteren Ende: Maschinencode. Jede Übergangsphase ist ein Compiler oder Interpreter.

Vorhersage der Sprachüberlebensdauer

Bis 1993 hatte Hamming viele Sprachen beobachtet, die erfolgreich waren und scheiterten. FORTRAN (1957) überlebte. ALGOL (1958) scheiterte. COBOL (1959) überlebte Jahrzehnte im Geschäftsbereich. LISP (1958) überlebte in der künstlichen Intelligenzforschung. PL/I (1964) versuchte, alles zu vereinen und scheiterte.

Verwende Hamming's Unterscheidung zwischen psychologischer und logischer Designqualität sowie seine vier Kriterien, um zu erklären, warum eine Sprache, die du kennst, geglückt ist und eine andere gescheitert ist (oder scheitern könnte). Deine Erklärung sollte die spezifischen menschlichen Faktoren identifizieren, die die Akzeptanz oder Ablehnung der Sprache getrieben haben - nicht nur technische Eigenschaften.

Das wiederkehrende Muster

Hamming's Kapitel über die Software-Geschichte enthält ein wiederkehrendes Muster:

1. Eine schmerzhafte Begrenzung besteht (absolute Adressen, binäre Notation, ununterhaltbare Code)

2. Jemand entwickelt eine Abstraktionsschicht, die die Begrenzung versteckt

3. Die Abstraktion ermöglicht eine neue Skala, was neue schmerzhafte Begrenzungen schafft

4. Wiederhole

Binär → oktal/hexadezimal → symbolische Assemblersprache → FORTRAN → strukturierte Programmierung → objektorientierte Sprachen → domänenspezifische Sprachen. Jeder Schichtenstapel löst die drängendste Problematik des Vorgängers und führt gleichzeitig eine neue Klasse von Problemen ein.

Das Spaghetticode-Problem (absolute Adressen) führte zur symbolischen Assemblersprache. Große Assemblervorgänge führten zu FORTRAN. Große FORTRAN-Programme führten zur strukturierten Programmierung und dann zur objektorientierten Programmierung. Hamming's Vorlesung endete vor diesen späteren Übergängen, aber das Muster setzt sich fort.

Sein Lehrstück für Ingenieure: Sie lösen immer die durch die vorherige Abstraktion aufgedeckten Probleme. Das Verständnis der Schicht, auf der Sie sich befinden, erfordert das Wissen darüber, warum die Schicht darunter existiert.

Identifiziere eine Software-Abstraktionsschicht, mit der du regelmäßig arbeitest. Was ist die schmerzhafte Begrenzung in der Schicht darunter, die sie versteckt? Und welche neuen Problemeklassen stellt deine aktuelle Schicht dar - welche Schmerzen wird die nächste Schicht übermorgen lösen müssen?