Zum Hauptinhalt springen

Maschinennahe Programmierung

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.

Konrad Zuse mit dem Z3, fertiggestellt 1941
Konrad Zuse mit dem Z3, fertiggestellt 1941@
Highlight: 4 Dezimalstellen genaue Ergebnisse, Programme: In Form eines Lochstreifens
Eckert & Mauchly mit dem "ENIAC", fertiggestellt 1946
Eckert & Mauchly mit dem "ENIAC", fertiggestellt 1946@
Highlight: 5000 Additionen pro Sekunde, Programme: In Form von Steckbrettern

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.

InstruktionMnemonicOpcodeErklärung
HALTHLT000Programm beenden
AddierenADD1xxAddiere den Inhalt von Speicherzelle xx zum Akkumulator
SubtrahierenSUB2xxSubtrahiere den Inhalt von Speicherzelle xx vom Akkumulator
SpeichernSTA3xxSpeichere den Inhalt des Akkumulators in Speicherzelle xx
LadeLDA5xxLade den Inhalt von Speicherzelle xx in den Akkumulator
Gehe zu (Branch Always)BRA6xxSetze den Programmzähler auf xx (also spring als nächstes dorthin)
Gehe wenn 0 (Branch if Zero)BRZ7xxWenn der Akkumulator 0 enthält spring als nächstes nach xx
Gehe wenn >=0 (Branch if Positive)BRP8xxWenn der Akkumulator positiv ist spring als nächstes nach xx
EingabeINP901Hol vom Operateur einen Eingabe und schreib sie in den Akkumulator
AusgabeOUT902Gib den Inhalt des Akkumulators aus
Freier Speicherort (Data Location)DATWeist 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.

Kommentare

Leider können die Online-Simulatoren keine Kommentare verarbeiten. Sie müssen die Kommentare vor dem Ausführen entfernen 😓

Kommentare Entfernen

Assembler-Code

Aufgabe IO

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.

Aufgabe I
  1. Schreiben Sie ein Programm, das zwei Zahlen eingeben lässt und dann zusammenzählt

  2. 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
Aufgabe II

Schreiben Sie ein Programm, das eine Zahl holt und dann bis 1 herunterzählt

SSR
Aufgabe III

Schreiben Sie ein Programm, das eine Zahl holt und dann bis 10 hochzählt

SSR
Aufgabe IV: Zahlenraten

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.

SSR
Zusatz ⭐

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.

Zwei Zahlen multiplizieren 1

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

Es gibt direkt einen Befehl, welcher die Multiplikation zweier Zahlen aus dem RAM durchführt und das Resultat zurück in den RAM schreibt:
MULT 5, 14 
Nach der Ausführung dieser Instruktion steht das Resultat in Speicherzelle 5. Es führt also im wesentlichen a = a * b aus.

RISC

Hier gibt es nur primitive Instruktionen - Zahlen aus dem RAM in ein Register laden, Zahlen von einem Register in den RAM schreiben, Zahlen in einem Register multiplizieren, etc. Dies führt zu 4 Zeilen Code:
LOAD A, 5
LOAD B, 14
MUL A, A, B ; multipliziere A und B
; und speichere das Resultat in A
STORE A, 5
RISC oder CISC?

Halten Sie fest, was die Vor- und Nachteile von RISC und CISC Prozessoren sind. Welche technologie wird heute in modernen Prozessoren verwendet?

SSR

Footnotes

  1. Inspiriert von diesem Artikel