Offensichtlich ist die Turingmaschine nicht für eine konkrete Realisierung geeignet. In den Dreissigerjahren des 20. Jahrhunderts begannen aber sowohl in Deutschland wie auch in den USA verschiedene Forscher mit dem Bau eines funktionierenden Computers.
Prinzipiell enthalten alle diese (und auch die heutigen) Computer die gleichen Bestandteile:
Speicher
Eine Reihe von "Speicherzellen", die nummeriert sind und sowohl die Instruktionen als auch Daten enthalten können. Der Inhalt dieser Speicherzellen musste mit Kabeln gesetzt werden!
IO
Eine Ein- und Ausgabeeinheit (Input/Output)
Recheneinheit
Die Recheneinheit erlaubt, mit Hilfe von Registern einfache Berechnungen auszuführen. Das erste Register wird in der Regel "Akkumulator" genannt.
Steuereinheit
Die Steuereinheit arbeitet im wesentlichen mit einem Speicher, in dem die Nummer der aktuellen Speicherzelle (Programmzähler, "Program counter") steht.
Taktgeber
Ein Taktgeber, der die Ausführung steuert.
Um einen Schritt in einem Programm auszuführen muss der Computer mehrere Schritte nacheinander durchführen:
Fetch
1. Hole den Inhalt der Speicherzelle, deren Nummer im Programmzähler steht
2. Erhöhe den Programmzähler um 1 (damit er auf der nächsten Instruktion steht, wenn die Aktion fertig ist)
Decode
3. Decodiere die Instruktion: Was ist mit welchen Daten zu tun?
Execute
4. Führe die Instruktion aus
5. Speichere das Resultat der Instruktion an geeigneter Stelle
6. Wiederhole oder fertig
Der Little Man Computer
Damit wir diese Aspekte genauer anschauen können, simulieren wir einen einfachen Rechner. Der "Little Man Computer" LMC eignet sich dazu sehr gut. Es gibt mehrere Online-Versionen des LMC's, die alle ähnlich funktionieren.
Die Benutzeroberfläche enthält jeweils drei Teile:
Editor
Im LMC Editor werden die Befehle in Form von Mnemonics eingegeben
Assembler
Der Assembler übersetzt diese Mnemonics in die Zahlen (Opcodes und Operanden) schreibt diese in die Speicherzellen
Simulator
Der Simulator führt die Instruktionen dann aus.
Instruction Set
Der LMC kennt 11 verschiedene Instruktionen und hat einen Speicher von 100 Zellen, welche von 00 bis 99 nummeriert werden. Mit diesen Instruktionen lassen sich alle Aktionen des Fetch-Decode-Execute Zyklus ausführen.
Instruktion | Mnemonic | Opcode | Erklärung |
---|---|---|---|
HALT | HLT | 000 | Programm beenden |
Addieren | ADD | 1xx | Addiere den Inhalt von Speicherzelle xx zum Akkumulator |
Subtrahieren | SUB | 2xx | Subtrahiere den Inhalt von Speicherzelle xx vom Akkumulator |
Speichern | STA | 3xx | Speichere den Inhalt des Akkumulators in Speicherzelle xx |
Lade | LDA | 5xx | Lade den Inhalt von Speicherzelle xx in den Akkumulator |
Gehe zu (Branch Always) | BRA | 6xx | Setze den Programmzähler auf xx (also spring als nächstes dorthin) |
Gehe wenn 0 (Branch if Zero) | BRZ | 7xx | Wenn der Akkumulator 0 enthält spring als nächstes nach xx |
Gehe wenn >=0 (Branch if Positive) | BRP | 8xx | Wenn der Akkumulator positiv ist spring als nächstes nach xx |
Eingabe | INP | 901 | Hol vom Operateur einen Eingabe und schreib sie in den Akkumulator |
Ausgabe | OUT | 902 | Gib den Inhalt des Akkumulators aus |
Freier Speicherort (Data Location) | DAT | Weist dem nächstmöglichen, freien Speicherplatz im RAM einen Name zu. Optional kann auch der Zahlenwert des zugewiesenen Speicherplatzes angegeben werden. |
Editor und Assembler kennen symbolische Links; Speichezellen können Namen haben und mit diesem angesprochen werden. Kommentare werden mit einem #
gekennzeichnet.
Ein erstes Programm soll das veranschaulichen. Es fragt nach einer Eingabe, zählt dann 5 dazu und gibt das Resultat aus.
;
; Programm Ein- und Ausgabe
;
INP ; Eingabe holen und in akk speichern
ADD five ; fünf dazu
OUT ; ausgeben
HLT ; fertig
five DAT 5 ; 5 zum Addieren
Im Speicher stehen jetzt folgende Zahlen:
00 901 (INP; Eingabe holen und in Akk laden)
01 104 (ADD 04; addiere den Inhalt von Speicherzelle 04 zum Akk)
02 902 (OUT; gib Akk aus)
03 000 (HLT; Programm beenden)
04 005 (Zahl 5; Datenzelle)
Mit "Run" kann das Programm nun ausgeführt werden.
Leider können die Online-Simulatoren keine Kommentare verarbeiten. Sie müssen die Kommentare vor dem Ausführen entfernen 😓
Kommentare Entfernen
Assembler-Code
Simulator
Geben sie das obige Programm im Editor ein, speichern Sie es und lassen Sie es dann vom Assembler übersetzen. Mit "Load" können Sie es dann in den Simulator holen und dort ausführen.
-
Schreiben Sie ein Programm, das zwei Zahlen eingeben lässt und dann zusammenzählt
-
Schreiben Sie ein Programm, das drei Zahlen eingeben lässt und dann zusammenzählt
Verzweigungen
Etwas komplizierter wird es mit Verzweigungen: Ein Programm, das eine Zahl holt und dann bis 0 herunterzählt:
Betrachten Sie dieses Programm genau, führen Sie es aus und wenn Sie es verstanden haben, versuchen Sie die weiteren Übungen zu lösen.
INP
OUT ; Zahl selber mal ausgeben
anfang SUB one
BRP ausgabe ; springe nach ausgabe wenn akk grösser/gleich 0
HLT ; fertig
ausgabe OUT
BRA anfang ; springe nach anfang
one DAT 1 ; Zahl 1
Schreiben Sie ein Programm, das eine Zahl holt und dann bis 1 herunterzählt
Schreiben Sie ein Programm, das eine Zahl holt und dann bis 10 hochzählt
a. Der Computer merkt sich eine Zahl und die Benutzer:in muss sie erraten. Der Computer teilt der Spieler:in dabei mit:
zu hoch
Output
100
zu tief
Output
-100
richtig
Output
200
b. Ergänzen Sie ihr Programm um einen Zähler für die Anzahl Versuche.
Weitere Ideen:
-
Fibonacci-Zahlen 0,1,1,2,3,5,8...
-
Pascalsches Dreieck
RISC vs CISC
In heutigen Computern wird grundsätzliche zwischen RISC und CISC Prozessoren unterschieden. RISC Prozessoren (für Reduced Instruction Set Computer) haben ein eher einfaches Instruktionenset das nur wenige Instruktionen kennt (RISC I hat nur 32 Instruktionen). Dies führt dazu, dass für eine Simple Aufgabe mehrere Instruktionen notwendig sind. CISC (für Complex Instruction Set Computer) Prozessoren haben im Gegensatz dazu ein sehr umfangreiches Instruktionenset, das viele spezialisierte Instruktionen kennt, so dass Programme mit weniger Instruktionen möglich sind.
a = 5
b = 3
# wir betrachten folgende Operation
a = a * b # => in a steht jetzt 15
Für diese Betrachtung nehmen wir folgende (vereinfachte) Architektur an:
Die Register stellen Speicherzellen im Prozessor dar, auf welche die Instruktionen direkt zugreifen können. Im LMC gibt es nur ein einziges Register, den Akkumulator. In modernen Prozessoren gibt es mehrere Register, die für verschiedene Zwecke verwendet werden können.
CISC
MULT 5, 14
a = a * b
aus.RISC
LOAD A, 5
LOAD B, 14
MUL A, A, B ; multipliziere A und B
; und speichere das Resultat in A
STORE A, 5
Halten Sie fest, was die Vor- und Nachteile von RISC und CISC Prozessoren sind. Welche technologie wird heute in modernen Prozessoren verwendet?
Footnotes
-
↩
Inspiriert von diesem Artikel
Maschinennahe Programmierung