Grundlagen

Was ist ein Computer?

Vom Schalter zum Smartphone: wie aus Strom an und Strom aus Zahlen werden, aus Zahlen Befehle – und warum eine Maschine, die nur addieren und springen kann, im Prinzip alles berechnen kann.

Lesestand

Ein Computer ist eine Maschine, die Befehle aus ihrem Speicher holt und ausführt – einen nach dem anderen, milliardenfach pro Sekunde. Programm und Daten liegen dabei im selben Speicher, beides sind nur Zahlen. Diese Idee heißt Von-Neumann-Architektur, und fast jeder heutige Computer folgt ihr.

Ganz unten besteht alles aus Schaltern, die an oder aus sind – Bits. Aus Schaltern baut man Logikgatter, aus Gattern Addierer, aus Addierern und Speicher einen Prozessor. Und weil so ein Prozessor rechnen, speichern und springen kann, kann er im Prinzip alles berechnen, was überhaupt berechenbar ist.

Die Grundidee

Ein Taschenrechner rechnet auch. Was macht einen Computer anders? Er ist programmierbar: Was er tut, steht nicht in seiner Verdrahtung, sondern in einer Liste von Befehlen, die man austauschen kann. Heute Textverarbeitung, morgen Schach, übermorgen ein Sprachmodell – dieselbe Hardware.

Der entscheidende Kniff stammt aus einem Bericht von John von Neumann aus dem Jahr 1945: Die Befehle liegen im selben Speicher wie die Daten. Ein Programm ist also selbst nur Daten. Damit kann ein Programm ein anderes laden, ein Compiler kann Programme erzeugen, ein Betriebssystem kann Programme starten – und ein Virus kann sich in fremde Programme schreiben.

Prozessor (CPU)Steuerwerkholt und dekodiert BefehleRechenwerk (ALU)rechnet, vergleichtBusSpeicherProgramm und Daten –beides nur ZahlenEin- und AusgabeTastatur, Bildschirm,SSD, Netzwerk
Die Von-Neumann-Architektur. Moderne Prozessoren sind unendlich viel komplizierter – das Grundschema gilt immer noch.

Alles ist eine Zahl

Ein Bit ist die kleinste Einheit: an oder aus, 1 oder 0. Acht Bits sind ein Byte und können 256 verschiedene Werte darstellen. Was ein Byte bedeutet, steht nicht im Byte selbst – das entscheidet allein das Programm, das es liest. Klick die Bits an:

Ein Byte, viele Bedeutungen

Probier 127 und dann 128: Als int wächst die Zahl, als Java-byte springt sie ins Negative.

Daher kommen ein paar Dinge, die jeder Java-Entwickler schon gesehen hat:

  • Hexadezimal ist nur eine bequeme Schreibweise: Eine Hex-Ziffer steht für genau 4 Bit, ein Byte also für zwei Hex-Ziffern. 0xFF = 1111 1111 = 255.
  • Negative Zahlen stellt man im Zweierkomplement dar: Das höchste Bit zählt negativ. Deshalb ist in Java Integer.MAX_VALUE + 1 == Integer.MIN_VALUE – die Zahl läuft über, ohne Fehlermeldung.
  • Kommazahlen (double) werden binär als Mantisse und Exponent gespeichert. Viele Dezimalbrüche lassen sich binär nicht exakt darstellen, so wie 1/3 dezimal nicht. Deshalb gilt:
System.out.println(0.1 + 0.2);                 // 0.30000000000000004
System.out.println(0.1 + 0.2 == 0.3);          // false
System.out.println(Integer.MAX_VALUE + 1);       // -2147483648
System.out.println((byte) 200);                  // -56
// Für Geld: BigDecimal oder ganze Cent als long

Text ist ebenfalls nur eine Tabelle von Zahlen: In ASCII ist „A“ die 65. Heute benutzt man Unicode mit über 150 000 Zeichen, gespeichert meist als UTF-8 – ein Zeichen braucht dort 1 bis 4 Bytes. Bilder sind Zahlen für Rot, Grün und Blau je Pixel. Und Befehle für den Prozessor sind auch nur Zahlen.

Vom Schalter zum Rechnen

Physisch ist ein Bit eine Spannung: hoch oder niedrig. Geschaltet wird mit Transistoren – winzigen elektronischen Schaltern, bei denen eine Spannung an einem Anschluss den Strom zwischen zwei anderen ein- oder ausschaltet. Aus wenigen Transistoren baut man Logikgatter:

&

UND

Ausgang 1, wenn beide Eingänge 1 sind. Wie a && b.

≥1

ODER

Ausgang 1, wenn mindestens einer 1 ist. Wie a || b.

=1

XOR

Ausgang 1, wenn genau einer 1 ist. Wie a ^ b.

