Rechnerarchitektur mit Simulator JOHNNY

aus ZUM-Wiki, dem Wiki für Lehr- und Lerninhalte auf ZUM.de
Wechseln zu: Navigation, Suche
Mathematik-digital Pfeil-3d.png
Lernpfad

Liebe Nutzerinnen und Nutzer dieser Seite, Bitte helfen Sie mit, diese Seite besser zu machen, indem Sie bei Fehlern und Unklarheiten

Wikis leben vom Mitmachen.

Inhaltsverzeichnis

Vorwort

Computer haben sich seit ihren Kindertagen sehr verändert: die Rechner sind immer leistungsfähiger, immer kleiner und immer billiger geworden. Die Rechenleistung, die in den 1950er Jahren von einem Computer erbracht wurde, der mehrere Schränke füllte, steckt heute in einem Mobiltelefon.

Etwa seit den 1980er Jahren ist der Computer auf dem Siegeszug durch die Privathaushalte. Heute verwenden die allermeisten Leute auch in ihrem alltäglichen Leben Computer, die meisten allerdings, ohne auch nur ansatzweise zu wissen, wie dieses Gerät aufgebaut ist und wie es die Computerhardware fertigbringt, Software auszuführen und damit „zum Leben“ zu erwecken.

Natürlich sind Computer – gerade die heutigen – so kompliziert, dass eine umfassende Behandlung im Unterricht ganz unmöglich ist. Daher muss sich der Informatikunterricht in der Schule und auch dieses Skript auf die wesentlichen Bestandteile und Funktionsprinzipien einschränken, muss aber jede Menge – auch wichtiger Details – außer Acht lassen.

Wenn man zum Beispiel einen Personal Computer (PC) öffnet, so erkennt man den groben Aufbau. Wie der Computer wirklich funktioniert, kann man jedoch nicht erkennen: der Computer sieht im laufenden Betrieb praktisch genauso aus wie im ausgeschalteten Zustand – wenn man von der Kühlung und vielleicht ein paar Kontrolllampen absieht. Um dennoch eine Vorstellung von den Abläufen zu haben, greifen wir hier auf ein typisches Mittel zurück: die Simulation. Ein Simulationsprogramm – „Johnny“ genannt – zeigt ein stark vereinfachtes Modell eines Rechners, an dem man jedoch viele wesentliche Funktionsabläufe erkennen kann.

Auf viele Details wie etwa den genauen Aufbau der Chipsätze oder modernere Entwicklungen, zum Beispiel die Mehrkern-Technologie, kann und soll hier nicht eingegangen werden.


Viel Spaß und viel Erfolg beim Durcharbeiten dieser interaktiven Lernumgebung.

Historische Bemerkungen

Die Geschichte des Computers kann hier natürlich nicht einmal ansatzweise erzählt werden, daher nur ein paar Bemerkungen und Literaturverweise.


Rechenmaschinen, die dem Menschen das stumpfsinnige Rechnen erleichtern sollten, gibt es schon lange. Schon im 17. Jahrhundert wurden mechanische Rechenmaschinen konstruiert, die addieren und subtrahieren konnten und auch das Multiplizieren und Dividieren stark erleichterten [1]. Als einer der Urväter solcher Maschinen gilt Wilhelm Schickard (1592-1635), das linke Bild zeigt seine Rechenmaschine. Solche mechanischen Rechenmaschinen wurden bis in die 1970er Jahre gebaut (rechtes Bild). Schickardmaschine.jpg Brunsviga 20, 4-Spezies-Rechner (Foto Sp).jpg
Neben einfachen Rechenoperationen war es lange der Traum von Mathematikern und Ingenieuren, auch komplexe Rechenabläufe mit vielen Rechenschritten zu automatisieren. Einer der Pioniere dieser Entwicklung war Charles Babbage (1791-1871), der im 19. Jahrhundert verschiedene Maschinen konstruierte, die aber mit der damaligen Feinmechanik nicht zu realisieren waren; erst nach 1990 konnte man seine Maschine nachbauen. Babbage Difference Engine (1).jpg Charles Babbage Difference Engine No2 Gears on Drawing.jpg


Ebenfalls mechanische Probleme hatte der deutsche Ingenieur Konrad Zuse (1910-1985) mit seinem mechanischen Rechner Z1. Bei seinem berühmt gewordenen Rechner Z3 aus dem Jahr 1941, der als der erste funktionsfähige Digitalrechner gilt, wurden daher elektromechanische Relais verwendet, bei denen Magnetspulen Mehrfachschalter betätigen [2]. Damit lassen sich komplexe Strukturen allein durch Verkabelung realisieren. Ein Nachbau der Z3 steht im Deutschen Museum München, in [3] findet sich auch ein Link zu einer Simulation eines Teils der Maschine. Waren die Relais ein gewaltiger Fortschritt gegenüber der reinen Mechanik, so konnte man wegen der darin enthaltenen mechanischen Schalter doch keine schnell arbeitenden Computer aufbauen; der Rechner Z3 hatte eine Geschwindigkeit von 5,3 Hz, also 5,3 Takte pro Sekunde. Z3 Deutsches Museum.JPG Elektromagnetischerspeicher zuse relais.jpg


