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.
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.
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:
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 longText 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.
ODER
Ausgang 1, wenn mindestens einer 1 ist. Wie a || b.
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:
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.
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
CPU
Wenige, sehr flexible Kerne (heute meist 4 bis 24 im Laptop), jeder mit eigenen schnellen Zwischenspeichern, den Caches.
Arbeitsspeicher (RAM)
Schnell, aber flüchtig: Ohne Strom ist alles weg. Hier liegen laufende Programme und ihre Daten.
SSD
Dauerhaft, aber viel langsamer als RAM. Hier liegen Programme und Dateien, wenn sie nicht laufen.
GPU
Tausende einfache Rechenwerke, die alle dasselbe auf vielen Daten tun – gebaut für Grafik, heute auch das Arbeitspferd der KI.
Busse
Die Verbindungen: Speicherbus zum RAM, PCI Express zu GPU und SSD, USB nach außen.
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.
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:
static int sum(int a, int b) {
int c = a + b;
return c;
}javap -ciload_0 // a auf den Operandenstapel
iload_1 // b auf den Operandenstapel
iadd // beide addieren
istore_2 // Ergebnis in c
iload_2
ireturnmov eax, esi // a ins Register eax
add eax, edx // b dazuaddieren
ret // zurück, Ergebnis steht in eax89 F0 01 D0 C3Der 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.
| Hardware | In Java sichtbar als |
|---|---|
| Wortbreite 64 Bit | long 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 754 | float, double, NaN, -0.0 |
| Bitoperationen | & | ^ ~ << >> >>> – direkt in Maschinenbefehle übersetzt |
| Byte-Reihenfolge | Java 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
0.1 + 0.2 ist nicht 0.3.