Instruktionssatzarchitektur - Computer and Communication Systems
Instruktionssatzarchitektur - Computer and Communication Systems
Instruktionssatzarchitektur - Computer and Communication Systems
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Computer</strong> <strong>and</strong> <strong>Communication</strong> <strong>Systems</strong><br />
(Lehrstuhl für Technische Informatik)<br />
<strong>Instruktionssatzarchitektur</strong> (ISA)<br />
Klassifikation, Operationen und Oper<strong>and</strong>en,<br />
Registersatz, Instruktionswort, Adressierung,<br />
Sprungbefehle, Unterprogramme, Arithmetik,<br />
Entwurf einer ISA, Übersetzung eines Programms<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 1
Lernziele<br />
Unterschiede verschiedener Klassen von ISAs<br />
Kennenlernen einer ISA am Beispiel MIPS<br />
Befehlssatz<br />
Adressierungsarten<br />
Instruktionsformate<br />
Kompromisse beim Entwurf einer ISA<br />
Erstellen kleiner Programme in MIPS-Assembler, u. a. mit<br />
Direktiven und Pseudobefehlen<br />
bedingten Verzweigungen<br />
Aufruf von Unterprogrammen<br />
Verständnis der Arbeitsweise von Assembler, Linker und<br />
Lader<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 2
KLASSIFIKATION VON ISAS<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 3
Ein Rückblick: von Neumann‘s Universalrechner<br />
Speicherwerk Daten Rechenwerk E/A-Werk<br />
zur Peripherie<br />
Adresse<br />
Adresse<br />
Akkumulator<br />
ACU<br />
Daten<br />
Befehle<br />
Status<br />
Steuersignale<br />
IR PC SR<br />
Leitwerk<br />
Instruktionsregister<br />
Befehlszähler<br />
Statusregister<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 4
Von Neumann Architektur<br />
Programme bestehen aus einer<br />
Folge von Befehlen<br />
Grundsätzlich eine Beschreibung<br />
eines sequentiellen Auftrags<br />
Befehle sind in der angegebenen Reihenfolge auszuführen<br />
Ausnahme: Sprünge und Unterbrechungen<br />
Zu jedem Zeitpunkt führt der Prozessor nur jeweils einen<br />
Befehl aus<br />
In jedem Befehl kann (höchstens) ein Datenwert bearbeitet<br />
werden<br />
Oper<strong>and</strong>en und Ergebnis werden durch Speicheradressen bzw.<br />
Register repräsentiert<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 5
Befehlssatz-Architektur (ISA)<br />
Schnittstelle zum Programmierer bzw. Compiler<br />
„Black box“-Sicht: interne Realisierung interessiert nicht<br />
Abstraktionsprinzip<br />
Prozessoren mit der selben ISA sind binärkompatibel<br />
ISA aus Sicht des Programmierers<br />
Datenformate und Datentypen<br />
Adressierung: Spezifikation der Oper<strong>and</strong>en<br />
Anzahl der (expliziten) Oper<strong>and</strong>en<br />
Speicherort (Hauptspeicher, Register)<br />
Adressierungsarten (Spezifikation der Speicheradressen)<br />
Befehle (Operationen auf Daten, Ablaufsteuerung) und<br />
Befehlsformate<br />
Ausführungsmodi, privilegierte Funktionen, Unterbrechungen, …<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 6
Klassifikation von ISAs (1)<br />
Instruktionssatz-Architekturen werden heute in<br />
Abhängigkeit von den Quellen der Oper<strong>and</strong>en bei einer<br />
Operation in folgende vier Klassen eingeteilt.<br />
Stack<br />
Akkumulator<br />
Register/Speicher<br />
Register/Register<br />
Früher gab es noch die Klasse der Speicher/Speicher ISAs,<br />
bei der beide Oper<strong>and</strong>en aus dem Speicher eingelesen<br />
wurden.<br />
Typisches Beispiel war die VAX-Architektur.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 7
Klassifikation von ISAs (2)<br />
Bei einer Stack-basierten ISA werden die<br />
beiden Elemente auf den obersten Stack-<br />
Positionen verknüpft.<br />
Die beiden Oper<strong>and</strong>en werden über push Befehle<br />
auf den Stack geschrieben.<br />
Bei Ausführung einer zweistelligen Operation op<br />
werden die Oper<strong>and</strong>en vom Stack entfernt,<br />
verknüpft und das Ergebnis wieder auf den Stack<br />
geschrieben.<br />
Das Ergebnis kann über einen pop Befehl dem<br />
Stack entnommen werden.<br />
Beispiele: Borroughs B5000 (1963), x86<br />
Gleitkommaeinheit, Sun picoJava Prozessor,<br />
Java VM<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 8
Klassifikation von ISAs (3)<br />
Bei der Akkumulator-basierten ISA wird ein<br />
Wert aus dem Speicher mit dem<br />
Akkumulator (Akku) verknüpft.<br />
Mit dem Befehl load kann ein Wert aus dem<br />
Speicher in den Akku geladen werden.<br />
Der Befehl op verknüpft Inhalt von Akku und<br />
Speicherinhalt; Ergebnis stets wieder im Akku.<br />
Mit dem Befehl store kann Inhalt des Akku in den<br />
Speicher geschrieben werden.<br />
Beispiele: erste Mikroprozessoren, einfache<br />
Mikrocontroller, z.B. MOS 6502/6510<br />
(Commodore 64)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 9
Klassifikation von ISAs (4)<br />
Bei der Register/Speicher-basierten<br />
Architektur steht statt eines einzelnen<br />
Akkumulators ein Satz aus mehreren<br />
Registern zur Verfügung.<br />
Vorteile gegenüber Akku-Variante:<br />
Speicherung von Zwischenergebnissen in<br />
Registern ist möglich.<br />
Erspart Speicherzugriffe!<br />
Beispiele: Intel x86, Motorola 680x0<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 10
Klassifikation von ISAs (5)<br />
Bei der Register/Register-basierten ISA<br />
können nur Oper<strong>and</strong>en aus den Registern<br />
verknüpft werden.<br />
Laden und Speichern von Daten erfolgt stets<br />
in separaten Befehlen.<br />
Diese Klasse wird daher auch als load/store-<br />
Architektur bezeichnet.<br />
Beispiele: MIPS, SPARC, DEC Alpha<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 11
Klassifikation von ISAs (6)<br />
Maschinen mit Register/Speicher- oder Register/Register-<br />
ISAs werden auch GPR Maschinen bezeichnet.<br />
GPR = General Purpose Register<br />
Diese werden nach<br />
Anzahl m der Oper<strong>and</strong>en aus Speicher je Operation<br />
Anzahl n der Oper<strong>and</strong>en je Operation (z.B. ist n = 2, wenn der<br />
Zieloper<strong>and</strong> stets einem der beiden Quelloper<strong>and</strong>en entspricht)<br />
auch als (m,n) ISA klassifiziert.<br />
Beispiele<br />
Ein Register/Register-ISA gehört stets zur Klasse (0,n), wobei der<br />
Wert n typischerweise 3 ist.<br />
Ein Register/Speicher-ISA mit 2 Oper<strong>and</strong>en, von denen 1 aus dem<br />
Speicher gelesen wird, gehört zur Klasse (1,2).<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 12
Klassifikation von ISAs (7)<br />
In dieser Veranstaltung wird überwiegend die MIPS ISA<br />
eingesetzt:<br />
1981 von J. Hennessy an der Stanford University (Kalifornien)<br />
entwickelt, Grundlage für ersten RISC-Prozessor.<br />
1984 wurde die Fa. MIPS <strong>Computer</strong> <strong>Systems</strong>, Inc. gegründet.<br />
1992 wurden MIPS CPUs in SGI Workstations eingesetzt.<br />
1999 wurden MIPS-32 und MIPS-64 ISAs eingeführt (32- und 64-<br />
Bit Architekturen).<br />
Heute überwiegend im Bereich eingebetteter Systeme eingesetzt<br />
(z.B. Router, Navigationsgeräte, DTV, DVD recorder, ...).<br />
Architektur erhielt viele Auszeichnungen, z.B. "Best high<br />
performance embedded processor" (Microprocessor Report,<br />
2002).<br />
Es wird hier nur die 32-Bit MIPS ISA betrachtet (MIPS-32).<br />
32-Bit Datenworte und 32-Bit Adressraum, d.h. 2 32<br />
Speicheradressen.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 13
OPERATIONEN UND OPERANDEN<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 14
Operationen und Oper<strong>and</strong>en (1)<br />
In der Assemblersprache der MIPS ISA werden<br />
arithmetische und logische Operationen op in der Form<br />
op dest,src1,src2<br />
beschrieben, wobei<br />
op eine symbolische Bezeichnung der Operation ist, z.B. add oder<br />
sub,<br />
src1 und src2 Platzhalter für die Oper<strong>and</strong>en der Operation sind,<br />
dest ein Platzhalter für das Ergebnis der Operation ist.<br />
In einem Assemblerprogramm steht in jeder Zeile eine<br />
derartige Maschineninstruktion, z.B.<br />
add sum,a,b<br />
sub diff,sum,c<br />
# sum = a + b<br />
# diff = sum – c<br />
Hinter jeder Maschineninstruktion kann ein Kommentar<br />
stehen, der mit einem Symbol # eingeleitet wird.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 15
Operationen und Oper<strong>and</strong>en (2)<br />
Die Oper<strong>and</strong>en src1 und src2 einer Operation können in<br />
der MIPS Hardware nur den Registern eines<br />
Registersatzes entnommen werden, ebenso wird das<br />
Ergebnis dest wieder in ein Register geschrieben.<br />
MIPS ISA gehört zur Register/Register ISA-Klasse (0,3).<br />
Ein Register hat in der hier betrachteten MIPS-Architektur<br />
eine Breite von 32 Bit.<br />
Die MIPS ISA verfügt über insgesamt 32 Register.<br />
In der MIPS Assemblersprache stehen für allgemeine<br />
Zwecke die Register $s0,...,$s7 und $t0,... ,$t7<br />
zur Verfügung:<br />
$s0, $s1,... zur Speicherung von Variablen<br />
$t0, $t1,... zur Speicherung temporärer Werte<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 16
Operationen und Oper<strong>and</strong>en (3)<br />
Wie kommen die Daten vom Speicher ins Register?<br />
Für den Zugriff auf ein Datum im Speicher muss die<br />
Speicheradresse angegeben werden.<br />
Speicher wird betrachtet als ein großes eindimensionales Feld<br />
aus Bytes, das mit 0 beginnend adressiert wird:<br />
Mit der MIPS Instruktion<br />
lw dest, addr<br />
kann ein 32-Bit Wort von der Speicheradresse addr in ein<br />
Register dest geladen werden (lw bedeutet load word).<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 17
Operationen und Oper<strong>and</strong>en (4)<br />
32-Bit Worte können nur auf Byte-Adressen liegen, die<br />
ohne Rest durch 4 teilbar sind!<br />
Die vollständige Adressierung beim Ladebefehl lautet:<br />
lw reg1, disp(reg2)<br />
hierin bezeichnen<br />
reg1 ein beliebiges der 32 MIPS-Register als Zielregister für den<br />
Datentransfer, z.B. $s0 bis $s7 oder $t0 bis $t7,<br />
reg2 ein beliebiges der 32 MIPS-Register, das eine 32-Bit<br />
Speicheradresse enthält (indirekte Adressierung),<br />
disp ein Offset, der vor der Speicheradressierung zum Inhalt von<br />
reg2 hinzuaddiert wird (Displacement).<br />
Die resultierende 32-Adresse ist somit: (reg2) + disp<br />
Diese Art der Speicheradressierung wird auch als Register indirect<br />
+ Displacement bezeichnet.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 18
Operationen und Oper<strong>and</strong>en (5)<br />
Für das Speichern von Daten gibt es die MIPS Instruktion<br />
sw reg1, disp(reg2)<br />
Die Oper<strong>and</strong>en dieses Befehls (sw = store word) entsprechen<br />
denen des Ladebefehls lw, nur ist reg1 hier das Quellregister.<br />
Beispiel:<br />
Es soll in MIPS Assembler die Anweisung<br />
A[12] = c + A[8];<br />
einer Hochsprache realisiert werden. Es sei angenommen, dass<br />
die Speicheradresse von A[0] im Register $s1, die Konstante c<br />
bereits im Register $s0 steht. Eine mögliche Lösung ist:<br />
lw $t0, 32($s1)<br />
add $t1, $t0, $s0<br />
sw $t1, 48($s1)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 19
Operationen und Oper<strong>and</strong>en (6)<br />
In einer MIPS Instruktion können Konstanten auch direkt<br />
angegeben werden.<br />
Einfacher und schneller, als die Konstanten aus dem Speicher<br />
zunächst in ein Register zu laden.<br />
Hierzu direkt gibt es für einige arithmetische/logische<br />
Operationen zusätzliche Instruktionen, deren<br />
symbolischer Name auf i endet.<br />
(i steht für immediate oper<strong>and</strong>), z.B. für die Addition:<br />
addi reg2, reg1, const<br />
Hierin bezeichnen:<br />
reg2 das Zielregister<br />
reg1 das Register mit dem ersten Oper<strong>and</strong><br />
const eine beliebige ganze pos. oder neg. Konstante<br />
Beispiel: addi $t1, $t0, 100<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 20
Operationen und Oper<strong>and</strong>en (7)<br />
Außer den arithmetischen Operationen add und sub gibt<br />
es in der MIPS ISA auch folgende logische Operationen,<br />
die eine bitweise logische Operation ausführen:<br />
Name Beispiel entsprechende Notation in<br />
C<br />
<strong>and</strong> <strong>and</strong> $s0,$s1,$s2 $s0 = $s1 & $s2<br />
<strong>and</strong> immediate <strong>and</strong>i $s0,$s1,10 $s0 = $s1 & 10<br />
or or $s0,$s1,$s2 $s0 = $s1 | $s2<br />
or immediate ori $s0,$s1,100 $s0 = $s1 | 100<br />
nor nor $s0,$s1,$s2 $s0 = ~($s1 | $s2)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 21
Operationen und Oper<strong>and</strong>en (8)<br />
Zu den logischen Operationen gehören auch die<br />
Schiebebefehle zum Schieben eines Oper<strong>and</strong>en nach links<br />
oder rechts um eine bestimmte Anzahl von Bitpositionen:<br />
Name Beispiel Entsprechende Notation in<br />
C<br />
Shift Left sll $s0,$s1,4 $s0 = $s1 > 10<br />
Anmerkung:<br />
Die Schiebedistanz ist hier stets eine Konstante!<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 22
REGISTERSATZ<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 23
Registersatz (1)<br />
Zum Datenpfad eines Prozessors gehören:<br />
ALU: Rechenwerk für arithmetische und logische Operationen<br />
(Arithmetic Logic Unit)<br />
Registersatz<br />
Verbindungen, Multiplexer und Demultiplexer zur Verbindung von<br />
Registersatz und ALU<br />
Der Registersatz einer CPU besteht aus:<br />
Universalregister<br />
Für Integerzahlen oder Adressen, Wortbreite entspricht der<br />
Wortbreite der Architektur, z.B. 32 oder 64 Bit<br />
Gleitkommaregister<br />
Mit erhöhter Wortbreite von mindestens 64 Bit zur Speicherung von<br />
Gleitkommazahlen<br />
Kontrollregister<br />
Z.B. zur Beh<strong>and</strong>lung von Unterbrechungen und Ausnahmen<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 24
Registersatz (2)<br />
MIPS ISA hat 32 Universalregister, die wichtigsten sind:<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 25
Registersatz (3)<br />
Das Register $gp (global pointer) dient in der MIPS ISA als<br />
Zeiger auf statische Daten, die im .data Segment<br />
deklariert wurden.<br />
Typische Speicheraufteilung der MIPS ISA:<br />
Zeiger $gp wird mit dem<br />
Wert 10008000h initialisiert.<br />
Mit positiven u. negativen<br />
Offsets kann auf den<br />
Speicherbereich von<br />
10000000h bis 1000FFFFh<br />
zugegriffen werden.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 26
Registersatz (4)<br />
Das Register $fp (frame pointer) wird oft als Zeiger auf<br />
den Rahmen (frame) einer Prozedur im Stack verwendet.<br />
Als Rahmen bezeichnet man den Platz im Stack, in dem beim<br />
Prozeduraufruf gerettete Register, Rücksprungadressen und<br />
lokale Variablen der Prozedur gespeichert werden.<br />
Zeiger $fp zeigt auf definierte Position<br />
im Rahmen, z.B. das erste Wort.<br />
Zeiger $fp dient der einfachen<br />
Adressierung der geretteten<br />
Registerinhalte.<br />
Zeiger $sp ist hierzu ungeeignet, da er bei<br />
lokalen Prozedurvariablen auf den zuletzt<br />
belegten Stackplatz zeigt.<br />
Beispiel: lw $ra, 0($fp)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 27
Registersatz (5)<br />
Bei Verwendung des $fp Registers werden in der<br />
aufgerufenen Prozedur zu Beginn z.B. folgende Schritte<br />
durchgeführt:<br />
1. Reserviere den für den Rahmen benötigten Speicher auf dem<br />
Stack (durch Subtraktion des Bytebedarfs b vom Register $sp).<br />
2. Sichere $ra und folgende Register, sofern sie in der Prozedur<br />
geändert werden: $s0 bis $s7, und $fp.<br />
3. Setze $fp auf den ersten Rahmeneintrag durch Berechnung von<br />
$sp+b–4.<br />
Vor dem Verlassen müssen am Ende der Prozedur<br />
folgende Schritte durchgeführt werden:<br />
1. Restauriere die geretteten Register.<br />
2. Freigeben des Stacks durch Addition von b zu $sp.<br />
3. Rücksprung zur Adresse in $ra.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 28
MIPS INSTRUKTIONSWORT<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 29
MIPS Instruktionswort (1)<br />
MIPS Operationen werden in einem 32-Bit<br />
Instruktionswort kodiert (R-Format):<br />
Das R-Format Instruktionswort enthält 6 versch. Felder:<br />
Im Feld op wird die Basisoperation kodiert.<br />
Das Feld rs bezeichnet den ersten Quelloper<strong>and</strong>en (s = source).<br />
Das Feld rt den zweiten Quelloper<strong>and</strong>en.<br />
Das Feld rd das Zielregister (d = destination).<br />
Im Feld shamt wird für Schiebebefehle die Schiebedistanz (shift<br />
amount) angegeben.<br />
Das Feld funct dient zur Auswahl einer bestimmten Variante einer<br />
Operation.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 30
MIPS Instruktionswort (2)<br />
Für Lade-/Speicherbefehle und Befehle mit Immediate<br />
Oper<strong>and</strong> wird das I-Format Instruktionswort verwendet:<br />
Hierin bezeichnen:<br />
Das Feld op den Befehl<br />
Das Feld rs den Quelloper<strong>and</strong>en (s = source)<br />
Das Feld rt das Zielregister (!)<br />
Das Feld constant/address entweder einen konstanten<br />
(Immediate) Oper<strong>and</strong>en oder ein Displacement<br />
Zu beachten ist, dass für das Feld const nur 16 Bit zur<br />
Verfügung stehen, d.h. Konstanten sind z.B. nur im<br />
Bereich von –32768 bis 32767 möglich!<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 31
MIPS Instruktionswort (3)<br />
Für Sprungbefehle (siehe Abschnitt Sprungbefehle)<br />
existiert zusätzlich das J-Format:<br />
Hierin bezeichnen:<br />
Das Feld op den Befehl,<br />
Das Feld address eine 26-bit Adresse<br />
Zu beachten ist, dass im Feld address keine vollständige<br />
32-Bit Adresse gespeichert werden kann.<br />
Die effektive Adresse ergibt sich z.B. bei MIPS Sprungbefehlen aus<br />
einer Konkatenation von den 4 führenden Bits des Befehlszählers,<br />
den 26 Bit aus dem Instruktionswort sowie zwei Null-Bits (Sprung<br />
nur zu Befehl auf Langwort-Adresse).<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 32
MIPS Instruktionswort (4)<br />
Es ergeben sich z.B. folgende Befehlskodierungen:<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 33
ARTEN DER<br />
SPEICHERADRESSIERUNG<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 34
Arten der Speicheradressierung (1)<br />
In MIPS Assembler sind folgende Adressierungsarten möglich:<br />
1. Unmittelbare Adressierung (Immediate addressing): Oper<strong>and</strong><br />
ist eine Konstante, die direkt im Instruktionswort kodiert ist.<br />
2. Registeradressierung (Register addressing): Oper<strong>and</strong> steht im<br />
Register.<br />
3. Indirekte Adressierung mit Displacement (Base addressing):<br />
Oper<strong>and</strong> steht im Speicher auf der Adresse, die sich aus der<br />
Addition eines Register-Inhalts und des Displacements ergibt.<br />
4. Befehlszählerrelative Adressierung (PC-relative addressing):<br />
Adresse ergibt sich durch Addition eines Offsets zum St<strong>and</strong><br />
des Befehlszählers.<br />
5. Pseudodirekte Adressierung (Pseudodirect addressing):<br />
Adresse bei Sprungbefehlen ergibt sich durch Konkatenation<br />
der oberen 4 Bit des Befehlszählers, eines 26 Bit Felds der<br />
Instruktion, und 2 Null-Bits.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 35
Arten der Speicheradressierung (2)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 36
SPRUNGBEFEHLE<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 37
Sprungbefehle (1)<br />
Ähnlich der if-Anweisung einer Hochsprache können in<br />
Assembler auch bedingte Verzweigungen realisiert<br />
werden.<br />
Hierzu gibt es in MIPS Assembler die Maschinenbefehle<br />
beq reg1, reg2, label<br />
bne reg1, reg2, label<br />
Mit folgender Bedeutung:<br />
Ist bei beq (branch if equal) der Inhalt von reg1 gleich dem Inhalt<br />
von reg2, so wird zur Sprungmarke label verzweigt.<br />
Ist bei bne (branch if not equal) der Inhalt von reg1 ungleich dem<br />
Inhalt von reg2, so wird zur Sprungmarke label verzweigt.<br />
Ist die Bedingung nicht erfüllt, so wird nicht verzweigt und die<br />
Abarbeitung des Programms mit der folgenden Instruktion<br />
fortgesetzt.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 38
Sprungbefehle (2)<br />
Ebenso gibt es in der MIPS ISA eine unbedingte<br />
Verzweigung zu einer Sprungmarke:<br />
j label<br />
Beispiel: Das Hochsprachenprogrammfragment<br />
if (b == c) a = b + c;<br />
else a = b – c;<br />
kann in MIPS Assembler wie folgt realisiert werden<br />
(b in $s1, c in $s2):<br />
bne $s1,$s2,Else<br />
add $s0,$s1,$s2<br />
j Cont<br />
Else: sub $s0,$s1,$s2<br />
Cont: ...<br />
# Sprung, wenn b ≠ c<br />
# unbedingter Sprung<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 39
Sprungbefehle (3)<br />
Bedingte Verzweigungen können auch zur Realisierung<br />
von Schleifen eingesetzt werden.<br />
Beispiel: Das Hochsprachenprogrammfragment<br />
while (a[i] == 0) i += 1;<br />
kann in MIPS Assembler wie folgt realisiert werden<br />
(i in $s3, Adresse von a in $s1):<br />
Loop: sll $t0,$s3,2 # berechne 4 * i in $t0<br />
add $t1,$s1,$t0 # Adr. von a[i] in $t1<br />
lw $s2,0($t1) # lade a[i] in $s2<br />
bne $s2,$zero,Cont # Sprung bei a[i] ≠ 0<br />
addi $s3,$s3,1 # i = i + 1<br />
j Loop<br />
# unbedingter Sprung<br />
Cont: ...<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 40
Sprungbefehle (4)<br />
Zur Realisierung einer Schleife ist es oft auch sinnvoll, zu<br />
überprüfen, ob ein Registerinhalt kleiner oder größer als<br />
der Inhalt eines <strong>and</strong>eren Registers ist.<br />
Hierzu gibt es in MIPS Instruktionssatz die Befehle<br />
slt reg1, reg2, reg3<br />
slti reg1, reg2, const<br />
Bei der Ausführung<br />
wird überprüft ob der Inhalt von reg2 kleiner als der Inhalt von<br />
reg3 ist (slt = set on less than),<br />
bzw. ob der Inhalt von reg2 kleiner ist als die Konstante const<br />
(slti = set on less than immediate),<br />
wird reg1 auf 1 gesetzt, wenn Bedingung erfüllt ist, ansonsten<br />
auf 0,<br />
erfolgt ein Sprung erst durch eine folgende beq oder bne<br />
Instruktion.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 41
UNTERPROGRAMME<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 42
Unterprogramme (1)<br />
Folgende Schritte sind bei Aufruf einer Prozedur bzw.<br />
einer Funktion erforderlich:<br />
Die Parameter werden an einer vereinbarten Stelle (Speicher oder<br />
Register) abgelegt.<br />
Ablaufsteuerung wird an die Prozedur übergeben.<br />
In der Prozedur muss Speicher für lokale Variablen bereitgestellt<br />
werden.<br />
Prozedur wird bis zum Ende ausgeführt.<br />
Ergebnis wird an einer Stelle abgelegt, auf die das aufrufende<br />
Programm zugreifen kann.<br />
Ablaufsteuerung muss an das aufrufende Programm an die Stelle<br />
unmittelbar hinter dem Aufruf zurückgegeben werden.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 43
Unterprogramme (2)<br />
In MIPS Assembler werden Register für die<br />
Parameterübergabe verwendet.<br />
$a0 bis $a3 sind vier Argumentregister zur Übergabe von<br />
Parametern an die Prozedur bzw. Funktion.<br />
$v0 bis $v1 sind Register für Rückgabewerte.<br />
$ra ist ein Register für die Rücksprungadresse (return address).<br />
Zusätzlich bietet der MIPS Assembler den Befehl<br />
jal proc<br />
der den Aufruf einer Prozedur proc realisiert:<br />
Es wird zur Startadresse der Prozedur gesprungen.<br />
Die Rücksprungadresse (St<strong>and</strong> des aktuellen Befehlszählers +4)<br />
wird im Register $ra gespeichert.<br />
jal steht für jump <strong>and</strong> link, d.h. es wird ein Sprung ausgeführt<br />
und ein Verweis an die Stelle des Aufrufs gespeichert.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 44
Unterprogramme (3)<br />
Der Rücksprung aus einem Unterprogramm erfolgt mit<br />
der Instruktion<br />
jr $ra<br />
wobei zu der Adresse im Register $ra gesprungen wird.<br />
jr bedeutet jump register und bewirkt einen unbedingten Sprung<br />
zu der im Register gespeicherten Adresse.<br />
Beispiel: Berechnung von | x 2 – x 1 | (x2 in $s2, x1 in $s1)<br />
or $a0,$zero,$s2 # x2 nach a0<br />
or $a1,$zero,$s1 # x1 nach a1<br />
jal absdiff<br />
...<br />
absdiff: sub $v0,$a0,$a1 # berechnet diff = x2–x1<br />
slti $t0,$v0,0 # ist diff < 0?<br />
beq $t0,$zero,ret # Sprung falls positiv<br />
sub $v0,$zero,$v0 # berechnet –diff<br />
ret: jr $ra<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 45
Unterprogramme (4)<br />
Benötigt das Unterprogramm weitere Register, so müssen<br />
die Inhalte von Registern, die im aufrufenden Programm<br />
genutzt werden, ggf. gerettet werden.<br />
Hierzu werden die Inhalte der entsprechenden Register zu<br />
Beginn der Prozedur auf den Stack (auch als Keller<br />
bezeichnet) gesichert.<br />
Der Stack ist ein LIFO Puffer (Last In First Out) im<br />
Arbeitsspeicher eines Programms.<br />
in dem ein Stackzeiger (SP, Stack Pointer) auf den obersten<br />
belegten Eintrag zeigt,<br />
der von oben nach unten wächst, d.h. von höherwertigen zu<br />
niedrig-wertigen Adressen.<br />
In MIPS Assembler ist $sp für den Stackzeiger vorgesehen.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 46
Unterprogramme (5)<br />
Beispiel:<br />
gegebenes C-Programmfragment:<br />
int calc(int a, int b, int c, int d) {<br />
int res;<br />
res = (a – b) + (c – d);<br />
return res;<br />
}<br />
resultierendes Assembler-Programmfragment:<br />
calc: addi $sp,$sp,–8 # Speicher reservieren<br />
sw $t0,4($sp) # rette Inhalt von<br />
sw $t1,0($sp) # Registern t0,t1<br />
sub $t0,$a0,$a1 # Rechnung mit<br />
sub $t1,$a2,$a3 # zwei Hilfsregistern<br />
add $v0,$t0,$t1<br />
lw $t0,4($sp) # Inhalt von t0,t1<br />
lw $t1,0($sp) # wiederherstellen<br />
addi $sp,$sp, 8 # Speicher freigeben<br />
jr $ra<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 47
Unterprogramme (6)<br />
In nicht geschachtelten Prozeduren kann in MIPS<br />
Assembler i.a. auf das Retten der Register verzichtet<br />
werden, da folgende Konvention gilt:<br />
Register $s0 bis $s7 beinhalten Variablen, die in der Prozedur<br />
vor Benutzung gerettet werden müssen.<br />
Register $t0 bis $t9 beinhalten temporäre Werte, die bei einem<br />
Prozeduraufruf überschrieben werden dürfen und somit nicht<br />
gerettet werden müssen.<br />
Im Falle geschachtelter oder rekursiver Prozeduren ist<br />
jedoch ein Retten der Register unvermeidlich:<br />
Zumindest die Rücksprungadresse muss auf dem Stack gerettet<br />
werden, zumeist auch die Inhalte weiterer Register.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 48
Unterprogramme (7)<br />
Beispiel:<br />
rekursives C-Programmfragment zur Berechnung von n! :<br />
int fact(int n) {<br />
if (n
ARITHMETIK IN MIPS<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 50
Addition und Subtraktion bei MIPS (1)<br />
In der MIPS ISA wird zwischen zwei Arten der Addition<br />
und Subtraktion unterschieden:<br />
Bei der einfachen Addition (Befehle add, addi, sub) wird eine<br />
Ausnahme generiert, wenn ein Überlauf bei der Addition oder<br />
Subtraktion von Zweierkomplementzahlen eintritt.<br />
Ausnahmen werden erst später in der Vorlesung beh<strong>and</strong>elt!<br />
Bei der vorzeichenlosen Addition (neue Befehle addu, addiu,<br />
und subu) werden Zahlen als vorzeichenlos angenommen und ein<br />
Überlauf ignoriert.<br />
Diese Befehle sollten auch für alle vorzeichenbehaftete Additionen<br />
und Subtraktionen verwendet werden, wenn wie in der<br />
Programmiersprache C Überläufe ignoriert werden sollen.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 51
Addition und Subtraktion bei MIPS (2)<br />
Soll per Software abgefragt werden, ob bei der Addition<br />
zweier vorzeichenbehafteter Zahlen ein Überlauf<br />
aufgetreten ist, so ist dies mit folgender MIPS<br />
Befehlssequenz möglich (Zahlen in $t1 und $t2):<br />
addu $t0, $t1, $t2<br />
xor $t3, $t1, $t2<br />
slt $t3, $t3, $zero<br />
bne $t3, $zero, no_overflow<br />
xor $t3, $t0, $t1<br />
slt $t3, $t3, $zero<br />
bne $t3, $zero, overflow<br />
# Summe ohne Überlauftest<br />
# Vorzeichen unterschiedlich?<br />
# Sprung, wenn Vorzeichen<br />
# unterschiedlich<br />
# stimmt Vorzeichen<br />
# der Summe?<br />
# Sprung bei falschem<br />
# Vorzeichen<br />
Entsprechende Befehlssequenzen gibt es auch zur<br />
Erkennung eines Überlaufs bei einer Subtraktion oder bei<br />
einer Addition vorzeichenloser Zahlen.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 52
Multiplikation in MIPS ISA (1)<br />
In der MIPS ISA werden zwei 32-Bit Zahlen aus zwei<br />
Registern multipliziert:<br />
mult reg1,reg2<br />
multu reg1,reg2<br />
# vorzeichenbehaftete<br />
# Multiplikation<br />
# vorzeichenlose<br />
# Multiplikation<br />
# (multiply unsigned)<br />
Ergebnis hat eine Wortbreite von 64 Bit und befindet sich<br />
in den Spezialregistern Hi und Lo, die jeweils 32 Bit breit<br />
sind.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 53
Multiplikation in MIPS ISA (2)<br />
Weiterverarbeitung des Produktes erfolgt durch<br />
mfhi reg4<br />
mflo reg3<br />
# Laden der höheren 32 Bit des<br />
# Produktes<br />
# Laden der niedrigen 32 Bit des<br />
# Produkts<br />
Der Assembler realisiert zusätzlich den Pseudobefehl<br />
mul reg3,reg1,reg2 # vorzeichenbehaftete<br />
# Multiplikation<br />
Ohne Überprüfung, ob das Ergebnis in 32 Bit dargestellt werden<br />
kann!<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 54
Division in MIPS ISA<br />
In der MIPS ISA werden zwei 32-Bit Zahlen aus zwei<br />
Registern dividiert:<br />
div reg1,reg2<br />
divu reg1,reg2<br />
# vorzeichenbehaftete<br />
# Division<br />
# vorzeichenlose Division<br />
# (divide unsigned)<br />
Quotient befindet sich nach Ausführung der Division im<br />
Spezialregister Lo, der Rest im Spezialregister Hi.<br />
Weiterverarbeitung erfolgt wie bei der Multiplikation mit<br />
den Befehlen mfhi und mflo.<br />
Der Assembler realisiert zusätzlich den Pseudobefehl<br />
div reg3,reg1,reg2 # Quotient nach reg3<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 55
Gleitkommazahlen in MIPS ISA (1)<br />
MIPS ISA unterstützt Gleitkommaformate für einfache und<br />
doppelte Genauigkeit.<br />
Arithmetische Operationen für einfache Genauigkeit erhalten den<br />
Suffix .s (single precision), arithmetische Operationen für<br />
doppelte Genauigkeit den Suffix .d (double precision).<br />
Ansonsten werden die gleichen Befehle wie für Operationen auf<br />
ganzzahligen Daten verwendet: add, sub, mul, div<br />
32 zusätzliche Register für Gleitkommazahlen: $f0 bis $f31<br />
Bei einigen MIPS CPUs haben diese nur eine Breite von 32 Bit, für<br />
Gleitkomma-zahlen doppelter Genauigkeit werden zwei Register<br />
konkateniert, daher sind dort nur $f0, $f2, $f4, ... zulässig.<br />
Beispiele: add.s $f2,$f3,$f4<br />
mul.s $f5,$f2,$f3<br />
sub.d $f6,$f8,$f12<br />
div.d $f6,$f6,$f14<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 56
Gleitkommazahlen in MIPS ISA (2)<br />
Die Gleitkomma-Arithmetik war in der MIPS Architektur<br />
ursprünglich im separaten Koprozessor 1 implementiert.<br />
In den aktuellen CPU-Version ist der Koprozessor natürlich auf<br />
dem Chip integriert.<br />
Zugriff auf Gleitkommazahlen im MIPS Programm.<br />
Die zusätzlichen Assembler-Direktiven .float und .double<br />
ermöglichen das Ablegen von Gleitkommawerten im Speicher.<br />
Laden und Speichern von 32-Bit Gleitkommazahlen:<br />
lwc1 freg,disp(reg) # load word to coprocessor 1<br />
swc1 freg,disp(reg) # store word from<br />
# coprocessor 1<br />
Für die Adressberechnung beim Speicherzugriff wird trotzdem ein<br />
Integerregister reg verwendet.<br />
Der Assembler bietet zusätzlich die Pseudo-Instruktionen l.s,<br />
l.d, s.s und s.d an.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 57
Gleitkommazahlen in MIPS ISA (3)<br />
Bedingte Verzweigungen sind in der MIPS FPU mächtiger<br />
als in der Integer-ALU.<br />
Es gibt verschiedene Vergleichsoperationen x: equal (eq), not<br />
equal (neq), less than (lt), greater than (gt), less than or equal<br />
(le), greater than or equal (ge)<br />
Zum Vergleich gibt es dann Instruktionen:<br />
c.x.s freg1,freg2<br />
c.x.d freg1,freg2<br />
# für einfache Genauigkeit<br />
# für doppelte Genauigkeit<br />
Diese Befehle setzen ein internes Bedingungsflag c, wenn die<br />
Bedingung erfüllt ist.<br />
Für die bedingten Sprünge gibt es dann die Befehle:<br />
bc1t label # Sprung, wenn Bedingung erfüllt ist<br />
# (true)<br />
bc1f label # Sprung, wenn Bedingung nicht erfüllt<br />
# ist (false)<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 58
Gleitkommazahlen in MIPS ISA (4)<br />
MIPS Beispielprogramm für Gleitkommazahlen:<br />
Umrechnung Fahrenheit in Celsius<br />
float f2c (float fahr) {<br />
return ((5.0/9.0) * (fahr – 32.0));<br />
}<br />
Per Konvention wird Gleitkommaargument in $f12 (ggf. +<br />
$f13), Rückgabewert in $f0 (ggf. + $f1) abgelegt.<br />
f2c: lwc1 $f16,const5($gp) # Konstante 5.0<br />
lwc1 $f18,const9($gp) # Konstante 9.0<br />
div.s $f16,$f16,$f18<br />
lwc1 $f18,const32($gp) # Konstante 32.0<br />
sub.s $f18,$f12,$f18<br />
# fahr aus f12<br />
mul.s $f0,$f16,$f18<br />
jr $ra<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 59
ENTWURF EINER ISA<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 60
Entwurf einer ISA (1)<br />
Kodierung der Instruktionen im Instruktionswort stellt<br />
beim Entwurf einer ISA stets einen Kompromiss dar:<br />
Ziel ist einheitliches kompaktes Instruktionswort (z.B. 32-Bit).<br />
Für Zwischenergebnissen möchte man viele Register.<br />
log 2 k Bits im Instruktionsw. zur Adressierung von k Registern nötig.<br />
Instruktionen mit 3 Oper<strong>and</strong>en (2 Quellen, 1 Ziel) bieten höchste<br />
Flexibilität, erfordern aber drei k-Bit Felder im Instruktionswort.<br />
Man möchte Direktoper<strong>and</strong>en mit der Prozessor-Wortbreite (z.B.<br />
32-Bit).<br />
Nicht möglich!<br />
Zur Kodierung der Offsets bei Sprungbefehlen steht nur eine<br />
beschränkte Anzahl von Bits zur Verfügung.<br />
Absolute Sprungadressen können oft nicht in einem kurzen<br />
Befehlswort kodiert werden.<br />
Tricks nötig!<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 61
Entwurf einer ISA (2)<br />
Evolution der Prozessorarchitekturen<br />
CISC (Complex Instruction Set <strong>Computer</strong>)<br />
Vorteil<br />
Semantische Lücke überbrückbar: durch Mikroprogramm einen<br />
Hochsprachenbefehl implementieren<br />
Nachteile<br />
neue Prozessoren Erweiterung der Befehlssätze, aber Zwang zur<br />
Abwärtskompatibilität<br />
Compiler-Bauer verwendeten nur kleine Teilmenge des Befehlssatzes<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 62
Entwurf einer ISA (3)<br />
RISC (Reduced Instruction Set <strong>Computer</strong>)<br />
Elementare, kleine Maschinenbefehlssätze<br />
Oper<strong>and</strong>en- und Befehlsholphasen in einem Grundtakt ausführbar<br />
Adressrechnungen werden durch explizite Befehle ausgeführt<br />
Keine komplizierten Adressierungsarten<br />
Load-Store-Architektur<br />
Alle Oper<strong>and</strong>en liegen in Registern vor<br />
Beispiel: Intel Pentium basiert auf CISC-Architektur, seit Pentium Pro wird der komplexe<br />
Intel-Maschinenbefehlssatz intern in eine Folge einfacher RISC-Befehle zerlegt<br />
Typische „General Purpose“-Prozessoren nutzen heute<br />
Caches nächstes Kapitel<br />
Pipelining<br />
Superskalare Befehlsabarbeitung<br />
Out-of-order execution<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 63
Beispiel CISC - Intel x86 ISA (1)<br />
Kurze Geschichte der Intel x86 ISA (auch IA-32)<br />
1978: Intel 8086 erscheint als 16-Bit Architektur.<br />
1980: Intel 8087 FPU wird hinzugefügt.<br />
1982: Im Intel 80286 wird der Adressraum auf 24 Bit erhöht;<br />
neue Instruktionen werden hinzugefügt.<br />
1985: Intel 80386 ist eine 32-Bit CPU mit neuen<br />
Adressierungsarten.<br />
1989-1995: Intel 80486, Pentium, Pentium Pro bieten nur wenige<br />
neue Instruktionen (überwiegend für höhere Leistung)<br />
1997: 57 neue MMX Instruktionen im Pentium II.<br />
1999: Pentium III bietet SSE mit 70 weiteren Instruktionen.<br />
2001: Pentium 4 bietet SSE2 mit 144 neuen Instruktionen.<br />
2003: AMD erweitert mit AMD64 die Architektur auf 64 Bit.<br />
2004: Intel übernimmt AMD64 (und nennt es EM64T).<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 64
Beispiel CISC - Intel x86 ISA (2)<br />
Intel x86 Registersatz:<br />
General Purpose Register<br />
Base Pointer<br />
Index Register<br />
Segment<br />
Register<br />
GPR können als 8-Bit, 16-Bit oder<br />
32-Bit Register genutzt werden.<br />
Zusätzliche acht 80-Bit float Register implementiert als Stack.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 65
Beispiel CISC - Intel x86 ISA (3)<br />
Intel x86 ISA bietet sieben Adressierungsarten:<br />
absolute<br />
register indirect<br />
based<br />
wie register indirect, aber benutzt base register bx oder bp<br />
based indexed<br />
Adresse ist base register + index register<br />
based indexed with displacement<br />
Adresse ist base register + index register + 8 oder 16 bit<br />
displacement<br />
based with scaled indexed<br />
zusätzlicher Scaling Faktor für index register ist entweder 1, 2, 4 oder<br />
8<br />
based with scaled indexed <strong>and</strong> displacement<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 66
Beispiel CISC - Intel x86 ISA (4)<br />
Beispiel Code in C:<br />
int a[10];<br />
int i;<br />
/* i gets some value */<br />
a[i]=12;<br />
a[i+2]=a[i+1];<br />
Gleicher Code im x86 Assembler:<br />
/* assume that &a is in %edi <strong>and</strong> i is in %esi */<br />
movl $12,(%edi,%esi,4) # Mem[%edi+%esi*4]=12<br />
movl 4(%edi,%esi,4),%eax # %eax=Mem[4+%edi+%esi*4]<br />
movl %eax,8(%edi,%esi,4) # Mem[8+%edi+%esi*4]=%eax<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 67
Beispiel CISC - Intel x86 ISA (5)<br />
Alle Adressen werden mit Hilfe der Segment Register CS,<br />
SS, DS oder ES gebildet:<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 68
Beispiel CISC - Intel x86 ISA (6)<br />
Länge einer Instruktion variiert zwischen<br />
1 und 17 Bytes:<br />
Bis zu 9 Byte für 8086 Instruktionen (in<br />
schwarz dargestellt)<br />
Bis zu 17 Byte für 80386 Instruktionen (in<br />
grau dargestellt)<br />
Opcodes werden durch Präfixe<br />
modifiziert.<br />
Beispiel:<br />
Default Oper<strong>and</strong>enlänge (8, 16, or 32 bit)<br />
wird in Kontrollregister gesetzt.<br />
Kann durch ein 8-bit Präfix überschrieben<br />
werden.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 69
Beispiel CISC - Intel x86 ISA (7)<br />
Alle arithmetisch/logischen Befehle haben zwei<br />
Oper<strong>and</strong>en.<br />
Ein Oper<strong>and</strong> ist gleichzeitig Quelle und Ziel.<br />
Quellen können entweder 2 Register oder Register +<br />
Speicherwort sein, Ziel ist entweder Register oder<br />
Speicheradresse des 2. Oper<strong>and</strong>en.<br />
Wachstum der x86 ISA:<br />
Der Instruktionssatz ist nicht orthogonal: z.B. sind nicht<br />
alle Adressierungsarten für alle Instruktionen möglich.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 70
ÜBERSETZUNG EINES PROGRAMMS<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 71
Übersetzung eines Programms<br />
Bei der Übersetzung eines C-Programms werden folgende<br />
Schritte ausgeführt:<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 72
Assembler (1)<br />
Assembler übersetzt Programm aus Assemblersprache in<br />
binäres Maschinenprogramm:<br />
Erlaubt Verwendung von symbolischen Namen für<br />
Speicheradressen und Sprungmarken.<br />
Realisiert eine Vielzahl von Pseudobefehlen zur Erweiterung des<br />
Instruktionssatzes (siehe Proseminar).<br />
Beispiel:<br />
Der Pseudobefehl mov $s0,$t1 des MIPS Assemblers erlaubt einen<br />
Datentransfer zwischen Registern und kann z.B. durch den MIPS.<br />
Maschinenbefehl addi $s0,$t1,0 realisiert werden.<br />
Stellt Direktive zur Steuerung der Assemblierung bereit.<br />
Erlaubt Arbeiten mit Zahlen in unterschiedlichen Formaten (z.B.<br />
dezimal, binär, oktal, hexadezimal).<br />
Unterstützt die Möglichkeit von Betriebssystem-Aufrufen (System<br />
Calls).<br />
Erzeugt schließlich eine Objektdatei ...<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 73
Assembler (2)<br />
Vom Assembler erzeugte Objektdatei besteht aus:<br />
Header mit Informationen über Größe und Positionen der<br />
einzelnen Teile der Objektdatei.<br />
Programmsegment (auch als Textsegment bezeichnet) mit<br />
binärem Maschinenprogramm.<br />
Datensegment mit statischen Daten.<br />
Informationen zur Relokation des Programms (Tabelle mit<br />
Instruktionen und Daten, die beim Laden von absoluten Adressen<br />
abhängen).<br />
Eine Symboltabelle mit Adressen von extern ansprechbaren<br />
Symbolen und intern nicht auflösbaren symbolischen Referenzen.<br />
Informationen zum Debugging des Assemblerprogramms.<br />
Detailliertes Format der Objektdatei ist vom<br />
Betriebssystem abhängig!<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 74
Assembler (3)<br />
Auswahl einiger Direktive des MIPS Assemblers:<br />
.text markiert Beginn des Programmsegments.<br />
.data markiert Beginn des Datensegments.<br />
.align n richtet nächstes Datum an 2 n Bytegrenze aus.<br />
.word w1,w2,...,wn füllt Speicher mit den n 32-Bit Worten<br />
w1,w2,...,wn.<br />
.byte b1,b2,...,bn füllt Speicher byteweise mit den<br />
angegebenen Inhalten b1,b2,...,bn.<br />
.space num reserviert Speicher für num Bytes (nicht initialisiert).<br />
.asciiz str stellt den String str in den Speicher (mit<br />
Terminierung durch Byte Null).<br />
.globl symb deklariert Sprungmarke oder Adresse symb als<br />
global.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 75
Assembler (4)<br />
Mögliche Systemaufrufe in MIPS Assembler bei Verwendung<br />
eines Simulators (Auswahl):<br />
code Bezeichnung Argumente und Wirkung<br />
1 print_int Gibt Inhalt von $a0 aus (Integer).<br />
4 print_string Gibt einen String (mit Terminierung durch Byte<br />
Null) ab Adresse $a0 aus.<br />
5 read_int Liest in $v0 einen Wert ein.<br />
8 read_string Liest ab Adresse $a0 einen String aus $a1<br />
Zeichen ein.<br />
9 sbrk Reserviert $a0 Byte im Speicher, Startadresse<br />
wird in $v0 zurückgegeben.<br />
10 exit Gibt Kontrolle an Betriebssystem zurück.<br />
Syntax:<br />
li $v0, code<br />
lw $a0, addr<br />
syscall<br />
# Pseudobefehl "load immediate"<br />
# ggf. Argument laden<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 76
Assembler (5)<br />
Aufbau eines MIPS Assemblerprogramms (Beispiel):<br />
.data<br />
x: .word 12<br />
y: .word 14<br />
z: .word 18<br />
res: .space 4<br />
str: .asciiz "Fertig."<br />
.align 2<br />
.globl main<br />
.text<br />
main: lw $t0, x # Eingabewerte laden<br />
lw $t1, y<br />
lw $t2, z<br />
add $t0, $t0, $t1<br />
add $t0, $t0, $t2<br />
sw $t0, res<br />
li $v0, 4<br />
# Pseudobefehl "load immediate"<br />
la $a0, str<br />
# Pseudobefehl "load address"<br />
syscall<br />
# Ausgabe des Strings<br />
li $v0, 10<br />
syscall<br />
# Ende<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 77
Linker<br />
Eine Objektdatei ist nicht ausführbar, da<br />
sie noch keine absoluten Adressen enthält,<br />
sie häufig externe Referenzen enthält (zu Daten und Prozeduren<br />
in <strong>and</strong>eren Objektdateien oder Bibliotheken).<br />
Der Linker fügt mehrere Objektdateien zusammen und<br />
generiert ein ausführbares Binärprogramm.<br />
Hierzu führt er folgende Schritte durch:<br />
Ablegen der Text- und Datensegmente in den Speicher und<br />
Festlegen der jeweiligen Speicherbereiche.<br />
Bestimmung globaler, absoluter Adressen für alle Marken unter<br />
Verwendung der Symboltabellen aller Objektmodule.<br />
Anpassen aller internen und externen Referenzen in den<br />
Textsegmenten.<br />
Erstellen eines ausführbaren Programms im Format einer<br />
Objektdatei.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 78
Lader<br />
Bei der Ausführung eines Programms durch den Lader<br />
(Loader) werden folgende Schritte ausgeführt:<br />
Einlesen des Headers, um die Größe des Daten- und<br />
Textsegmentes zu ermitteln.<br />
Bereitstellen von Arbeitsspeicher für Daten und Text.<br />
Laden von Daten und Text in Arbeitsspeicher.<br />
Schreiben der Aufrufparameter für Hauptprogramm auf Stack.<br />
Initialisieren einiger Register und des Stackzeigers.<br />
Aufruf einer Startprozedur, die die Aufrufparameter in<br />
Argumentregister kopiert und das Hauptprogramm aufruft.<br />
[TI] Winter 2013/2014 <strong>Instruktionssatzarchitektur</strong> 79