Eine sehr viel höhere Geschwindigkeit konnte man mit Elektronenröhren erreichen. Der ENIAC (Electronic Numerical Integrator and Computer) aus dem Jahr 1946 bestand (unter anderem) aus mehr als 17000 solcher Röhren und wog 27 Tonnen [4]. Im Vergleich zu den 5,3 Hz des elektro-mechanischen Zuse Z3 zeigen die 10 kHz (10000 Hz) des ENIAC den gewaltigen Fortschritt dieser elektronischen Technologie [1]. Die wesentliche informatische Struktur auch der heutigen Rechner, die in diesem Skript beschrieben wird, ist nach dem ungarisch-amerikanischen Mathematiker John von Neumann (1903-1957) benannt und stammt letztlich aus dieser Röhren-Zeit der Computer. ENIAC-changing a tube.jpg Ibm-tube.jpg
Das Problem der Elektronenröhren waren einerseits ihre Störanfälligkeit und andererseits ihr Platzbedarf und extremer Energieverbrauch (die Elektronen werden in den Röhren durch glühende Drähte freigesetzt). Außer für große Forschungseinrichtungen, Industrieunternehmen und das Militär waren solche Rechner praktisch unbezahlbar.

Die Erfindung des Transistors, eines elektronischen Bauteils auf Halbleiterbasis, ermöglichte in den Folgejahren, immer kleinere und leistungsfähigere Rechner zu bauen. Man spricht in diesem Zusammenhang auch von „Miniaturisierung“. Mit der damit einhergehenden Verbilligung von Rechenleistung wurden Computer immer mehr Anwendern zugänglich.

DM IBM S360.jpg Computer Transistor 1965.jpg
In den 1980er Jahren eroberten die Computer (Home Computer und Personal Computer genannt) die Privathaushalte. Heute haben in den Industrieländern die meisten Menschen Zugang zu Computern und nutzen dies geschäftlich und privat. Die Miniaturisierung hat in den letzten Jahren angehalten: Immer kleinere Geräte verfügen heute über erstaunliche Rechenleistung, so dass zum Teil Computer selbst dort Anwendung finden, wo wir sie gar nicht mehr bemerken. Mikrocontroller werden zur Steuerung von Abläufen in vielen elektrischen und elektronischen Geräten verwendet, vor allem auch in der Automobil-Branche, ohne dass wir diese Geräte als Computer überhaupt wahrnehmen.


Apple iie.jpg World’s first dual-core smartphone comes to europe.jpg


Eine gute Darstellung der früheren Entwicklung bieten die Bücher [2] und [3].


Arbeitsauftrag 1

Eine ganz ganz kurze Zusammenfassung der Computergeschichte
Vervollständigen Sie den folgenden Lückentext:

Die ersten Rechenmaschinen arbeiteten mechanisch. Mit ihrer Hilfe konnte man gut Rechnungen in den Grundrechenarten ausführen. Der Versuch, kompliziertere Berechnungen mit solchen Maschinen durchzuführen, scheiterten an Problemen der Feinmechanik. Einen ersten großen Fortschritt brachten im 20. Jahrhundert elektromechanische Relais, die allerdings wegen der beweglichen mechanischen Teile keine große Geschwindigkeit erreichten. Einer der bekanntesten solchen Rechner ist der Z3 des Ingenieurs Konrad Zuse. Deutlich schneller arbeiten Rechner auf der Basis von Elektronenröhren. Einer der ersten Rechner mit dieser Technik war der ENIAC, der jedoch sehr groß und schwer war, dazu anfällig gegenüber Störungen und einen extrem hohen Energieverbrauch hatte. Eine Lösung dieser Probleme fand sich erst mit der Erfindung des Transistors. Durch Miniaturisierung der elektronischen Schaltungen wurden PCs, Smartphones und ähnliche Kleinstcomputer überhaupt erst möglich.


Aufbau eines heutigen Personalcomputers

Schraubt man einen heutigen PC auf, ergibt sich etwa das Bild links. Oben links befindet sich das Stromversorgungsgerät, auf der rechten Seite erkennt man die Schächte, in der etwa Festplatten und DVD-Laufwerke montiert werden können.

Den wichtigste und kompliziertesten Teil sieht man etwa in der Mitte links des Gehäuses: die Hauptplatine (Motherboard) mit dem Prozessor (CPU). Eine solche Platine ist nochmal im rechten Bild gezeigt.

In der technischen Beschreibung von Rechnern (und natürlich auch der Werbung) wird vor allem auf den Prozessor (CPU, Central Processing Unit) und auf den Arbeitsspeicher (RAM, Random Access Memory) hingewiesen. Alle anderen Bestandteile (Festplattenspeicher, Ein- und Ausgabemedien wie USB-Schnittstelle, Tastatur, Maus, Graphik- und Soundkarte usw.) wollen wir hier als Peripherie (also „Umgebung“) bezeichnen.

