10.01.2014 Aufrufe

Instruktionssatzarchitektur - Computer and Communication Systems

Instruktionssatzarchitektur - Computer and Communication Systems

Instruktionssatzarchitektur - Computer and Communication Systems

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!