Mehr braucht man nicht, um zu rechnen. Binär addieren funktioniert wie schriftliches Addieren in der Schule, nur einfacher: 0+0=0, 0+1=1, 1+1=10 – also 0, „eins gemerkt“. Ein Volladdierer addiert zwei Bits und den Übertrag von der Stelle davor. Klick auf die Eingänge:

Ein Volladdierer aus fünf Gattern

Orange Leitung = 1. Für 64-Bit-Zahlen schaltet man 64 solcher Addierer hintereinander; echte Prozessoren benutzen schnellere Varianten, die den Übertrag vorausberechnen.

So geht es Schicht für Schicht weiter: Aus Gattern werden Addierer, aus rückgekoppelten Gattern Speicherzellen (Flipflops), aus beidem ein Rechenwerk. Ein aktueller Prozessor enthält davon unvorstellbar viele: Der erste Mikroprozessor, der Intel 4004 von 1971, hatte rund 2 300 Transistoren. Apples M3 Max von 2023 hat 92 Milliarden.

Holen, dekodieren, ausführen

Ein Prozessor macht im Kern immer dasselbe, in einer endlosen Schleife: den nächsten Befehl aus dem Speicher holen, herausfinden, was er bedeutet (dekodieren), ihn ausführen. Ein Register namens Befehlszähler (PC, program counter) merkt sich, wo der nächste Befehl steht. Den Takt gibt ein Quarz vor – bei 4 GHz vier Milliarden Mal pro Sekunde.

Hier ist eine Mini-CPU mit 16 Byte Speicher und sieben Befehlen. Programm und Daten liegen im selben Speicher; die CPU kann sie nicht unterscheiden. Sie führt einfach aus, worauf der Befehlszähler zeigt.

Mini-CPU zum Durchsteppen
HolenDekodierenAusführen
Befehlszähler (PC)0
Befehlsregister (IR)–
Akkumulator (ACC)0
Ausgeführte Befehle0
Befehlssatz anzeigen
CodeBefehlBedeutung
0xHLTanhalten
1aLDA alade Speicherzelle a in den Akkumulator
2aADD aaddiere Zelle a zum Akkumulator
3aSUB aziehe Zelle a ab
4aSTA aspeichere den Akkumulator in Zelle a
5aJMP aspringe zu Adresse a
6aJZ aspringe zu a, wenn der Akkumulator 0 ist

Ein Befehl ist ein Byte: die erste Hex-Ziffer ist der Befehl, die zweite die Adresse. 1E heißt also „LDA 14“.

Mit nur diesen Befehlen – rechnen, laden, speichern, springen, bedingt springen – lässt sich jedes Programm schreiben, das es gibt; es wird nur entsprechend lang. Der bedingte Sprung JZ ist dabei das Entscheidende: Er macht aus einer Rechenmaschine eine, die Schleifen und if kann.

Echte Prozessoren sind trickreicher: Sie bearbeiten mehrere Befehle gleichzeitig wie am Fließband (Pipelining), raten, wohin ein Sprung geht (Sprungvorhersage), und führen Befehle in anderer Reihenfolge aus, wenn das Ergebnis dasselbe bleibt. Nach außen sieht es trotzdem so aus, als liefe genau diese einfache Schleife.

Die Bauteile und ihr Tempo

C

CPU

Wenige, sehr flexible Kerne (heute meist 4 bis 24 im Laptop), jeder mit eigenen schnellen Zwischenspeichern, den Caches.

R

Arbeitsspeicher (RAM)

Schnell, aber flüchtig: Ohne Strom ist alles weg. Hier liegen laufende Programme und ihre Daten.

S

SSD

Dauerhaft, aber viel langsamer als RAM. Hier liegen Programme und Dateien, wenn sie nicht laufen.

G

GPU

Tausende einfache Rechenwerke, die alle dasselbe auf vielen Daten tun – gebaut für Grafik, heute auch das Arbeitspferd der KI.

B

Busse

Die Verbindungen: Speicherbus zum RAM, PCI Express zu GPU und SSD, USB nach außen.

F

Firmware

Ein kleines Programm im Chip auf der Hauptplatine (UEFI), das beim Einschalten alles prüft und das Betriebssystem startet.

Der wichtigste Unterschied zwischen diesen Bauteilen ist ihre Geschwindigkeit – und der ist so gewaltig, dass man ihn sich kaum vorstellen kann. Darum hier ein Trick: Tu so, als dauerte ein einziger Prozessortakt eine Sekunde.

Wenn ein Takt eine Sekunde wäre

Größenordnungen, gerundet; echte Werte schwanken je nach Hardware. Die Balken sind logarithmisch – linear wären alle oberen Zeilen unsichtbar.

Daraus folgt einer der wichtigsten Sätze der Informatik-Praxis: Rechnen ist billig, Daten holen ist teuer. Ein Prozessor wartet die meiste Zeit auf Daten. Darum gibt es Caches, darum ist ein Durchlauf durch ein Array so viel schneller als durch eine verkettete Liste, und darum wartet ein Server meistens aufs Netzwerk.