RAM und Peripherie sind über ein so genanntes Bus-System mit der CPU verbunden (Das Wort Bus leitet sich aus dem lateinischen „omnibus“ - „für alle“ ab. Wie beim Straßen-Omnibus wird auch beim Computer-Bus das Transportsystem von verschiedenen Daten als „Verkehrsteilnehmern“ verwendet, obwohl sie unter Umständen unterschiedliche Start- und Zielpunkte haben).

Ein Personal Computer etwa aus dem Jahr 2005 Hauptplatine eines PC

Der Prozessor selbst besteht vor allem aus zwei Einheiten: dem so genannten Rechenwerk (englisch: ALU, Arithmetic Logic Unit), das mathematische und logische Operationen ausführen kann und dem Steuerwerk (englisch: Control Unit), das letztlich alle Abläufe des Rechners steuert.


Vereinfachte Struktur eines von-Neumann-Rechners

Arbeitsauftrag 2
Englisches und deutsches Fachvokabular

Das Fachvokabular der Computertechnik stammt großteils aus dem Englischen, allerdings gibt es für viele Begriffe auch sinnvolle deutsche Übersetzungen. Unterhalten sich Computerfreaks, geht Englisch und Deutsch oft wild durcheinander, von den Abkürzungen ganz zu schweigen. Konstruieren Sie eine "Übersetzungstabelle". Manche Begriffe werden im Text erklärt; bei anderen muss man sich informieren (z.B. im Internet) oder eben auch mal "glücklich raten".

CPU Prozessor
RAM Arbeitsspeicher
Hard Disk Festplatte
I/O Ein- und Ausgabe
Interface Schnittstelle zwischen verschiedenen Teilen eines Computersystems
Control Unit Steuerwerk
ALU Rechenwerk




Der Johnny-Simulator – ein einfaches Modell

Wie schon im Vorwort gesagt, sieht man einem modernen Rechner seine Funktion nicht an. Um besser zu verstehen, wie Rechner funktionieren, greifen wir deshalb auf eine Simulation zurück. Der Simulator „Johnny“ ist nach dem genialen Entwickler der heutigen Rechnerstruktur, John von Neumann (1903-1957) benannt: Privat war von Neumann für seine Partys berühmt und sein Spitzname war wohl auch deshalb „Good Time Johnny“, worauf der Name des Simulators anspielt.

Der Johnny-Simulator konzentriert sich auf CPU mit Rechenwerk und Steuerwerk und den Arbeitsspeicher. Die Benutzungsoberfläche entspricht dabei etwa dem obigen Blockdiagramm:

Pd Johnny hidden CU.png


Beim Start ist die Struktur des Steuerwerks (Control Unit) noch verdeckt, um die Dinge zunächst einfach zu halten. Der Inhalt des RAM kann im Simulator gelöscht, aus einer Datei geladen bzw. in eine Datei geschrieben werden.


Vieles ist beim Johnny-Simulator einfacher als bei einem richtigen Rechner. So rechnen praktisch alle Rechner im Binärsystem, während der Simulator in unserem gewohnten Dezimalsystem rechnet. Auch die Funktion des Bus-Systems ist gegenüber echten Rechnern vereinfacht: Normalerweise können sich Bus-Syteme keine Daten merken, sondern sind lediglich Verbindungswege.

All diese Vereinfachungen sollen den Benutzern des Simulators die Bedienung vereinfachen, die Grundprinzipien des Rechners bleiben jedoch erhalten.

Der Simulator kann vom Bildungsserver des Landes Rheinland-Pfalz, vom Server des Heise-Verlags oder direkt vom SourceForge-Server ohne Kosten heruntergeladen werden. Das Programm ist ein OpenSource-Projekt und kann unter der Programmierumgebung Lazarus selbst weiterentwickelt werden.

Zahlen im Arbeitsspeicher (RAM)

Betrachten wir zunächst den Arbeitsspeicher. Dieser ist im Simulator als eine Tabelle dargestellt, was seiner tatsächlichen Struktur recht nahe kommt. Jede Zeile der Tabelle hat eine Nummer, die so genannte Adresse (Spalte „Adr“). Statt von Zeilen spricht man auch von Speicherstellen. In jeder Speicherstelle kann eine Zahl zwischen 0 und 19999 abgelegt werden. Aus technischen Gründen sind dabei die 10000er- und die 1000er-Stelle in einer gesonderten Spalte „Hi“, die 100er-, die 10er- und die 1er-Stelle „Lo“ abgelegt. Die hinteren beiden Spalten „Asm“ und „Op“ werden später eine Rolle spielen, sie sind aber nur Kommentare. Der eigentliche RAM-Inhalt sind die Spalten „Hi“ und „Lo“.

Die Inhalte der einzelnen Speicherstellen kann man (im Simulator) entweder durch Anklicken der entsprechenden Zeile, oder aber über das Bus-System des Simulators ändern.

Pd Johnny RAM.png


