Christian Seiler: Zukunft des Programmierunterrichtes

Beitrag lesen

Hallo Martin,

Ja, einverstanden. Ich meinte das "Anfangen mit Assembler" aber viel allgemeiner und nicht auf eine konkrete Prozessorarchitektur bezogen. Sondern eher als Grundlagenkapitel:
* Wie funktioniert eine CPU (Prinzip)
* Wie funktioniert das Zusammenspiel von CPU, Speicher, I/O
* Welche Arten von Instruktionen gibt es (Beispiele verschiedener CPUs)
* Wie kann man den Programmfluss strukturieren (Subroutines, Sprünge, Bedingungen)
Diese Grundlagen sollte man dann mit ein paar einfachen(!) Beispielprogrammen festigen und ein bisschen damit rumspielen dürfen.

Die ersten beiden Punkte zu erklären, halte ich noch für sinnvoll, die anderen beiden wiederum nicht. Programmflusssteuerung auf Assembler-Ebene ist nichts, was ich Anfängern beibringen will, weil man da außer Funktionsaufrufen wirklich nur Sprünge und nichts weiteres hat.

Zum Beispiel das Abstraktionsvermögen [...] Datenstruktur je nach Kontext ganz unterschiedlich interpretieren kann [...] Sequenz von Bytes im Speicher eine bestimmte Zahl, einen String, einen Fließkommawert oder gar eine komplexe Struktur vorzustellen.
Dazu braucht's aber kein Assembler.
[...]
Diese Äquivalenz bzw. kontextabhängige Interpretation von Daten kommt meiner Ansicht nach in keiner "höheren" Programmiersprache so anschaulich rüber wie in Assembler.

Ich gehöre zu den Leuten, die der Auffassung sind, dass die Abkehr von diesem Paradigma eines der größten Geschenke der Hochsprachen ist. Denn: Es sei denn, ich mache etwas sehr hardwarenahes oder muss meinen Algorithmus auf das letzte Quäntchen Performance / Speicherverbrauch optimieren, interessiert es mich ehrlich gesagt nicht die Bohne, wie das intern im Speicher organisiert ist. Und wenn ich Datentypen umwandele, will ich eher logische Umwandlungen als Uminterpretationen.

Es ist zwar ganz interessant, mal zu sehen, wie Daten tatsächlich im Computer dargestellt werden und ich finde schon, dass das Anfängern gezeigt werden sollte, aber wirklich nützlich sind Uminterpretationen von Daten im Speicher selten. Was soll ich mit einem Float als Integer interpretiert? Das ist irgend eine krumme, bedeutungslose Zahl, nützt mir absolut nichts. Und auch bei einzelnen Zeichen wird es in Zeiten von Unicode immer sinnloser, da irgend etwas direkt uminterpretieren zu wollen, denn nicht mal UTF-16 kann alle Unicode-Zeichen mit einer Einheit (2 Byte) darstellen, für manche braucht es 2 (also 4 Byte), bei denen man dann auf geschickte Weise bestimmte Bits extrahieren muss, um an das Zeichen zu kommen. Ich lege daher beim täglichen Programmieren keinen gesteigerten Wert darauf (auch wenn ich der Auffassung bin, dass man es schonmal gesehen haben sollte, aber das geht wie gesagt eben auch in anderen Sprachen).

Ich glaube, hier kommt einfach ein anderes Paradigma durch: Du willst, wenn Du programmierst, möglichst genau beeinflussen können, was bei der Hardware ankommt. Das ist mir persönlich nicht so wichtig (außer ich will besonders effiziente / zeitkritische Algorithmen schreiben), mir ist es viel wichtiger, in einer Programmiersprache einen Algorithmus ausdrücken zu können und es dann dem Compiler / Interpreter zu überlassen, was er denn tatsächlich daraus macht. Ich finde es zum Beispiel bei Haskell extrem geil, dass man beliebig große Zahlen als Integer-Werte nutzen kann. Wie das intern umgesetzt wird, weiß ich nicht, ist mir auch vollkommen egal, ich kann einfach darauf losrechnen und muss mich nicht um so Blödsinnigkeiten wie Integer Overflows und damit verbundene Probleme kümmern.

Nein. Radfahren lernt man auch am besten ohne Stützräder.
Wieso Stützräder? Bis auf den Embedded-Bereich hat man heutzutage einfach keinen Real Mode mehr, ...

Aber gerade dieser Bereich wächst immer noch so rasch, dass man ihn bitte nicht unterschätzen oder für irrelevant halten sollte.

Schon, aber es wird wohl kaum jemand Embedded-Programmierung lernen, ohne vorher Programmiergrundlagen auf normalen Rechnern zu kennen. Und sich *zusätzliches* Wissen anzueignen für ein bestimmtes Feld ist ja nie ein Problem.

Ich will ja nicht sagen, dass Assembler pauschal schlecht ist, ich finde nur, dass Assembler denkbar ungeeignet für Anfänger ist.

Wieso also Konzepte lernen, mit denen man sich während der Lernphase EXTREM ins Knie schießen kann, im praktischen Leben aber in der Form nicht mehr vorkommen?

Weil sie Grundlagenwissen schaffen, das der angehende Programmierer eben in vielen Bereichen *doch* wieder braucht.

Real Mode und Segmentierung? Habe ich außer für persönliche Spielereien mit Assembler noch NIE für irgend etwas praktisches gebraucht, auch nicht, als ich mit Turbo C damals noch unter DOS programmiert habe...

Assembler kann nützlich sein, wenn man vor einem Debugger sitzt. Das war aber auch das einzige Mal, wo ich Assembler außer für's Rumspielen jemals gebraucht hätte.

Wenn der Computer abstürzt, startet er ihn einfach neu, genauso, wie er eine Meldung einfach wegklickt. Das mag zwar etwas lästig sein, richtig weh tut es dem Schüler aber auch nicht - was vmtl. auch daran liegt, dass Benutzer auf Abstürze konditioniert wurden.

Wurden sie?

Ja. Dass es Leute wie Du oder ich gibt, die einen Absturz ernst nehmen, ist die Ausnahme.

Zudem: In Assembler passiert intern viel "Mojo"

Für mich passiert in Javascript, PHP oder C++ viel mehr Voodoo, als du es in Assembler siehst (z.B. Speicherverwaltung, Typecasting).

Aber dieses Voodoo passiert für Dich nur weil Du aus Sicht eines maschinennahen Programmierers an alle Sachen herangehst (naja ok, bei C++ passiert wirklich viel Voodoo, lassen wir die Sprache mal außen vor ;-)). Aber Javascript und PHP machen aus Sicht der restlichen Welt[tm] eben viel weniger Voodoo, weil man einer Zeile viel leichter ansehen kann, was sie denn tatsächlich tut, als einer Assembler-Zeile. Da steckt zwar intern viel mehr dahinter, aber der Effekt der Zeile auf den umgebenden Programmcode auf dem Niveau der Programmiersprache ist viel geringer, als bei Assembler.

Und automatische Speicherverwaltung inklusive automatischem Garbage Collector ist, wenn es richtig umgesetzt ist, eine Sache, die einem sehr viel Arbeit abnimmt und außerdem mit hoher Wahrscheinlichkeit sogar noch effizienter ist (sic!), als malloc/free bzw. pendants. Hierzu empfehle ich den 24C3-Vortrag Automatic memory management, Video dazu.

Viele Grüße,
Christian