Für Entwickler übersetzt: der Weg einer Java-Zeile

Ein Prozessor versteht kein Java. Was mit dieser Methode passiert, bis sie wirklich läuft:

Quelltextdu
static int sum(int a, int b) {
    int c = a + b;
    return c;
}
Bytecodejavac, sichtbar mit javap -c
iload_0      // a auf den Operandenstapel
iload_1      // b auf den Operandenstapel
iadd         // beide addieren
istore_2     // Ergebnis in c
iload_2
ireturn
MaschinencodeJIT-Compiler zur Laufzeit, x86-64, sinngemäß
mov  eax, esi   // a ins Register eax
add  eax, edx   // b dazuaddieren
ret             // zurück, Ergebnis steht in eax
Byteswas die CPU wirklich liest
89 F0  01 D0  C3

Der Bytecode ist der Befehlssatz einer gedachten Maschine, der JVM – sie arbeitet mit einem Stapel statt mit Registern, wie die Mini-CPU oben mit ihrem Akkumulator. Erst der JIT-Compiler übersetzt häufig benutzte Methoden in echten Maschinencode für genau diesen Prozessor. Und die fünf Bytes am Ende sind derselbe Stoff wie die Bytes im Widget oben: Zahlen, die zufällig als Befehle gemeint sind.

HardwareIn Java sichtbar als
Wortbreite 64 Bitlong und Referenzen; int bleibt bewusst 32 Bit, auf jeder Plattform gleich
ZweierkomplementÜberlauf ohne Exception; Math.addExact wirft eine, wenn man es will
Gleitkomma nach IEEE 754float, double, NaN, -0.0
Bitoperationen& | ^ ~ << >> >>> – direkt in Maschinenbefehle übersetzt
Byte-ReihenfolgeJava rechnet intern unabhängig davon; beim Lesen fremder Binärdaten hilft ByteBuffer.order()

Ausblick: Was kann ein Computer überhaupt?

1936 – bevor es einen einzigen elektronischen Computer gab – beschrieb Alan Turing eine gedachte Maschine: ein unendliches Band mit Zeichen, ein Lese-Schreib-Kopf und eine Tabelle von Regeln. Die Turingmaschine ist absurd unpraktisch, aber sie kann alles berechnen, was überhaupt berechenbar ist. Und jeder Computer, der rechnen, speichern und bedingt springen kann, kann eine Turingmaschine nachbilden – man nennt ihn Turing-vollständig.

Daraus folgt etwas Verblüffendes: Ein Smartphone und ein Supercomputer können dieselben Probleme lösen. Sie unterscheiden sich nur darin, wie schnell und mit wie viel Speicher. Und Turing zeigte gleich mit, dass es Fragen gibt, die kein Computer je beantworten kann – etwa, ob ein beliebiges Programm irgendwann anhält. Mehr dazu in einem späteren Eintrag.

Kurze Geschichte

  • 1837Charles Babbage entwirft die Analytical Engine, einen mechanischen, programmierbaren Rechner. Gebaut wird sie nie; Ada Lovelace schreibt 1843 ein Programm für sie.
  • 1936Alan Turing beschreibt die Turingmaschine.
  • 1941Konrad Zuse stellt in Berlin die Z3 fertig – den ersten funktionsfähigen, frei programmierbaren, vollautomatischen Digitalrechner.
  • 1945ENIAC in den USA; John von Neumann beschreibt das Prinzip „Programm im Speicher“.
  • 1947Der Transistor wird bei den Bell Labs erfunden und ersetzt bald die Röhre.
  • 1971Intel 4004: der ganze Prozessor auf einem Chip.
  • 1981Der IBM-PC macht den Computer zum Bürogerät.
  • 2007Das Smartphone macht ihn zum Taschengerät – heute die häufigste Form des Computers.

Häufige Irrtümer

„Mehr Gigahertz heißt schneller.“ – Nur bei sonst gleicher Bauweise. Wie viel ein Prozessor pro Takt schafft, wie viele Kerne er hat und wie groß seine Caches sind, zählt oft mehr.
„Speicher ist Speicher.“ – Arbeitsspeicher und SSD unterscheiden sich um einen Faktor von etwa tausend in der Zugriffszeit. „Mein Handy hat 256 GB Speicher“ meint die SSD, nicht den RAM.
„Der Computer versteht Java.“ – Er versteht nur Maschinencode für seinen Prozessortyp. Alles andere wird übersetzt – vorher oder zur Laufzeit.
„Computer rechnen exakt.“ – Mit ganzen Zahlen ja, bis zum Überlauf. Mit Kommazahlen nur näherungsweise: 0.1 + 0.2 ist nicht 0.3.
„Ein Supercomputer kann Dinge, die mein Laptop grundsätzlich nicht kann.“ – Er kann sie nur schneller. Beide sind Turing-vollständig.

Verwandte Begriffe