Zunächst muss die richtige Zeile, also Adresse gewählt werden. Dies tut man, indem man die Adresse der betreffenden Zeile am so genannten Adressbus oben links im Textfeld eingibt, mit dem nebenstehenden Knopf diese Zahl auf den Adressbus legt. Danach legt man analog die Zahl, die in den RAM geschrieben werden soll, auf den Datenbus und drückt auf den Knopf „db->ram“.

Rechnen mit Johnny

Betrachten wir nun das Rechenwerk (Arithmetic Logic Unit). Diese kann mit Daten, die auf dem Datenbus liegen, rechnen. Kernstück des Rechenwerks ist der so genannte Akkumulator (lat.: „Sammler“). In ihm sammeln sich die Rechenergebnisse an. Drückt man z.B. auf die Taste plus, so wird der Wert auf dem Datenbus zum Wert des Akkumulators addiert und das Ergebnis wieder im Akkumulator gespeichert. Johnny beherrscht von sich aus nur die beiden Rechenoperationen plus und minus, alles andere muss man ihm sozusagen beibringen (mehr dazu später). Der Wert des Akkumulators kann auch wieder auf den Datenbus kopiert werden (mit acc->db). Daneben gibt es noch ein paar andere Möglichkeiten, den Akkumulator zu manipulieren, die Sie aber auch leicht selbst herausfinden können. Wichtig für später ist auch die Kontrolllampe links neben dem Akkumulator. Diese zeigt an, ob der Inhalt des Akkumulators gerade den Wert 0 hat.

Pd Johnny ALU.png

Arbeitsauftrag 3

Herunterladen und Inbetriebnahme von JOHNNY Falls der Simulator "JOHNNY" auf Ihrem Rechner noch nicht installiert ist, Laden Sie ihn von einer der oben genannten Download-Seiten herunter. Unter Windows-Betriebssystemen muss "JOHNNY" muss nicht installiert werden, es muss lediglich die heruntergeladene ZIP-Datei in einen beliebigen Ordner ausgepackt und die Datei "johnny.exe" ausgeführt werden.

Anmerkung für Linux-Benutzer:
Wenn Sie "Johnny" unter einem Linux-Betriebssystem ohne Emulation betreiben möchten, kann man die Quelldateien herunterladen und unter Verwendung der Entwicklungsumgebung Lazarus kompilieren.

Mikrobefehle im Handbetrieb

Bis hierher hat Ihnen das Skript nur Dinge beschrieben. Vieles jedoch können Sie auch selbst herausfinden.


Arbeitsauftrag 4
a) Die Bedeutung eniger Mikrobefehle

Die Knöpfe des Simulators entsprechen Aktionen, die man als „Mikrobefehle“ bezeichnet; sie sind die kleinsten Befehlseinheiten, mit denen der Prozessor gesteuert werden kann.Probieren Sie die folgenden Mikrobefehle aus und ordnen Sie die Lösungen zu:

db->ram Businhalt auf die aktive Adresse des RAM legen
ram->db RAM-Inhalt der aktiven Adresse auf den Bus legen
acc:=0 Akkumulator auf 0 setzen
acc++ Inhalt des Akkumulators um 1 erhöhen
acc-- Inhalt des Akkumulators um 1 erniedrigen
db->acc Inhalt des Datenbusses in den Akkumulator kopieren
plus Inhalt des Datenbusses zum Akkumulator hinzuaddieren
minus Inhalt des Datenbusses vom Akkumulator subtrahieren
acc->db Inhalt des Akkumulators auf den Datenbus kopieren


b) Rechnen mit Mikrobefehlen

Angenommen, die Adresse „42“ würde bereits auf dem Adressbus stehen. Welche Mikrobefehle muss man nacheinander ausführen, um den Wert in der Speicherstelle mit der Adresse 42 zu verdoppeln (unabhängig davon, welche Zahl vorher gerade im Akku steht).

Zum Testen mit dem Simulator sollte man vorher die Speicherstelle 42 mit einem Wert >0 belegen, denn sonst kann man die Verdopplung natürlich nicht gut erkennen.

ram->db
db->acc
plus
acc->db
db->ram



Makrobefehle als praktische Abkürzung

Wiederkehrende Befehlsfolgen

Arbeitsauftrag 5

Mikro- und Makrobefehle

Beschreiben Sie in der mitleren Spalte, mit welcher Folge von Aktionen man mit dem Simulator die Zahlen in den Speicherstellen 10,11 und 12 addieren und dann die Zahl in Speicherstelle 14 davon subtrahieren kann. Das Ergebnis soll in der Speicherstelle mit der Adresse 15 abgespeichert werden. (Bei den letzten drei Zeilen kann auch eine andere Lösung als die "Musterlösung" richtig sein, aber diese Lernumgebung ist nicht ganz so flexibel ;-).

Neben den schon bekannten Mikrobefehlen brauchen wir zusätzlich noch eine Anweisung wie „Lege Adressse ... auf den Adressbus“ wobei „...“ für die entsprechende Adresse, also die Nummer der Zeile im RAM steht.


Ordnen Sie danach in der rechte Spalte "Abkürzungen" wie TAKE 10 oder SUB 14 für die Befehlsfolgen in der mittleren Spalte zu.


