Rechnerarchitektur
Rechnermodell
Das Bild des Rechnermodells zeigt
- die CPU mit ihren Hauptkomponenten
- Steuerwerk und
- Rechenwerk
sowie die Komponenten
- Hauptspeicher und
- E/A-Steuerung
Sie sind durch verschiedene Leitungen miteinander verbunden:
- Datenbus
- transportiert Daten zwischen CPU und anderen Komponenten,
teilweise auch zwischen anderen Komponenten untereinander (s.u. DMA)
- Addressbus
- transportiert Adressen von der CPU zum Hauptspeicher, sowie zu
E/A-Interfaces, teilweise auch von E/A-Interfaces zum Hauptspeicher (s.u. DMA)
- Steuerbus
- fasst die Steuerleitungen zusammen, die die Interaktion zwischen
den Komponenten koordinieren
Von-Neumann-Prinzipien
John von Neumann postulierte grundlegende Architekturprinzipien auf,
nach denen Computer möglichst gebaut werden sollten, um universell
nutzbar zu sein:
- Die Grundkomponenten des Computers sind wie oben beschrieben.
- Befehle und Daten liegen in einem einheitlichen gemeinsamen Hauptspeicher.
- Hauptspeicher soll aus Datenworten fester Breite bestehen.
- Hauptspeicherworte sind wahlfrei adressierbar (RAM).
- Sequenzielle Abarbeitung
- Die Ausführung eines Programms geschieht in der Regel durch
Interpretation im Speicher aufeinander folgender Befehlscodes.
- Sprungbefehle setzen davon abweichend die Bearbeitung an
anderer Stelle fort.
- Mit jedem Befehl wird ein Datenwort verarbeitet.
Programmiermodell eines Prozessors (Intel)
Das Programmiermodell eines Prozessors ist eine Abstraktion,
die nur diejenigen Komponenten enthält, die für die Programmierung
sichtbar sind, also insbesondere die vom Code explizit ansprechbaren
Register des Prozessors.
Der Intel 8086 hat folgende Register:
| 8 bit
| 8 bit
|
AX:
| AH
| AL
|
BX:
| BH
| BL
|
CX:
| CH
| CL
|
DX:
| DH
| DL
|
|
| SP (stack pointer)
|
| BP (base pointer)
|
| SI (source index)
|
| DI (destination index)
|
|
| IP (instruction pointer)
|
|
CS (code segment)
|
DS (data segment)
|
SS (stack segment)
|
ES (extra segment)
|
|
| Flags: S, Z, O, C, ...
|
Die Flags geben Eigenschaften des Ergebnisses einer der letzten
Instruktionen an, z.B. das Vorzeichen (S, sign), ob das Ergebnis
Null war (Z, zero), ob ein Überlauf (bei Rechnung mit Vorzeichen)
stattgefunden hat (O, overflow), ob ein Überlauf (bei Rechnung ohne Vorzeichen)
stattgefunden hat (C, carry).
Assemblerprogrammierung (Intel), Einführung
; Lege Anfagsadresse der Codegenerierung fest
; (altmodische Technik, unter MSDOS für "kleines Speichermodell"
; geeignet, bei dem das Programm bis zu 64KB groß ist)
ORG 100h
MOV AX,CS ; Adressbasis (Segmentadresse) kopieren,
MOV DS,AX ; ... korrekte Adressierung der Daten sicherstellen
JMP start ; Datenbereich überspringen, zum Programmanfang
; Datenbereich
zahl1: DB 5 ; Variable mit 1 Byte und Anfangsinhalt 05h
zahl2: DW 3456 ; Variable mit 1 Wort (2 Byte) und Anfangsinhalt 0D80h
text1: DB 'Hallo',13,10,'$' ; Zeichenfolge (8 Bytes):
; 5 Bytes mit ASCII-Codes für 'H' 'a' 'l' 'l' 'o'
; 2 Bytes mit ASCII-Codes für CR/LF (Zeilenwechsel)
; 1 Byte mit '$'-Zeichen als Endemarkierung
; Programm
start:
; Beispiel für 8-Bit-Ladebefehl:
MOV AL,[zahl1] ; AL ← M[zahl1]
; Beispiel für 16-Bit-Ladebefehl:
MOV AX,[zahl2] ; AL ← M[zahl2]
; Ausgabe des Begrüßungstextes:
MOV DX,text1 ; DX ← Adresse des Textes
MOV AH,9 ; AH ← Code der MSDOS-Funktion "WRITE STRING"
INT 21h ; MSDOS aufrufen
; Programm beenden
INT 20h
; Ende der Assembler-Übersetzung
END
Hinter "end" kann hier jetzt z.B. das Lied von der Glocke stehen.
Befehlssatz eines Prozessors
Der Befehlssatz eines Prozessors lässt sich in Gruppen aufteilen:
- Transferbefehle
MOV AL,BL ; AL ← BL
OUT 80h,BL ; Output-Port 80h ← BL
- Arithmetische Befehle
ADD AL,BL ; AL ← AL + BL
SAR AX,1
- Logische Befehle
AND AL,BL ; AL ← AL bitwise-AND BL
SHR AX,1
- Sprungbefehle
JMP start ; jump
JNZ loop ; jump if not zero (Z-Flag 0)
- Kontroll- und sonstige Befehle
NOP ; no operation
INT 21h ; interrupt
HLT ; halt
| | | | | | | | | |
Eine Übersicht des Befehlssatzes des Intel-80186-Prozessors gibt die
Intel-Code-Tabelle.
Befehlsoperanden
Operandenlängen
Operanden einer Maschineninstruktion sind typischerweise 8 Bit (1 Byte),
16 Bit (bei Intel 1 Wort), oder 32 Bit (bei Intel 1 Doppelwort); es gibt
auch Bitoperationen.
Die meisten Befehle gibt es in Varianten für unterschiedlich lange
Operanden.
Byte (8 Bit)
| MOV AL,[zahl1]
Word (16 Bit)
| MOV AX,[zahl2]
Bit
| STC ; Carry-Flag setzen
| | |
Die Unterscheidung der Operandenlängen erfolgt bei manchen Assemblern
explizit durch unterschiedliche symbolische ("mnemonische")
Befehlsnamen (z.B. Standard-Linux-Assembler), bei anderen meist
implizit durch die Länge bekannter (Register) oder deklarierter Operanden
(Microsoft, Borland, nasm).
Addressierungsmodi
Maschineninstruktionen können auf verschiedene Weise an die Daten ihrer
Operanden kommen. Auch hierfür gibt es Varianten der Maschineninstruktionen,
die Adressierungsarten; bei manchen Prozessoren kann die Adressierungsart
sogar für die Operanden unabhängig variieren.
- register – Register-Adressierung:
- das Datum (Datenwort) befindet sich in einem Register
- Befehlsparameter: Nummer des Registers
MOV AL,BL
- implicit – Implizite Adressierung:
- das Datum (Datenwort) befindet sich in einem bestimmten Register
(tritt bei Intel bei mehreren Befehlen auf, für die jeweils verschiedene
Register vorgesehen sind, oder bei allen Prozessoren für bestimmte
Operationen auf Flags)
- Befehlsparameter: keiner
STC ; C ← 1
MUL BL ; AX ← AL × BL
- immediate – Unmittelbare Adressierung:
- das Datum befindet sich im Befehl selbst
- Befehlsparameter: das Datum (Konstante)
MOV AL,9
MOV DX,text1 ; lade Adresse
- direct – Direkte Adressierung:
- das Datum befindet sich im Speicher, der Befehl adressiert es
- Befehlsparameter: die Speicheradresse des Datenworts
MOV AL,[zahl1]
- indirect – Indirekte Adressierung:
- das Datum befindet sich im Speicher, seine Adresse ebenfalls;
die Adresse der Adresse befindet sich im Befehl
- Befehlsparameter: die Speicheradresse des Speicherworts, das
die Speicheradresse des Datenworts enthält
MOV AL,[[adresse1]]
- indexed (with offset) – Indizierte Adressierung (mit Offset):
- das Datum befindet sich im Speicher, seine Adresse setzt sich zusammen
aus dem Inhalt eines (Index-)Registers und einem im Befehl enthaltenen
konstanten Offset
- Befehlsparameter: die Nummer des zu verwendenden Indexregisters
und der zu dessen Inhalt zu addierende Offset
MOV AL,[SI+2]
MOV BX,[SI]
- relative – Relative Adressierung:
- die Adresse ist relativ zum aktuellen Programmzähler;
bei Intel kommt das bei „kurzen“ Sprungbefehlen vor;
Programme, die ausschließlich relativ adressieren (nicht bei Intel),
lassen sich im Speicher verschieben
- Befehlsparameter: der Offset zur aktuellen Befehlsadresse
JMP schleife
Stack
Der Stapelspeicher ist eine Organisationsform für Speicherzugriffe,
die nach dem Prinzip „last in first out“ (LIFO) erfolgen. Dieser
Zugriffsmodus wird von der Hardware unterstützt, weil er für viele
Zwecke elementar von Nutzen ist.
Der Stackpointer zeigt jeweils auf das „obere“ Ende des Stapels.
Er wird von den Zugriffsbefehlen automatisch verwaltet und angepasst.
Diese sind:
PUSH AX ; SP ← SP - 2 ; M[SP] ← AX
- Ein Datenwort (Register AX/BX/CX/DX) wird auf den Stapel gelegt
und ist dann das oberste Stack-Element.
POP AX ; AX ← M[SP] ; SP ← SP + 2
- Ein Datenwort wird vom Stapel entnommen und in das angegebene
Register kopiert; das bisher darunter liegende Stack-Element
ist nun das oberste.
CALL func1 ; SP ← SP - 2 ; M[SP] ← IP ; IP ← func1
- Die Rückkehradresse (bereits inkrementierter Inhalt
des IP, der auf den nächsten Befehl hinter dem CALL zeigt)
wird auf den Stack gepusht, dann wird zum Unterprogramm gesprungen.
RET ; IP ← M[SP] ; SP ← SP + 2
- Der Instruction Pointer IP wird mit der (hoffentlich!)
Rückkehradresse vom Stack geladen; dadurch wird hinter den
Aufrufbefehl zurückgesprungen.
Einsatz des Stacks
- für Rückkehradressen von Unterprogrammen
- zum Zwischenspeichern („Retten“) von Daten (meist aus Registern)
zur spätere Wiederherstellung und Weiterverwendung, während das Register
zwischenzeitlich anderweitig genutzt wird
- für Funktionsparameter
- für lokale Daten (Variablen) von Funktionen
- als fest verdrahtete Stack-Architektur, z.B. im
Intel-Gleitkomma-Rechenwerk oder in den HP-Taschenrechnern
(Emulator Free42)
Interrupts
Ein Interrupt ist die Unterbrechung der regulären Programmabarbeitung
aufgrund eines besonderen Ereignisses.
Auslöser für einen Interrupt können in drei Gruppen unterteilt werden:
- extern: Ein Unterbrechungswunsch kommt von außerhalb der CPU, z.B.
durch einen I/O-Controller, der Aufmerksamkeit wünscht (Tastatureingabe)
oder eine Steuerungschaltung im Rechner (Temperatur- und
Spannungsüberwachung, Uhr)
- intern: Ein Befehl kann nicht wie vorgesehen bearbeitet werden,
weil z.B. eine Division durch 0 vorliegt (Datenfehler) oder der Befehlscode
nicht bekannt ist oder ein Zugriffsversuch auf den Hauptspeicher scheitert
- explizit: Durch den Befehl
int
wird ein bestimmter
Interrupt ausgelöst, um die damit verbundene Funktion aufzurufen
(int 21h
zum Aufruf einer DOS-Systemfunktion,
int 10h
zum Aufruf einer Funktion des VGA-BIOS)
Im Falle eines externen Interrupts teilt das Gerät (z.B. I/O-Controller)
der CPU den Interrupt-Wunsch über ein Steuersignal mit,
den Interrupt Request IRQ
.
Nachdem die CPU die Bereitschaft über ein Steuersignal
Interrupt Acknowledge mitgeteilt hat, legt das Gerät die Nummer
des Interrupts auf den Datenbus.
Simultaner Speicherzugriff
Virtueller Speicher
Beschleunigung des Speicherzugriffs / Cache
Wir betrachten die Zugriffsgeschwindigkeit für dynamischen RAM (DRAM)
als Hauptspeicher. Die Speicherzelle selbst (s. Exkurs) hat sich seit
Jahrzehnten im Aufbau nicht verändert.
Zugriffstechnologie
Zwischen CPU und Speicherbausteinen ist (je nach Speichertechnologie)
ein Protokoll (definiertes Zugriffsverfahren) festgelegt, das den
Übermittlung von Adressen und Daten im Wechsel mit Steuersignalen
(Handshake) regelt.
Zugriffsorganisation
Systemarchitektur: Cache
Klassifizierungen von Rechner-/Prozessorarchitekturen
Beschleunigung des Prozessors