Michael WahlRainer Brück
Seite 1
Befehlssatz
des MIPS R2000 Prozessors
Michael WahlRainer Brück
Seite 2
Die fünf klassischen Rechnerkomponenten
Control: SteuerungDatapath: Datenpfad
Michael WahlRainer Brück
Seite 3
Die fünf klassischen Rechnerkomponenten
Der Datenpfad enthält funktionale Einheiten zurManipulation von Daten, insbesondere klassische „Recheneinheiten“ wie Addierer, Multiplizierer, etc.
Michael WahlRainer Brück
Seite 4
Die fünf klassischen Rechnerkomponenten
Das Steuerwerk enthält funktionale Einheiten zurKoordination des Ablaufs von Programmen. Es regelt das Zusammenspiel aller Prozessorkomponenten.
Michael WahlRainer Brück
Seite 5
Die fünf klassischen Rechnerkomponenten
Der Speicher enthält die Programme und Daten vor, während und nach der Ausführung der Programme.
Michael WahlRainer Brück
Seite 6
Die fünf klassischen Rechnerkomponenten
Die Eingabeeinheiten übertragen Programme und zu verarbeitende Daten in den Speicher.
Michael WahlRainer Brück
Seite 7
Die fünf klassischen Rechnerkomponenten
Die Ausgabeeinheiten lesen Ergebnisdaten aus dem Speicher und stellen sie der „Umwelt“ zur weiteren Nutzung zur Verfügung.
Michael WahlRainer Brück
Seite 8
Die fünf klassischen Rechnerkomponenten
Damit das Ganze auch sinnvoll funktioniert brauchtman aber noch etwas mehr:
Eine formale Schnittstelle, die die Kommunikation
zwischen Rechner und Umwelt organisiert.
Michael WahlRainer Brück
Seite 9
Der Instruktionssatz: Schnittstelle zwischen Compiler und Rechner
Michael WahlRainer Brück
Seite 10
Grundlegende Ideen
• Instruktionssatz• Formale Sprache zur Beschreibung der einzelnen Aktionen,
die ein Prozessor ausführen kann.• „Primitive Form“ einer Programmiersprache• „Maschinensprache“
• Eigenschaften• Die Instruktionssätze aller Prozessoren sind sich relativ
ähnlich (es gibt keine „babylonische Sprachverwirrung wie bei natürlichen Sprachen).
• Sie sind so einfach wie möglich gehalten, um gleichzeitig die Möglichkeiten der Hardware und die Fähigkeiten der Compiler zu unterstützen.
• Beispiel:• Der MIPS-R2000-Instruktionssatz: einfach, überschaubar, mit
allen wichtigen Konzepten
Michael WahlRainer Brück
Seite 11
Erstes Beispiel:
add a, b, c
„Addiere die Werte der beiden Variablen „b“ und „c“ und weise das Ergebnis der Variablen „a“ zu.“
• Assemblersprache• Die gewählte symbolische Darstellung ist nicht unmittelbar
vom Prozessor zu verarbeiten. Sie ist durch einen „Assembler“ in eine geeignete Eingaberepräsentation zu übersetzen (s.u.)
• (Assembler-)befehle sind stark formalisiert• Arithmetische Operationen werden immer mit zwei Argument-
und einem Ergebnisoperanden angegeben. • (3-Adress-Maschine)• Eine Addition von mehr als 2 Zahlen muss aus mehreren
Additionsbefehlen zusammen gesetzt werden.
Michael WahlRainer Brück
Seite 12
Übersetzung eines einfachen C-Programms
C MIPS-Assembler
a = b + c;d = a - e;
add a, b, csub d, a, e
f=(g+h)-(i+j)
… oder etwas komplizierter:
add t0, g, hadd t1, i, jsub f, t0, t1
Temporäre Variable
Beachten von Operator-Prioritäten (=> Reihenfolge)
Michael WahlRainer Brück
Seite 13
Operanden in Hardware
• Variable• Variable werden auf elementare Speichereinheiten innerhalb
des Prozessors abgebildet: Register• Register sind Teile der Rechner/Programmierer-Schnittstelle.
Sie können direkt vom Programm aus zugegriffen werden.
• Register• Feste, identische Länge: Wortbreite, typisch heute 32 bit (64-
bit-Maschinen in Kürze)• Feste Anzahl: 32 Register.
• MIPS:• 32 Register mit je 32 bit• Register mit spezieller Funktion: Register 0 und 31• Frei benutzbare Register: Register 1 … 30• Register werden entsprechend der Nutzung im GNU C
Compiler benannt.
Michael WahlRainer Brück
Seite 14
GNU MIPS C Registerbenutzung
Name Nummer Funktion• $zero 0 constant 0• $at 1 assembler • $v0 ... $v1 2-3 result value registers• $a0 ... $a3 4-7 arguments• $t0 ... $t7 8-15 temporary variables• $s0 ... $s7 16-23 saved• $t8 ... $t9 24-25 temporary variables• $k0 ... $k1 26-27 operating system• $gp 28 global pointer• $sp 29 stack pointer• $fp 30 frame pointer• $ra 31 return address
Michael WahlRainer Brück
Seite 15
Das „alte“ Beispiel mit Registern
f=(g+h)-(i+j)add $t0, $s1, $s2add $t1, $s3, $s4sub $s0, $t0, $t1
Die Variablen der C-Anweisung wurden der Reihe nach den Registern $s0 - $s4 zugeordnet:f: $s0, g: $s1, h: $s2, i: $s3, j: $s4
Michael WahlRainer Brück
Seite 16
0
Speicherbefehl: „store word“: Datenübertr. Register - Speicher
48121620
$s2$s1$s0
0sw $s0, 16($s1)
… aber wie kommen die Variablenwerte in die Register?
C-Beispiel: int V[6]; a = V[2]; V[4] = a;
$s1: Basisadr. V,$s0: a
Ladebefehl: „load word“: Datenübertragung Speicher - Register
lw $s0, 8($s1)
048121620
$s2$s1$s0
0
Kein anderer Befehlstyp greift auf den Speicher zu:„Load/Store-Architektur“
Michael WahlRainer Brück
Seite 17
C-Programme mit variablen Array-Indizes
C-Code: g = h + A[i]
add $t1, $s4, $s4 # $t1 = 2 * iadd $t1, $t1, $t1 # $t1 = 4 * i
Index auf Speicheradressen abbilden (mit 4 multiplizieren)Speicher wird Byte-weise adressiert
add $t1, $t1, $s3 # $t1 = 4*i + &A
Wortadresse zu Basisadresse addieren
Array-Element laden
add $s1, $s2, $t0 # $s1 = h + A[i]
Addition ausführen
$s1: g$s2: h$s3: &A$s4: i
Registerzuweisung
lw $t0, 0($t1) # $t0 = A[i]
Michael WahlRainer Brück
Seite 18
Wie werden Instruktionen im Rechner dargestellt?
• Grundlage: Binärdarstellung• Digitale Informationsverarbeitung bedeutet, dass alle Informationen als
Folgen von zwei unterscheidbaren Zuständen dargestellt werden.• Alle Informationen im Rechner lassen sich als Binärzahlen darstellen.• Sowohl Daten, als auch Befehle werden durch Binärzahlen dargestellt.• Die typische Verarbeitungseinheit ist ein Wort: 32-stellige Binärzahl.• Maschinenbefehle werden durch 32-stellige Binärzahlen dargestellt.• Unterschied zur Mic, 8086:• dort haben Maschinen-Befehle unterschiedliche Länge• Register als Teile in Instruktionen werden durch Binärzahlen bezeichnet.
Michael WahlRainer Brück
Seite 19
Beispiel: Repräsentation eines Additionsbefehls
MIPS-Assembler
add $t0, $s1, $s2
Dezimaldarstellung
0 17 18 8 0 32
AdditionZielregisterOperandenregister hier unbenutzt
Binärdarstellung
000000 10001 10010 01000 00000 100000
6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
Michael WahlRainer Brück
Seite 20
MIPS-Instruktionsformate: „R“ (Register)
• Das R-Format• op: „opcode“; Grundtyp der Instruktion• rs: erster Operand (Register)• rt: zweiter Operand (Register)• rd: Ziel (Register)• shamt: „Shift amount“. Wichtig für Schiebeoperationen
(s.u.)• funct: „Funktionscode“; Ergänzung zum op-Feld. Genaue
Spezifikation der durchzuführenden Operation
op rs rt rd shamt funct
6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
Michael WahlRainer Brück
Seite 21
MIPS-Instruktionsformate: „I“ (Immediate)
• Manche Operationen benötigen längere Felder für ihre Operanden. Bsp: „lw“-Operation spezifiziert eine Konstante als Array-Offset. Diese sollte länger als 5 oder 6 Bit sein dürfen.
• Das I-Format• op: „opcode“; Grundtyp der Instruktion• rs: Basisadressregeister• rt: Zielregister• address: Konstante, die Offset bzgl. Basisregister angibt
op rs rt
6 Bit 5 Bit 5 Bit
adress
16 Bit
Michael WahlRainer Brück
Seite 22
Beispiel: Vom C-Programm zur Maschinensprache
C-Programmcode
A[300] = h + A[300]
Maschinencode symbolisch
Machinencode binär
MIPS-Assembler
lw $t0, 1200($t1)add $t0, $s2, $t0sw $t0, 1200($t1)
Michael WahlRainer Brück
Seite 23
… und wie übersetzt man Kontrollstrukturen?
• Alternative Pfade der Programmausführung• Bedingte Programmausführung:
• if … then … [else …]• switch … case …
• Wiederholte Programmausführung:• for …• while …
• Bedingte und unbedingte Sprunginstruktionen• beq reg1, reg2, label (branch if equal)• bne reg1, reg2, label (branch if not equal)• j addr (jump to address)
• Auf der Ebene der Maschinensprache gibt es keine „goto-lose“ (strukturierte) Programmierung!
Michael WahlRainer Brück
Seite 24
Erstes Beispiel: „C“-If-statement
C-Programmcode if (i == j) goto L1;f = g + h;
L1: f = f - i;
MIPS-Assembler
beq $s3, $s4, L1Testen auf Registergleichheit;ggf. Verzweigen zur Subtraktion
add $s0, $s1, $s2 # $s0 = g + h
Addition(ausgeführt im FALSE-Fall)
L1: sub $s0, $s0, $s3 # $s0 = f - i
Subtraktion; Sprungziel(immer ausgeführt)
Register-Zuordnung:• i: $s3• j: $s4• g: $s1• h: $s2• f: $s0
Michael WahlRainer Brück
Seite 25
Etwas komplizierter: If…then…else
C-Programmcode if (i == j)f = g + h;
elsef = g - h;
MIPS-Assembler
bne $s3, $s4, ElseTesten und Verzweigen
add $s0, $s1, $s2Addition (im TRUE-Fall)
Else: sub $s0, $s1, $s2Subtraktion (im FALSE-Fall)
j ExitElse-Fall überspringen
Exit:Ausgang
•Register-Zuordnung:• i: $s3• j: $s4• g: $s1• h: $s2• f: $s0
Michael WahlRainer Brück
Seite 26
Schleifen sind auch nicht viel schwieriger:
C-Programmcode while (save[i] == k)i = i + j;
MIPS-AssemblerLoop: add $t1, $s3, $s3
add $t1, $t1, $t1add $t1, $t1, $s6
# $t1 = &save +4*ilw $t0, 0($t1)
# $t0 = save[i]
Schleifenanfang und Ladendes Array-Elements
bne $t0, $s5, ExitTest Schleifenkriterium
add $s3, $s3, $s4Schleifenrumpf
j LoopExit:
Rücksprung/Ausgang
Michael WahlRainer Brück
Seite 27
Die MIPS-Architektur verwendet ein spezielles Register,das konstant den Wert „0“ enthält. Es wird in derAssemblersprache als $zero bezeichnet.
Weitere Vergleichsmöglichkeiten
Wie realisiert man einen Vergleich der Art if a < b?
slt $t0, $s1, $s2
If $s1 < $s2 then $t0 := 1 else $t0 := 0
Damit lässt sich if a < b goto less wie folgt übersetzen:
slt $t0, $s1, $s2bne $t0, $zero, less
Michael WahlRainer Brück
Seite 28
Resümee – Das Grundkonzept: Speicherprogrammierbarer Rechner• Grundprinzip heutiger Rechnerarchitekturen
• Instruktionen werden als (binäre) Zahlen repräsentiert.• Programme werden im Speicher abgelegt und können dort
gelesen und geschrieben werden wie Zahlen.• Es gibt keinen Unterschied zwischen Daten und Programmen.• Dies ist das Prinzip des speicherprogrammierbaren
Rechners (stored-program-computer).
• Stärken des Konzepts• Daten und Programme können beliebig im Speicher
angeordnet werden.• Programmstart erfolgt einfach durch Angabe einer
Speicheradresse.• Programme können auch als Daten interpretiert werden
(Bsp.: Compiler betrachten Programme als Daten).
Michael WahlRainer Brück
Seite 29
„Höhere Konstrollstrukturen“: Prozeduren
• HW-Unterstützung für Prozeduren• Prozeduren stellen das wichtigste Strukturierungskonzept
in modernen Programmiersprachen dar.• Alle modernen Instruktionssatzarchitekturen bieten Mittel
zur effizienten Bearbeitung von Prozeduren an.
• Schritte bei der Ausführung einer Prozedur• Parameter so plazieren, dass die Prozedur darauf
zugreifen kann• Kontrolle an die Prozedur übergeben• Prozedur ausführen• Ergebniswert so plazieren, dass aufrufendes Programm
darauf zugreifen kann• Kontrolle an die Aufrufstelle zurück geben
Michael WahlRainer Brück
Seite 30
GNU-MIPS-Unterstützung von Prozeduren
• Zuordungen von Registern• $a0 - $a3: Argumente• $v0, $v1: Ergebniswertregister• $ra: Rücksprungadresse
• Befehl für den Aufruf• jal Prozedur (jump and link)• Spezialbefehl für Prozedurausführung:
Springt zu Prozedur
speichert Adresse der folgenden Instruktion in $ra: $ra = PC + 4
• Befehl für den Rücksprung• jr $ra• Gewöhnlicher Sprungbefehl, liest Sprungziel aus $ra
Michael WahlRainer Brück
Seite 31
… und was passiert bei Prozeduren mit mehr als 4 Argumenten?• Argumentspeicher und Zustandssicherung
• Im Speicher wird ein Stack verwaltet, der dynamisch die Prozedurverwaltung unterstützt.
• Er enthält• Argumentwerte, wenn mehr als 4 auftreten• Register, die vor Prozeduraufruf gesichert wurden.
• Stackverwaltung• Ein Register weist auf den ersten freien Platz im Stack
(Stackpointer $sp)• Der Stack ist am „oberen Ende“ des Speichers
angeordnet, wächst in Richtung kleinerer Speicheradressen.
Michael WahlRainer Brück
Seite 32
Ein einfaches Prozedurbeispiel
C-Programmcode
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) - (i + j);return f;
}
MIPS-Assembler Stack
Hohe Adresse
Niedrige Adresse
$spfirst_proc:
sub $sp, $sp, 12
Hohe Adresse
Niedrige Adresse
$sp
sw $t1, 8($sp) $t1
Hohe Adresse
Niedrige Adresse
$spsw $t0, 4($sp) $t0
$t1
Hohe Adresse
Niedrige Adresse
$spsw $s1, 0($sp)$t0$s1
$t1
Hohe Adresse
Niedrige Adresse
$sp
Phase 1: Registerinhalte auf den Stack retten
Michael WahlRainer Brück
Seite 33
Ein einfaches Prozedurbeispiel
C-Programmcode
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) - (i + j);return f;
}
MIPS-Assembler Stack
Hohe Adresse
Niedrige Adresse
$spfirst_proc:
sub $sp, $sp, 12
Hohe Adresse
Niedrige Adresse
$sp
sw $t1, 8($sp) $t1
Hohe Adresse
Niedrige Adresse
$spsw $t0, 4($sp) $t0
$t1
Hohe Adresse
Niedrige Adresse
$spsw $s1, 0($sp)$t0$s1
$t1
Hohe Adresse
Niedrige Adresse
$sp
Phase 2: Berechnungen durchführen
add $t0, $a0, $a1add $t1, $a2, $a3sub $s1, $t0, $t1
Register:$a0: g$a1: h$a2: i$a3: j
Michael WahlRainer Brück
Seite 34
Ein einfaches Prozedurbeispiel
C-Programmcode
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) - (i + j);return f;
}
MIPS-Assembler Stack
Hohe Adresse
Niedrige Adresse
$spfirst_proc:
sub $sp, $sp, 12
Hohe Adresse
Niedrige Adresse
$sp
sw $t1, 8($sp) $t1
Hohe Adresse
Niedrige Adresse
$spsw $t0, 4($sp) $t0
$t1
Hohe Adresse
Niedrige Adresse
$spsw $s1, 0($sp)$t0$s1
$t1
Hohe Adresse
Niedrige Adresse
$spadd $t0, $a0, $a1add $t1, $a2, $a3sub $s1, $t0, $t1
Phase 3: Returnwert speichern
add $v0, $s1, $zero
Michael WahlRainer Brück
Seite 35
Ein einfaches Prozedurbeispiel
C-Programmcode
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) - (i + j);return f;
}
MIPS-Assembler Stack
Hohe Adresse
Niedrige Adresse
$spfirst_proc:
sub $sp, $sp, 12
Hohe Adresse
Niedrige Adresse
$sp
sw $t1, 8($sp) $t1
Hohe Adresse
Niedrige Adresse
$spsw $t0, 4($sp) $t0
$t1
Hohe Adresse
Niedrige Adresse
$spsw $s1, 0($sp)$t0$s1
$t1
Hohe Adresse
Niedrige Adresse
$spadd $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1
Phase 4: Registerzurückspeichern
add $v0, $v0, $zero
……
lw $s1, 0($sp)lw $t0, 4($sp)lw $t1, 8($sp)
Hohe Adresse
Niedrige Adresse
$sp
addi $sp, $sp, 12
Michael WahlRainer Brück
Seite 36
Ein einfaches Prozedurbeispiel
C-Programmcode
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) - (i + j);return f;
}
MIPS-Assembler Stack
Hohe Adresse
Niedrige Adresse
$spfirst_proc:
sub $sp, $sp, 12
Hohe Adresse
Niedrige Adresse
$sp
sw $t1, 8($sp) $t1
Hohe Adresse
Niedrige Adresse
$spsw $t0, 4($sp) $t0
$t1
Hohe Adresse
Niedrige Adresse
$spsw $s1, 0($sp)$t0$s1
$t1
Hohe Adresse
Niedrige Adresse
$spadd $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1add $v0, $v0, $zero
……
lw $s1, 0($sp)lw $t0, 4($sp)lw $t1, 8($sp)
Hohe Adresse
Niedrige Adresse
$sp
addi $sp, $sp, 12
Phase 5: Rücksprung
jr $ra
Michael WahlRainer Brück
Seite 37
Warum eigentlich ein Stack?Prozeduren, die andere aufrufen
• Probleme• Alle Prozeduren verwenden $a0 - $a3 für Argumente• Alle Prozeduren verwenden $ra als Rücksprungregister• Alle Prozeduren verwenden dieselben Arbeitsregister Register:
$s0 - $s7, $t0 -$t9
• Mögliche Lösung• Aufrufende Prozedur sichert Argumentregister auf Stack• Aufrufende Prozedur sichert temporäre Arbeitsregister auf
Stack:
temporäre Register: $t0 - $t9• Aufgerufene Prozedur sichert Rücksprungregister $ra und
verwendete gespeicherte Register auf Stack
gespeicherte Register: $s0 - $s7• Beim Rücksprung aus aufgerufener Prozedur werden alle
gesicherten Register zurück geladen.
Michael WahlRainer Brück
Seite 38
Beispiel: Rekursiver Prozeduraufruf
C-Sourcecode: Fakultätsberechnung
MIPS-Assembler: Fakultätsberechnung
Registerzuordnung: $a1 enthält nVor rekursivem Aufruf zu sichern:• $a1 (wird nach rekursiven Aufruf benötigt)• $ra (weil Prozedur rekursiv)
Michael WahlRainer Brück
Seite 39
Beispiel: Rekursiver Prozeduraufruf
MIPS-Assembler: Fakultätsberechnung
Michael WahlRainer Brück
Seite 40
GNU-MIPS-Stack-Konventionen
• Struktur des Stack• Stack-Segment, das zu Prozedur gehört, heißt Frame.• Frame pointer ($fp) zeigt auf Anfang des Frames.• Dadurch lassen sich lokalen Variablen unabhängig von $sp
adressieren: Bequem, da $sp sich ändern kann.
Michael WahlRainer Brück
Seite 41
Die Welt besteht nicht nur aus Zahlen
• Byteweise Zugriffe und Zeichen• Daten werden nicht immer als Zahlen interpretiert. In der
heutigen Praxis ist die Verarbeitung von Texten (Zeichenketten) mindestens genau so wichtig.
• Zeichen werden durch einzelne Bytes repräsentiert. Instruktionssätze verfügen daher über Byte-Lade- und Speicheroperationen.
• Ladeoperationlb $t0, 0($sp)
Lädt ein Byte aus dem Speicher und plaziert es in die rechts gelegenen (niederwertigen) Bits eines Registers
• Speicheroperationsb $to, 0($a1)
speichert die niederwertigen acht Bits eines Registers in die bezeichnete Speicherposition
Michael WahlRainer Brück
Seite 42
Beispiel: Text kopieren
MIPS-Assembler:
C-Sourcecode:
Michael WahlRainer Brück
Seite 43
Beispiel: String kopieren
MIPS-Assembler:
Michael WahlRainer Brück
Seite 44
Mehr Komfort beim Datenzugriff:Adressierungsarten
• Mängel der derzeitigen Instruktionen• Die Verwendung von Konstanten ist unhandlich
• Man muss entweder spezielles Register bereit stellen ($zero) oder Konstante im Speicher an bekannten Stellen ablegen.
• Da Konstanten (z.B. für Inkrement/Dekrement-Operationen bei Datenzugriffen in Schleifen) häufig auftreten, ist ein verbesserter Konstantenzugriff wünschenswert.
• Die Handhabung von Verzweigungsadressen ist unzulänglich
• Das ist bisher nicht aufgefallen, da wir immer auf Assembler-Ebene mit symbolischen Sprungzielen operiert haben!
• Für Verzweigungsziele sind nur Adressbereiche im Rahmen von 16 Bits erreichbar
• Als Sprungziele nur 16 Bit lange Adressen möglich
Michael WahlRainer Brück
Seite 45
Verwendung von Konstanten
Spezielle Befehle, die Konstanten in der Instruktion enthalten: Immediate-Adressierung addi, $sp, $sp, 4 ($sp = $sp + 4)
slti $t0, $t1, 13 (if $t1 < 13 $t0 = 1)
8 29 29 4
001000 11101 11101 0000 0000 0000 0100
10 8 9 13
001010 01000 01001 0000 0000 0000 1101
Michael WahlRainer Brück
Seite 46
Verwendung von Konstanten
Und wie behandelt man große Konstanten? Der Befehl lui (load upper half word immediate) lädt die angegebene
Konstante in die höherwertigen 16 Bit des Zielregisters. lui $t0, 255
001111 00000 01000 0000 0000 1111 1111
0000 0000 0000 00000000 0000 0000 0000 0000 0000 0000 00000000 0000 1111 1111
0000 0000 0000 00000000 0000 0000 0000
Beispiel:
lui $s0, 61
0000 0000 0011 1101
addi $s0, $s0, 2304
0000 1001 0000 0000
Michael WahlRainer Brück
Seite 47
Adressierung von Sprungzielen
Unbedingte Sprungbefehle: Das j-Format j 10000 (go to 10000)
Die Implementierung von Verzweigungsbefehlen: PC-relative Adressierung PC: Program Counter: Befehlszähler; Register, das
während des Programmablaufs die Speicheradresse des jeweils nächsten auszuführenden Befehls enthält
bne $s0, $s1, 16if $s0 - $s1 ≠ 0 PC = PC + 16
2
6 Bit
10000
26 Bit
Michael WahlRainer Brück
Seite 48
Beispiel: Maschinenprogramm mit Sprungbefehlen
Achtung: Der PC wird jeweilsvor der eigentlichen Befehls-ausführung um 4 inkrementiert
PC = PC + 8
PC = 80000
20000
Michael WahlRainer Brück
Seite 49
Wie realisiert man weite Verzweigungen?
Verzweigungsbefehle können Verzweigungen um ± 215 Speicherworte realisieren.
Das beschränkt die absolute Programmgröße Für weitere Verzweigungen wird vom Assembler eine
indirekte Verzweigungsmethode implementiert: unbedingter Sprung zum Sprungziel (26 Bit Adresse) invertierter Verzweigungsbefehl.
beq $s0, $s1, L1bne $s0, $s1, L2j L1
L2:
Michael WahlRainer Brück
Seite 50
MIPS-Adressierungsarten
addi $s0 $s1, 24
add $t0, $s1, $s2
lw $s0, 16($t0)
Michael WahlRainer Brück
Seite 51
MIPS-Adressierungsarten
bne $s1, $s2, 16
PC = PC + (Address || “00“)
j 10000
PC = PC.(31..28) || Address || “00“
Michael WahlRainer Brück
Seite 52
Was haben wir jetzt an MIPS-Instruktionen?
Michael WahlRainer Brück
Seite 53
Vom C-Programm zur Ausführung im Rechner
Vier grundsätzliche Schritte:
C-Programm
Assemblercode
Objektocde: Maschinensprachmodul
Objektcode: Bibliotheksroutinen
Executable: Maschinenprogramm
Speicher
Compiler
Assembler
Linker
Loader
Michael WahlRainer Brück
Seite 54
Compiler
Übersetzung von Hochsprachen in Assembler Hochsprachenprogrammierung wird verwendet,
da die Programmiereffizienz hier ungleich höher ist als bei der Verwendung der Maschinensprache,
da Programme in Hochsprachen (mehr oder weniger) maschinenunabhängig sind.
Moderne Compiler erzeugen Assemblercode, der so gut optimiert ist, dass er manuell kaum besser erzeugt werden könnte.
Während höhere Programmiersprachen (weitestgehend) maschinenunabhängig sind, muss für jede Zielarchitektur ein spezieller Compiler bereit gestellt werden.
Michael WahlRainer Brück
Seite 55
Assembler
Assemblersprache Symbolische Repräsentation der
Maschineninstruktionen. Vereinfachte Anwendung durch
Pseudoinstruktionen: Instruktionen, die der Befehlssatz nicht enthält, und die vom Assembler in gültige Maschineninstruktionen übersetzt werden
mov $t0, $t1 -> add $t0, $zero, $t1 blt $s0, $s1, L1 -> slt $t0, $s0, $s1
bne $t0, $zero, L1 Zahlendarstellungen: Neben binären und dezimalen
Zahlenrepräsentationen ist gewöhnlich auch die hexadezimale Darstellung gebräuchlich, die v.a. für Adressberechnung vorteilhaft ist.
Michael WahlRainer Brück
Seite 56
Assembler
Objektcode Objektfiles enthalten alle Informationen, die für die weitere
Bearbeitung erforderlich sind. Beispiel: Unix-Objektfiles Header: Beschreibt die Größe und Position der übrigen Teile
des Objektfiles Textsegment: Maschinensprachcode Datensegment: Statische Daten, die während der
Programmlaufzeit alloziert werden, dynamische Daten, die während der Programmlaufzeit ihre Größe verändern
Relokationsinformation: Identifikation von Instruktionen und Daten, die von absoluten Speicheradressen abhängig sind
Symboltabelle: noch undefinierte Labels (z.B externe Sprungziele)
Debugging Information: Informationen, die dem Debugger ermöglichen, Maschinenbefehle mit C-Sourcecode in Verbindung zu bringen
Michael WahlRainer Brück
Seite 57
Linker
Um eine weitgehende Wiederverwendung von Programmteilen zu ermöglichen, werden Programme Prozedur für Prozedur übersetzt.
Für jedes einzelne der so entstehenden Programmstücke müssen die relativen Positionen innerhalb des Speichers bestimmt werden.
Aufgaben des Linkers Symbolische Plazierung von Code und Daten im Speicher Bestimmung der Adressen von Daten- und
Instruktionslabels „Patchen“ von internen und externen Referenzen, d.h.
Einsetzen der ermittelten Sprungweiten bzw. Sprungziele
Das Executable hat dasselbe Format wie das Objektfile, nur mit aufgelösten Referenzen
Michael WahlRainer Brück
Seite 58
Loader
Betriebssystemroutine, die ein Programm zur Ausführung auf dem Rechner bringt.
Dabei werden in Unix die folgenden Schritte ausgeführt: Lesen des Programms und Bestimmten der Programm-
und Datensegmentgrößen Bereitstellen eines hinreichend großen Adressraums für
Programm und Daten Kopieren der Instruktionen und Daten aus dem Programm
in den Speicher Initialisierung der Maschinenregister; Setzen des
Stackpointers auf die erste freie Position Sprung zu einer Start-up-Routine, die Parameter in die
Argumentregister schreibt und zur main-Prozedur des Programms verzweigt
Michael WahlRainer Brück
Seite 59
Ein umfassendes Beispiel
Assembler-Programmierung (bzw. Übersetzung von Hochsprachenprogrammen in Assembler) Dreischrittiges Vorgehen
Resgisterzuweisung für Programmvariablen Erzeugen des Assemblercodes für den Prozedurrumpf Einfügen von Umgebungssicherungsmaßnahmen
Modulares Vorgehen Die o.g. Vorgehensweise wird modular für jede einzelne
Prozedur durchgeführt
Beispielprogramm Sortieren mit Hilfe des Bubblesort-Algorithmus Modularisierung in zwei Prozeduren
swap: Vertauschen zweicher benachbarter Speicherinhalte sort: Sortieren aufeinanderfolgender Speicherworte
Michael WahlRainer Brück
Seite 60
Die Prozedur swap
C-Programm
Registerzuweisung Parameter:
$a0: v (Adresse des ersten Array-Elements) $a1: k
lokale Varaible $t0: temp
swap (int v[], int k){ int temp;
temp = v[k];v[k] = v[k+1],v[k+1] = temp;
}
Michael WahlRainer Brück
Seite 61
Prozedurrumpf
Die Prozedur swap
1) Adressberechnung
1
2) Array-Elemente laden
2
3) Array-Elemente vertauscht abspeichern
3
4) Rücksprung
4
Michael WahlRainer Brück
Seite 62
Die Prozedur swap
Und was wird gesichert? Nichts! Denn …
Es werden nur $t-Register verwendet, die gemäß Registerkonventionen nicht gesichert werden
Es wird keine Unterprozedur aufgerufen:
– Argumentregister
– Rücksprungadressregister
werden daher nicht überschrieben und müssen nicht gesichert werden.
Michael WahlRainer Brück
Seite 63
Die Prozedur sort
Bubblesort-Prozedur Der C-Code
sort (int v[k], int n){ int i, j;
for (i=0; i<n; i=i+1){ for (j=i-1;
j>=0 && v[j] > v[j+1]; j=j-1)
{ swap (v, j); }}
}
Michael WahlRainer Brück
Seite 64
Die Prozedur sort
Registerzuweisung Parameter
$a0: v, Adresse des ersten Elements des zu sortierenden Arr ays $a1: n, Anzahl der zu sortierenden Elemente
Register für lokale Variable $s0: i $s1: j Diese Register würden bei Aufruf weiterer Prozeduren gesichert
(trifft in diesem Beispiel nicht zu!) temporäre Rechenregister
$t0 - $t4, verwendet für Adressberechnungen
Michael WahlRainer Brück
Seite 65
Die Prozedur sort: Prozedurrumpf
Die äußere Schleife:
1) Initialisierung
1
2) Schleifentest
2
3) Inkrement und Iteration
3
Michael WahlRainer Brück
Seite 66
Die Prozedur sort: Prozedurrumpf
Die innere Schleife:1) Initialisierung2) Schleifentest3) Inkrement und Iteration
1
2
3
{ for (j=i-1; j>=0 && v[j] > v[j+1]; j=j-1) { … }
Michael WahlRainer Brück
Seite 67
Die Prozedur sort: Prozedurrumpf
Parameterübergabe an swap und Aufruf
Initiale Parameterübergabe an sort
Michael WahlRainer Brück
Seite 68
Die Prozedur sort: Prozedurrumpf
Michael WahlRainer Brück
Seite 69
Die Prozedur sort: Gesamteinbindung
Register sichern
Register zurückspeichern
Prozedurrücksprung
Michael WahlRainer Brück
Seite 70
Instruktionssatzarchitekturen in der Praxis
Realistische Beispiele Es wäre zu zeitaufwendig, in einer Überblicksveranstaltung
wie dieser alle Details der komplexen realistischen Prozessorarchitekturen von heute zu behandeln.
Wir werden uns immer wieder einzelnen interessanten Aspekten solcher Prozessoren zuwenden.
Für Details folge man den „WEB-Enhanced“ Verweisen aus dem Buch von Hennessy/Patterson(auch über die RS-WEB-Pages erreichbar)
Michael WahlRainer Brück
Seite 71
Ein kurzer Blick auf den PowerPC
IBM/Motorola Prozessorfamilie, Einsatz in IBM-Rechnern und Apple-Macintosh
Registersatz 32 Register à 32 bit, Load/Store-Architektur
Adressierungsarten Indizierte Adressierung
Adressierungsart, die die Summe der Inhalte zweier Register als Adresse verwenden kann. Dies ist nützlich für die Adressierung von Arrays
Die MIPS Instruktionsfolge
kann beim PowerPC ersetzt werden durch
Michael WahlRainer Brück
Seite 72
Ein kurzer Blick auf den PowerPC
Adressierungsdarten (Forts.) Update-Adressierung (manchmal auch Autoinkrement/
Autodekrement-Adressierung genannt Datentransferoperationen erhöhen/erniedrigen nach der
Befehlsausführung automatisch den Inhalt des Basisregisters. Dies ermöglicht schnelle Blocktransferoperationen Anstatt der MIPS-Instruktionsfolge
reicht beim PowerPC der Befehl
Michael WahlRainer Brück
Seite 73
Ein kurzer Blick auf den PowerPC
Spezielle PowerPC-Instruktionen Mehrfach-Laden/Speichern
Transfer von bis zu 32 Speicherworten mit einem Befehl aus dem Speicher in Register oder umgekehrt
Instruktion zur Schleifenunterstützung Spezieller Befehl, der die Ausführung von for-Schleifen effizient
implementiert. Die folgende C-for-Schleife
wird in MIPS so übersetzt … ,
beim PowerPC so …
Michael WahlRainer Brück
Seite 74
Ein kurzer Blick auf Intel-Architekturen
Während MIPS und auch PowerPC bei ihrer Einführung neue Architekturen waren hat INTEL bei der Prozessorentwicklung über 20 Jahre lang auf Kompatibilität geachtet.
Auf diese Weise mussten die Leistungsparameter neuer Architekturkonzepte immer unter Berücksichtigung der Möglichkeiten der alten Prozessoren eingeführt werden.
Das Ergebnis sind leistungsfähige Prozessoren mit sehr komplexen und sehr irregulären Instruktionssatzarchitekturen.
Michael WahlRainer Brück
Seite 75
Geschichte der Intel-Architekturen
1978: 8086 Erster 16 Bit-Prozessor als kompatible Erweiterung des
erfolgreichen 8080. Register mit spezifischen Aufgaben.
1982: 80286 Erweiterter Adressraum (24 bit). Zusätzliche Instruktionen zur
Abrundung des Befehlssatzes, speziell für Protection.
1985: 80386 Sowohl Adressraum, als auch Register auf 32 bit erweitert.
Zusätzliche Operationen schaffen fast eine General-purpose-Register-Maschine.
1989: 80486; 1992: Pentium; 1995 Pentium Pro Erhöhte Performanz durch interne Maßnahmen. Nur 4 neue
Instruktionen.
1997: Pentium MMX 57 zusätzliche Instruktionen für Multimedia-Anwendungen.
Michael WahlRainer Brück
Seite 76
Der Registersatz ab 80386
8 der ursprünglichen 16 Bit-Register wurden auf 32 Bit erweitert und dienen als „General-Purpose-Register“
Für einzelne Instruktionen dienen einzelne Register speziellen Zwecken
Michael WahlRainer Brück
Seite 77
Instruktionstypen und Operanden
2-Adressbefehle Ein Register dient sowohl als Quell- als auch als Zielregister Operationen spezifizieren also höchstens zwei
Register/Speicheradressen (2-Adress-Maschine) Alle Operationen mit Speicherzugriff
Keine „Load/Store-Architektur. Jede Instruktion kann Operanden aus dem Speicher nutzen
Michael WahlRainer Brück
Seite 78
80x86-Instruktionsbeispiele
Verzweigungen werden in Abhängigkeit von „Condition Codes“ durchgeführt,die bei der Ausführung von Instruktionen (als Seiteneffekt) gesetzt werden!
(*)
Michael WahlRainer Brück
Seite 79
Adressierungsarten
Intel-Architekturen verwenden recht vielfältige und komplexe Adressierungsarten mit uneinheitlichen Restriktionen hinsichtlich der Registernutzung.
Michael WahlRainer Brück
Seite 80
Instruktionsformate (Beispiele)
Intel-Instruktionen variieren zwischen 1 und 17 Byte Länge bei äußerst verschiedenartigen Aufteilungen. Dies mach die HW-Implementierung ausgesprochen aufwendig.
Michael WahlRainer Brück
Seite 81
Klassische Architekturkonzepte
Akkumulatorarchitekturen Zu Beginn der Geschichte der Mikroproprozessoren war Speicher so teuer,
dass man sich nur möglichst wenig davon leisten durfte. Damals gab es in der Regel nur ein Register, den Akkumulator, auf den mit
kurzen Instruktionen (eine Speicheradresse) zugegriffen wurde (1-Adress-Maschine)
Nach und nach konnten mehr und längere Register bereit gestellt werden, was zu General-Purpose-Register-Architekturen und 2- bzw. 3-Adress-Maschinen führte.
C.Code
Assembler
Michael WahlRainer Brück
Seite 82
Klassische Architekturkonzepte
Stackarchitekturen In den frühen 60er Jahren wurden in der Annahme, Compiler
könnten keine effiziente Registerverwaltung durchführen, Architekturen ganz ohne Register (!!) entworfen
Operanden wurden direkt im Speicher mit Hilfe eines Stack-Modells (ähnlich wie in HP-Taschenrechnern) realisiert (0-Adress-Maschine)
C.Code
Assembler
Michael WahlRainer Brück
Seite 83
Klassische Architekturkonzepte
Ab 1980: RISC-Architekturen In den achziger Jahren war Speicher hinreichend billig geworden und die Compiler-Technik hinreichend
weit fortgeschritten, so dass man sich erlauben konnte, beim Entwurf von Instruktionssatzarchitekturen konsequent auf Hardware-Optimierung zu setzen.
Dies führte zu den sog. RISC-Architekturen (Reduced Instruction Set Computer), die hinsichtlich der Instruktionssätze über folgende Eigenschaften verfügen:
eine feste Instruktionslänge Load/Store-Architekturen wenige, einander ähnliche Instruktionsformate wenige einfache Adressierungsarten wenige Instruktionen (insbes. wenige hochspezifische Spezialbefehle) (Ein weiteres definierendes Element von RISC-Architekturen: Pipelining wird im folgenden ausführlich behandelt)
Das RISC-Konzept bietet gute Voraussetzungen für eine hocheffiziente HW-Realisieerung (s.u.)!
Top Related