1 Lege Adresse 10 auf den Adressbus TAKE 10
2 ram->db
3 db->acc

4 Lege Adresse 11 auf den Adressbus ADD 11
5 ram->db
6 plus

7 Lege Adresse 12 auf den Adressbus ADD 12
8 ram->db
9 plus

10 Lege Adresse 14 auf den Adressbus SUB 14
11 ram->db
12 minus

13 Lege Adresse 15 auf den Adressbus SAVE 15
14 acc->db
15 db->ram


Man nennt ein Programm bestehend aus solchen Abkürzungen auch Maschinenprogramm, die einzelnen Befehle darin Makrobefehle, da sie mehrere Mikrobefehle zu größeren Einheiten zusammenfassen.

Der Speicher als Programmspeicher

Am Arbeitsauftrag 5 merkt man: Maschinenprograme aus Makrobefehlen lassen sich leichter verstehen und vor allem viel kompakter hinschreiben als eine Folge von Mikrobefehlen. Die Frage ist nur: wo genau hinschreiben. In den ersten Rechnern wie dem Zuse Z3 waren die Programme z.B. auf Lochstreifen gespeichert. John von Neumann hatte die Idee, nicht nur Zahlen sondern auch Programme in ein und demselben Arbeitsspeicher abzulegen. Man spricht in diesem Zusammenhang von der von-Neumann-Architektur.

Wie aber lassen sich Makrobefehle im Speicher (RAM) ablegen? Wir sehen, dass der RAM nur Zahlen – in unserem Simulator zwischen 0 und 19999 – ablegen kann.

Wie also kann man einen Befehl wie ADD 12 im RAM speichern?

Zunächst überlegt man sich hierfür, dass dieser Befehl eigentlich zweigeteilt ist, einmal in die eigentliche Operation „ADD“ und dann in die Adresse, auf die sich der Befehl bezieht. Der Speicher unseres Simulationsrechners enthält 1000 Speicherstellen mit Adressen zwischen 0 und 999. Um die Adressen darzustellen brauchen wir also die 1er-, die 10er- und die 100er-Stelle einer Zahl. Die verbliebenen zwei Stellen, die 1000er- und die 10000er-Stelle können wir verwenden, um die Operation selbst zu beschreiben, nicht mit einer Zeichenfolge wie „Add“ sondern mit einer Zahl etwa 20000.

Damit wird aus dem Befehl „ADD 12“ nun einfach die Zahl „20012“. Damit man sich als Benutzer des Simulators die Zahlen für die einzelnen Operationen nicht merken muss, kann man bei der Eingabe von Werten in den RAM ein Auswahlmenü anklicken, dass direkt die einzelnen Operationen mit ihren entsprechenden Zahlen zur Auswahl stellt.

Pd Johnny Edit RAM.png

Auf diese Weise kann man ohne Auswendiglernen der entsprechenden Zahlen (der so genannten Operation Codes, kurz Opcodes genannt) ein Maschinenprogramm eingeben. Neben dem eigentlichen Speicherinhalt, der – wie wir wissen – nur aus den Zahlen besteht, zeigt der Simulator als Kommentar die zugehörigen Makrobefehle an.

Pd Johnny RAM Macro Program.png

Erste Maschinenprogramme

Arbeitsauftrag 6
a) Programme und Daten im Arbeitsspeicher

Geben Sie das folgende Maschinenprogramm ab der Adresse 000 ein:


000: TAKE 010
001: ADD 011
002: ADD 012
003: SUB 014
004: SAVE 015

Testen Sie das Programm, in dem sie unter den verschiedenen Adressen 10,11,12 und 14 verschiedene Zahlen vor dem Programmlauf speichern.


b) Weitere Befehle
Neben den Befehlen TAKE, ADD, SUB und SAVE gibt es noch einige andere. Finden Sie anhand des folgenden Programms heraus, was die darin enthaltenen Befehle bewirken und kreuzen Sie die richtige Beschreibung der Funktion an.


000: INC 010
001: INC 010
002: DEC 010
003: INC 010
004: INC 010
005: NULL 010


1. INC<Adresse>

Erniedrigt die Speicherzelle mit der Adresse um 1
Erhöht die Speicherzelle mit der Adresse um 1
Verschiebt den Inhalt der Speicherstelle mit der Adresse auf einen Platz weiter hinten
Setzt die Speicherzelle mit der Adresse auf den Wert 0

2. DEC<Adresse>

Erniedrigt die Speicherzelle mit der Adresse um 1
Erhöht die Speicherzelle mit der Adresse um 1
Verschiebt den Inhalt der Speicherstelle mit der Adresse auf einen Platz weiter hinten
Setzt die Speicherzelle mit der Adresse auf den Wert 0

3. NULL<Adresse>

Erniedrigt die Speicherzelle mit der Adresse um 1
Erhöht die Speicherzelle mit der Adresse um 1
Verschiebt den Inhalt der Speicherstelle mit der Adresse auf einen Platz weiter hinten
Setzt die Speicherzelle mit der Adresse auf den Wert 0

