Programmieren lernen mit Eas — das Tutorial von Molaskes

Wie der Computer funktioniert:10. Besser, immer besser

Der Computer ist ein fortlaufendes, gemeinschaftliches Projekt von Generationen von Wissenschaftlern, Ingenieuren und Software-Entwicklern, wobei jede Generation auf den Errungenschaften der Vergangenheit aufbaut. Diese Prinzipien gelten zwar für viele technische Leistungen, finden sich aber nirgends so wie beim Computer verdichtet und in solch rasanter Abfolge. Der Computer ist damit wahrhaftig die höchste kulturelle, wissenschaftliche und technische Errungenschaft der Menschheit. (Leider hinken seine Nutzer, vor allem die Generation Web 2.0, ihm größtenteils weit hinterher und verwenden ihn entsprechend.) Dieses Kapitel wird, als ein Beispiel für die fortlaufenden Verbesserungen, die Entwicklung von Programmiersprachen erklären. Der Programmspeicher sehr früher Computer war nur ein ROM (engl. "read-only memory" = "Nur-Lesen-Gedächtnis"), und zwar in Form von Lochkarten und später Lochstreifen. Die Löcher in der Pappkarte oder im Papierstreifenband erlaubten es Elektroden‌ (Metallkugeln oder -sfifte), die unter der Karte bzw. dem Streifen liegende andere Elektrode (ein Metallrad oder -plättchen) zu kontakten, was ein Bit in der Steuereinheit setzte. Der Programmzeiger wurde dadurch erhöht, dass ein Motor die Karte oder den Streifen um eine Lochreihe weiterzog. Das Programmieren erfolgte dadurch, dass man sorgfältig die Löcher in die Karte oder den Streifen stanzte, wobei man sich an Referenz-Tabellen orientierte, die angaben, mit welchem Bit-Muster der gewünschte Effekt zu erzielen war. Diese Programme wurden also direkt im Maschinencode geschrieben, den reinen Bits, was eine harte Arbeit bedeutete, nur um, verglichen mit modernen Programmen, geradezu rudimentäre Aufgaben zu erledigen. Aber es gab Leute, die darin so gut wurden, und genug Leidenschaft entwickelten, um auf diese Art immer längere, immer komplexere Programme zu schreiben. Sie schafften es, dass der Computer die Eingaben von einfachen Tastaturen akzeptierte, den eingegebenen Text auf automatisch gestanzten Lochstreifen speicherte, solchen Text wieder vom Lochstreifen lesen konnte, um ihn in der nächsten Sitzung fortzuschreiben ... ... und schließlich, dass dieser Text vom Programm analysiert wurde und nach einigen gekonnten Berechnungen aus diesem Text ein neuer‌ Maschinencode erzeugt werden konnte — an diesem Punkt war mit dem Assembler‌ die erste Programmiersprache geboren, und das Programmieren in Maschinencode wurde über Nacht überflüssig. Programmieren in Assembler bedeutete nun, dass man den Quellcode als Textbefehle auf einer Computertastatur schrieb. Dieser Text wird dann von dem Assembler-Compiler-Programm gelesen, das aus ihm den Maschinencode erzeugt, der auf den Lochstreifen gestanzt wurde. Auch heute noch hat jeder Computer und jeder Mikrocontroller seinen eigenen‌ Assembler (nur wird nicht mehr auf Lochstreifen gespeichert), auf dem alles weitere aufbaut. Da der Maschinencode für jeden Miktrocontroller und Miktroprozessor unterschiedlich ist, unterscheiden sich auch die Assembler voneinander. Assembler ist also mehr ein Konzept, keine einzelne Programmiersprache. Assemler verwendet Befehlskürzel, die für ein oder aber auch mehrere Maschinencode-Befehle stehen können. Nachschlagetabellen sagen dem Programmierer, wie viele Prozessorzyklen jeder Assembler-Befehl tatsächlich benötigt. Um dir mal einen Eindruck zu vermitteln, hier vier typische Assembler-Befehle:
MOV A,B
= "move from A to B" (engl. "beweg von A nach B") Kopiert das resultierende Register-Byte, das von der Adresse A gelesen wurde, in den Speicher bei Adresse B. (Manche Assembler schreiben es MOV B,A.)
ADD 7
Addiert (engl. "add") die Konstante 7 zum letzten Ergebnis der ALE.
NOP
= "no operation" (engl. "keine Operation") Der NOP-Befehl wird verwendet, um den Computer einen Takt lang warten zu lassen, etwa um ihn mit E/A-Datenprotokollen zu synchronisieren, die langsamer laufen.
JNZ l1
= "jump (on) non-zero" (engl. "spring, [wenn] nicht null") Wenn das letzte Ergebnis der ALE nicht "0" war, wird der Programmzeiger auf die Adresse gesetzt, die der Compiler aus dem Label "l1" berechnet. Labels werden als Quellcode-Textzeilen gesetzt und können sehr bequem anstelle von festen Adress.Konstanten verwendet werden. Das "l1" von oben etwa könnte man mit der folgenden Zeile (zwischen Befehlszeilen) setzen:
l1:
‌ Auch führten Assembler bereits Variablen ein, Namen für Seicher-Adressen, die erst der Compiler konkret zuordnet. Und wieder gab es Manche, die so gut darin wurden und genug Leidenschaft mitbrachten, dass sie mit dem Assembler den nächsten Schritt, die eigentlichen Programmiersprachen, entwickelten. Diese parsen mehr oder weniger einfach lesbare Quellcode-Zeilen variabler Länge, die oft für dutzende Zeilen Assemblercode stehen oder gar für ganze Assembler-Unterprogramme. Sie führten auch viele Abstraktionen ein, die, verglichen mit Assembler, viel näher an dem sind, wie wir Menschen gewohnt sind zu denken, etwa mit sprachlicher Grammatik‌ (beispielsweise wenn-dann-sonst und Schleifen) oder in mathematischen Formeln. Die eigentlichen Programmiersprachen laufen zudem auf verschiedenen Mikroprozessortypen. Jeder Typ braucht seinen eigenen Compiler für die Programmiersprache, so dass eine Zeile wie "a = b + c*d" je nach Mikroprozessor recht unterschiedlich umgesezt wird (Maschinencode), die Zeile selbst bleibt aber in der gegebenen Programmiersprache stets gleich und hat auch überall denselbe definierte Wirkung. Es sind viele Programmiersprachen entwickelt worden, alle mit ihren eigenen Features, Ideen, Stärken — und Schwächen. Nur wenige erlangten weite Verbreitung, wobei ihr Erfolg nicht immer proportional zu ihrer allgemeinen Qualität war, sondern oft nur das Ergebnis von Großkonzern-Marktkämpfen mit ihrer geballten Marketing-Macht. So wurde die mit Abstand einflussreichste‌ Programmiersprache ausgerechnet eine schlicht "C" genannte, vergleichsweise kryptische Sprache, die so un-clever ist wie ihr Name und voller Fallstricke steckt, die schon zahllose katastrophale Softwarefehler bedingt haben. Alle frühen Programmiersprachen waren noch ziemlich anstrengend in der Benutzung, aber wieder gab es manche Leute, die sie nutzten, um neue, bessere Programmiersprachen zu implementieren, die immer komfortablere‌ Features hinzufügten und die Fallstricke und Fehler der alten vermieden. Wirklich? Leider nicht ganz. Tatsächlich bestand die nächste Generation oft nur aus reformierten‌ Versionen der alten Sprachen, so folgten auf C etwa C++ und C#, aber sie behielten die meisten Nachteile der alten Sprachen bei. Auch führten neue Sprachen immer exzentrischere‌ Features ein, die von akademischen Theoretikern erdacht worden waren und dann heftig vermarktet wurden, tatsächlich aber nur dazu führen, dass Programme langsamer laufen, immer mehr RAM und Festplattenplatz vergeuden und nicht wirklich die Produktivität verbessern. Aber Marketing zieht, weil es als professionelle, das ganze Jahr aktive Großindustrie auf dem hauptberuflichen Missbrauch von Psychologie basiert, so dass dir viele Leute begegnen werden, die, obwohl das Gegenteil wissenschaftlich gut belegt ist, eisern der Meinung sind, dass etwa objekt-orientierte Programmierung‌ eine richtig tolle Sache sei. Als das Internet ernsthaft wichtig wurde, kamen spezielle Programmiersprachen auf, etwa PHP zum Programmieren von Software für Webserver, die sichere Logins ermöglicht, Nutzerdaten verwaltet und vieles mehr, und JavaScript zum Programmieren von Software. für Webbrowser, die die angezeigte Website dynamisch auf Nutzereingaben reagieren lässt oder Seiten-Elemente animiert. So ziemlich alle davon basieren auf C, haben aber recht tiefgreifende Reformen vorgenommen, die sie sehr viel komfortabler‌ machen — allerdings laufen ihre Programme langsamer als in C geschriebene Programme. Der Grund ist, dass der Programmierer in C festlegen muss, wie viele Bytes eine Variable belegen soll (typisierte Variablen) und diese Einstellung im gesamten Code genauestens einhalten muss — in PHP, JavaScript und Co jedoch können Variablen jederzeit ihren Typ ändern, und das Programm selbst übernimmt die Überprüfungen und Konvertierungen zur Laufzeit, und zwar jedesmal, wenn eine Variable gelesen oder geschrieben wird. Und wieder werden immer weitere neue Programmiersprachen entwickelt, so wie Eas, das in seiner aktuellen Eas-4B-Umsetzung nach JavaScript kompiliert, weswegen es noch ein wenig langsamer ist als JavaScript, dafür aber als wirklich von Grund auf neu erschaffene‌ Sprache keine der üblichen Fallstricke und Schwachpunkte aller C-Ableger hat und zudem in der Anwendung maximalen Komfort bietet. Die Geschichte geht weiter, und ich denke, dass das größte Potenzial darin liegt, den Ballast der alten Sprachen endlich abzuschütteln, indem sie durch Maschinencode-Compiler für moderne Sprachen vollständig ersetzt werden. Warum? Weil mir meine Erfahrung mit großen Softwareprojekten immer und immer wieder gezeigt hat, dass die größten Fortschritte nur dadurch zu erzielen sind, dass man wieder ganz von vorn mit einem leeren Blatt beginnt, nachdem man von der Arbeit mit dem alten Code ein paar Generationen bzw. Versionen hinweg gelernt hat. Beispielsweise verwendete eine Firma ein wichtiges Mikrocontrollerprogramm, das über die Jahre von mehreren Programmierern immer weiter verbessert worden war. Als man es mir übergab, warf ich es in den Papierkorb und schrieb es in nur zwei Wochen ganz neu — meine Version ist mehr als 1000-mal‌ schneller, hat mehr Features und läuft (im Gegensatz zu dem alten Programm) hundertprozentig zuverlässig.
10. Besser, immer besser
D Du brauchst zwei Dinge
K Kontakt
Esc Suchen / Inhaltsverzeichnis
Tab