[vorheriger Abschnitt][nächster Abschnitt][Inhalt]


3.2.3 Rechnen mit dem VNR

Jetzt, da unser VNR Laden und Speichern kann, soll er auch Verarbeiten - lassen wir ihn also rechnen!

Zu diesem Zweck hat das Applet wieder eine Erweiterung erfahren: Das Feld "Opcodes anzeigen" im Steuerfenster. Weil es immer schwieriger wird, sich die Maschinensprachecodes der verschiedenen Befehle zu merken, zeigt der VNR nach Anklicken des Kästchens statt einer Zahl einen sogenannten Opcode (operation code, Befehlskode) aus max. fünf Buchstaben. Inklusive dieses Applets kennen wir dann folgende Befehle (RAM[x] bezeichnet den Wert im RAM an Adresse x):


Um die Schlichtheit des VNR zu betonen, beherrscht unser Exemplar kein ADD absol. etc. Man überlegt sich leicht, daß für solche Befehle keine neuen Komponenten wie z.B. Register notwendig wären; jeder neue Befehl vergrößert aber das Steuerwerk des Rechners. Auch deswegen gibt es kein ADD absol., sehr wohl aber, wie wir bald sehen werden, die sehr häufig gebrauchten Befehle INC und DEC (increase und decrease, diese bewirken ein "AKKU := AKKU + 1" bzw. "... - 1").

Im Applet kommt auch ein Divisionsbefehl vor. Dieser liefert natürlich kein ganz präzises Ergebnis (mit Nachkommastellen), weil unser Beispiel-VNR nur ganze Zahlen kennt.
Wer trotzdem nicht glaubt, daß der VNR richtig rechnet, der kann dem Rechner ab jetzt auch eigene Werte vorgeben: Einfach eine beliebige Speicherzelle des RAMs anklicken und einen neuen Wert eingeben (am Besten die Simulation vorher neu starten).

Was das Rechenprogramm genau tut, ist unterhalb des Applets zu lesen:


Hier sollte die Ausgabe des Java-Applets "Von-Neumann-Rechner - Rechnen mit dem VNR" erscheinen. Wenn Sie statt dessen diesen Text sehen, unterstützt ihr Browser kein Java!



Was das Programm in diesem Applet tut:

Zunächst werden eine Addition und eine Multiplikation durchgeführt. Sehr schön ist hier die Abfolge Laden-Rechnen-Speichern zu sehen; der an jeder Rechnung zwangsläufig beteiligte Akkumulator muß vorher mit einem Wert initialisiert und nachher "gesichert" werden.

Anschließend wird (30+40) / (5+6) * 7 berechnet. Man beachte, daß jetzt nicht mehr auf jeden Rechenbefehl gleich ein STA folgt, weil nämlich idealerweise ein Rechenbefehl das Ergebnis des vorherigen gleich weiterverwendet. Ziel eines Maschinensprache-Programmierers wird es sein, den Anteil von Lade- und Speicherbefehlen im Verhältnis zu den Rechenbefehlen, die ja in diesem Falle die eigentliche Arbeit tun, zu reduzieren. Damit spart man doppelt: Das Programm wird kürzer und schneller, denn gerade die Zugriffe auf das "langsame" RAM kosten Zeit.

Ein unbedarfter Programmierer hätte den zu berechnenden Term so wie er oben steht in VNR-Code umgesetzt, also folgendermaßen:

Die beiden fett markierten Befehle lassen sich einsparen, wenn man, wie im Applet, erst den "Nenner" und dann den "Zähler" berechnet:

Man beachte, daß es nichts "bringt", wenn man das "* 7" als zum "Zähler" gehörig ansieht und vorher einschiebt. Sehr wohl aber hilft diese Anordnung, den Rundungsverlust der Ganzzahl-Division zu reduzieren: Es gilt nämlich bei ausschließlicher Verwendung ganzer Zahlen:

((30+40)/(5+6)) * 7 = 42 , hingegen
((30+40)*7) / (5+6) = 44 ,

was näher am Dezimalbruch-Ergebnis 44,54... liegt.

Durch diese Ausführungen zur Maschinenprogrammierung sollte klar geworden sein, warum auch heute noch, im Zeitalter komfortabler Hochsprachen wie Java, zeitkritische Teile von Programmen in Maschinensprache kodiert werden - je nach verwendeter Sprache und Optimierungsgrad spricht man von einem Unterschied zwischen handoptimiertem und hochsprachlichem Kode von Faktor 2 bis 10 (oder noch wesentlich höher bei interpretierten Sprachen).


[vorheriger Abschnitt][nächster Abschnitt][Inhalt] Carsten Kelling 1996 ([EMail senden]); letzte Änderung: 21. Februar 1997