Punkte: 0 / 0



Sprünge und Bedingungen

Bisher sind unsere Programme immer von einem Befehl zum nächsten gegangen. Für kompliziertere Aufgaben reicht das jedoch nicht. Wie Sie wahrscheinlich aus anderen Programmiersprachen wissen, muss es auch Verzweigungen (if ... then ... else ...) oder Schleifen (etwa while ... do ...) geben können.


Arbeitsauftrag 7
a) Kreuz und quer durch's Programm

Testen Sie das folgende Programm und finden Sie heraus, was die Befehle JMP und TST bewirken. Setzen Sie vor Ausführung des Programms die Speicherstelle Nr. 10 auf den Wert 5 und die Speicherstelle Nr. 11 auf den Wert 42.


000: INC 010
001: DEC 010
002: TST 010
003: JMP 001
004: TAKE 011
005: SAVE 012

Beschreiben Sie die Funktion der beiden Befehle JMP und TST in kurzer Form:


1. JMP<Adresse>

Die Speicherstelle an der Adresse springt um eins nach oben.
Das Programm spingt in seiner Ausführung an den Befehl, der an der Adresse steht.
An der Adresse springt das Programm aus der Ausführung heraus.
Testet, ob die Speicherstelle an der Adresse den Wert 0 hat und überspringt in diesem Fall den nächsten Befehl.
Testet, ob die Speicherstelle an der Adresse größer als 1 ist und springt in diesem Fall an den Anfang des Programms.

2. TST<Adresse>

Die Speicherstelle an der Adresse springt um eins nach oben.
Das Programm spingt in seiner Ausführung an den Befehl, der an der Adresse steht.
An der Adresse springt das Programm aus der Ausführung heraus.
Testet, ob die Speicherstelle an der Adresse den Wert 0 hat und überspringt in diesem Fall den nächsten Befehl.
Testet, ob die Speicherstelle an der Adresse größer als 1 ist und springt in diesem Fall an den Anfang des Programms.

Punkte: 0 / 0


b) Malnehmen - eigentlich gar nicht eingebaut

Nun wird es komplizierter: Konstruieren Sie ein Maschinenprogramm, das die Zahlen in den Speicherstellen 10 und 11 miteinander multipliziert und das Ergebnis in der Speicherstelle 12 abspeichert.

Tipp: Das Programm soll folgendes tun:

  • Die Speicherstelle 12 zunächst auf 0 setzen.
  • Den Wert der Speicherstelle 12 in den Akku holen, den Wert der Speicherstelle 10 addieren das Ergebnis und wieder in Speicherzelle 12 abspeichern.
  • Nach einer solchen Addition den Wert der Speicherstelle 11 um 1 erniedrigen.
  • Das Verfahren ab dem 2. Punkt so lange wiederholen Sie, bis die Speicherstelle 11 den Wert 0 hat.

Testen Sie Ihr Programm, ob es auch funktioniert. Hierfür sollten die Speicherstellen 10 und 11 auf kleine, von Null verschiedene Werte gesetzt werden, also z.B. 5 und 3.

000 : NULL 012
001 : TAKE 012
002 : ADD  010
003 : SAVE 012
004 : DEC  011
005 : TST  011
006 : JMP  001
007 : HLT  000

(Der Befehl HLT 000 stoppt den Programmablauf im Simulator ab).


c) Dividieren - einfache Version Schreiben Sie ein Programm, das eine Zahl durch eine andere Zahl teilt. Betrachten Sie dabei zunächst nur den Fall, dass die größere Zahl in Speicherzelle 10 tatsächlich durch die kleinere in Speicherzelle 11 ganzzahlig teilbar ist.

d) Größer, kleiner oder gleich Wir betrachten zwei Zahlen in den Speicherstellen 10 und 11. JOHNNY soll entscheiden, ob die Zahl in Speicherstelle 10 größer ist als die in Speicherstelle 11, gleich groß ist, oder aber kleiner. Je nachdem soll in Speicherstelle 12 nach der Untersuchung der Wert 1, 2 oder 3 stehen.
Tipp: a-b=a+1-b-1

e) Dividieren - komplizierte Version Schreiben Sie ein Programm, das eine Zahl durch eine andere Zahl teilt. Und zwar in der Art, wie wir vermutlich alle das in der Grundschule gelernt haben:
17:5 = 3 Rest 2.
Die Zahl in Speicherstelle 10 soll dividiert werden durch die Zahl in Speicherstelle 11. Der ganzzahlige Quotient soll danach in Speicherstelle 12, der Rest in Speicherstelle 13 gespeichert sein. Tipp: Vielleicht hilft Ihnen das Ergebnis aus Aufgabe d)

Programme, die sich selbst ändern

Wie bereits gesagt, ist das besondere an von Neumanns Idee zur Speicherung von Programmen, dass Programmcode („Was soll gemacht werden?“) und Programmdaten („Womit soll etwas gemacht werden?“) in ein und dem selben Arbeitsspeicher gespeichert sind.

Mehr noch: Das Programm besteht selbst aus Daten, der einzige Unterschied ist, dass diese Daten, die einem Programm entsprechen, von der Maschine als Befehle interpretiert und ausgeführt werden.

Dies hat eine wichtige Konsequenz, die zunächst ein wenig abwegig klingt: Programme können sich selbst (oder andere Programme im Arbeitsspeicher) verändern, indem sie die entsprechenden Daten im Speicher manipulieren. Compiler z.B. lesen einen Text in einer höheren Programmiersprache und übersetzen ihn in ein Maschinenprogramm. So etwas geht in dieser Weise nur dank der von-Neumann-Architektur.

Einen Compiler zu bauen würde den Rahmen dieses Kurses sprengen, allerdings wollen wir uns ein Programm anschauen, das tatsächlich sich selbst, also seinen eigenen Programmcode ändert:


Arbeitsauftrag 8
a) Mut zur Selbst-Veränderung

Untersuchen Sie das folgende Programm und beschreiben Sie seine Funktion:


Pd Johnny Selfmodifying.png

b) Ein weiteres Programm, das sich verändert

Modifizieren Sie das Programm so, dass es nicht ständig ein und die selbe Zahl schreibt, sondern fortlaufende Zahlen, also z.B. 42, 43, 44, 45 usw. Außerdem soll das Programm diese Zahlen nur in die ungeraden Speicherstellen ab 100 schreiben, also in die 101, die 103 usw.

000 : TAKE 010
001 : SAVE 101
002 : INC  001
003 : INC  001
004 : INC  010
005 : DEC  011
006 : TST  011
007 : JMP  000
---
010 : 42
011 : 13



Vom Makrobefehl zu den Mikrobefehlen – das Steuerwerk

Der Aufbau des Steuerwerks

Bisher haben wir einfach akzeptiert, dass unser Computer die Befehle im Speicher liest und die entsprechenden Mikrobefehle irgendwie ausführt. Wie aber macht er das? Schließlich handelt es sich nur um ein elektronisches Gerät ohne eigene Intelligenz (auch wenn er zugegebenermaßen intelligent konstruiert ist).

Um zu sehen, wie das Interpretieren der Makrobefehle und die Übersetzung in Mikrobefehls-Folgen geschieht, müssen wir zunächst das (bislang versteckte) Steuerwerk betrachten.

Pd Johnny with CU.png

Wichtig sind hierbei vor allem das so genannte Befehlsregister (Command Register), der Programmzähler (Program Counter) und der so genannte Mikrobefehlsspeicher (Micro Code). Diese sind über Leitungen miteinander verbunden und für den Transport von Daten zwischen diesen Bestandteilen und zu den beiden Bussen braucht man noch ein paar weitere Mikrobefehle.

Die Mikrobefehle des Steuerwerks

Arbeitsauftrag 9
a) Mikrobefehle des Steuerwerks

Legen Sie die Zahl 04.142 auf den Datenbus, was dem Befehl „SAVE 142“ entspricht.

Führen Sie dann (in der hier gegebenen Reihenfolge) die folgenden Mikrobefehle aus und ordnen Sie zu, was dabei jeweils geschieht:

db->ins Businhalt ins Befehlsregister [Instruction Register] kopieren
ins->mc Mikrobefehlszähler [Micro Counter] auf das Zehnfache der Befehlsnummer setzen
ins->ab Adressteil des Befehls im Befehlsregister [Instruction Register] auf den Adressbus kopiereren
pc++ Programmzähler [Program Counter] um 1 erhöhen
pc->ab Inhalt des Programmzählers [Program Counter] auf den Adressbus kopieren
ins->pc Inhalt Adressteil im Befehlsregisters [Instruction Register] auf den Programmzähler [Program Counter] kopieren
mc:=0 Mikrobefehlszähler [Micro Counter] auf den Wert 0 setzen.


b) Ganz besondere Mikrobefehle

1. Testen Sie den Mikrobefehl „=0:pc++“, einmal, wenn der Akku den Wert 0 hat, einmal, wenn sie einen von 0 verschiedenen Wert hat.

Der Befehlszähler wird immer um 1 erhöht.
Der Befehlszähler wird um 1 erhöht, aber nur dann, wenn der Akku den Wert 0 hat.
Wenn der Akku den Wert 0 hat wird, der Programmzähler um 1 erhöht, ansonsten um 2.

2. Wenn man auf den Taster One-Micro-Step klickt (Play-Button oben rechts mit dem \mu-Symbol), passiert folgendes:

Der gelb markierte Makrobefehl wird ausgeführt und der Befehlszähler (Prog. Counter) wird um 1 erhöht.
Der Akkumulator-Wert wird um 1 erhöht und der Wert auf den Datenbus gelegt.
Der gelb markierte Mikrobefehl wird ausgeführt und der Mikrobefehlszähler (über dem Micro-Code) wird dann um 1 erhöht. Die Markierung verschiebt sich.

Punkte: 0 / 0


Der von Neumann-Zyklus

In Arbeitsauftrag 9 haben Sie gesehen, dass die Befehlsnummer des Befehls im Befehlsregister (Command Register) beim Klick ins->mc in den Micro-Code-Zähler kopiert wird (multipliziert mit 10).

Bei jedem Klick auf One Micro Step wird der Befehl, den der Mikro-Code-Zähler nummeriert (und der gelb markiert ist) ausgeführt. Dann wird der Mikro-Code-Zähler um 1 erhöht. Auf diese Weise werden nacheinander alle zum Makrobefehl gehörenden Mikrobefehle ausgeführt. Wenn die Liste der zugehörenden Mikrobefehle abgearbeitet ist, muss der nächste Befehl ins Befehlsregister (Command Register) geladen werden. Dies erfolgt ebenfalls über die Mikrobefehle, die Sie in Arbeitsauftrag 9 kennen gelernt haben.

Die Folge von Mikrobefehlen, die zum Laden des Befehls ins Befehlsregister notwendig ist, steht im Mikrobefehlsspeicher ab der Speicherstelle 000 und werden im Johnny-Simulator mit „fetch“ bezeichnet.


Arbeitsauftrag 10
a) Die Mikrobefehle des fetch-Bereichs

Erläutern Sie, wofür die einzelnen Befehle des fetch-Bereichs des Mikrobefehlsspeichers notwendig sind:

pc->ab Die Speicherzelle mit dem richtigen Befehl aus dem RAM auswählen.
ram->db Befehl im RAM auf den Datenbus legen
db->ins Businhalt ins Befehlsregister [Instruction Register] kopieren
ins->mc Mikrobefehlszähler [Micro Counter] gemäß der Befehlsnummer setzen

b) Abschluss von Mikrobefehlssequenzen

Die Mikrobefehls-Folge für jeden Makrobefehl wie TAKE, ADD, SUB usw. endet mit den beiden Mikrobefehlen pc++ und mc:=0.


1. Der Befehl pc++ sorgt dafür, ...

... dass der Wert im Akkumulator um genau 1 erhöht wird.
... dass demnächst der nächste Befehl und nicht derselbe wie bisher abgearbeitet wird.
... dass der Wert auf dem Datenbus um 1 erhöht wird

2. Der Befehl mc:=0 sorgt dafür, ...

... dass der Datenbus auf den Wert 0 gesetzt wird.
... dass der Adressbus auf den Wert 0 gesetzt wird.
... dass damit begonnen wird, den nächsten Befehl ins Befehlsregister zu holen.

Punkte: 0 / 0



Das abwechselnde Laden des nächsten Befehls und das Ausführen dieses Befehls wird auch als „von-Neumann-Zyklus“ bezeichnet:

Pd Johnny von Neumann Cycle.png


Weitere Experimente mit JOHNNY und darüber hinaus

Arbeitsauftrag 11
  1. Eigene Befehle in JOHNNY
    Das Simulationsprogramm JOHNNY erlaubt es, eigene Makrobefehle aus einzelnen Mikrobefehlen zusammenzubasteln. Wie genau, ist im Handbuch dokumentiert, das dem Programm beiliegt. Konstruiere aus Mikrobefehlen einen Befehl zum Verdoppeln einer Speicherzelle. Überlege Dir auch andere Makrobefehle, die vielleicht nützlich sein könnten und realisiere sie als Abfolge von Mikrobefehlen. Natürlich musst Du die Befehle dann auch mit entsprechenden Maschinenprogrammen testen.
  2. Viren in JOHHNY?
    Keine Angst. Das Programm JOHNNY sollte virenfrei sein, wenn es von den genannten Seiten heruntergeladen wurde. Die Frage ist vielmehr: Kann man in JOHNNY selbst einen Computervirus als Maschinenprogramm schreiben. Also ein Programm, dass sich selbst im Speicher kopiert. Du kannst es ja einmal ausprobieren. Für den PC, auf dem JOHNNY läuft, ist das natürlich nicht gefährlich, denn der PC "spricht" eine ganz andere Maschiensprache.
  3. BONSAI -- ein anderer Schulcomputer
    JOHNNY ist ein sehr vereinfachter Simulator für Schulzwecke: Echte Computer sind deutlich komplizierter. Ein Computer, der ebenfalls für Schulzwecke entworfen wurde, aber näher an der "echten Wirklichkeit" ist, ist der BONSAI-Rechner. Informieren Sie sich über diesen Rechner, über Ähnlichkeiten und Unterschiede zu JOHNNY.

Literatur

  1. Precht, M. u.a.: EDV-Grundwissen: Eine Einführung in Theorie und Praxis der modernen EDV. Addison-Wesley, 2004. ISBN 978-3827321299
  2. Wieland, H.R.: Computergeschichte(n) - nicht nur für Geeks. Galileo Computing, 2011. ISBN 978-3836215275
  3. Cerzuzzi, P.: The History of Modern Computing. MIT Press, 2003. ISBN 978-0262532037

Dank

Ein großer Dank an alle, die bei der Entwicklung von JOHNNY und der Unterrichtsmaterialien durch konstruktive Vorschläge und Anregungen für Erweiterungen sowie Fehlerberichte mitgeholfen haben.