grundlagen der informatik iii - tu darmstadt · pdf fileprof. dr. rer. nat. frederik armknecht...
TRANSCRIPT
Prof. Dr. rer. nat. Frederik Armknecht
Sascha Müller
Daniel Mäurer
Fachbereich Informatik / CASEDMornewegstraße 3064293 Darmstadt
Grundlagen der Informatik III
WS 2008 / 2009
[Folien basierend auf VL von Prof. Dr. Claudia Eckert, WS 07/08]
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 2
Gliederung der Vorlesung GdI 3
1. Einführung 2. Assemblerprogrammierung 3. Leistungsbewertung4. Speicherhierarchie5. Assembler, Binder, Lader6. Betriebssysteme und Ein-/Ausgabe (Grundlagen)7. Rechnernetze (Grundlagen)8. Compiler (Grundlagen)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 3
Gliederung dieses Kapitels
2.1 Instruktionssatz2.2 Variablen und Register2.3 Speicherorganisation2.4 Speicherbefehle2.5 Befehlsformate2.6 Konzept der universellen Interpretierbarkeit2.7 Übersetzung von Kontrollstrukturen2.8 Verarbeitung von Zeichen2.9 Höhere Kontrollstrukturen: Prozeduren2.10 Adressierung2.11 Fazit
Ziel: systemnahes Programmieren auf der Assemblerebene unter Nutzung desMARS-Simulators für die MIPS-RISC-Architektur
Achtung: Vorlesung ist kein Assemblerkurs; sie erläutert wichtige Prinzipien.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 4
2.1 Instruktionssatz (Befehlssatz, instruction set):• Maschinen-Sprache zur Beschreibung der einzelnen Aktionen, die ein Prozessor ausführen kann
• so einfach wie möglich gehalten, primitive SpracheBeispiel in Vorlesung:• MIPS-R2000-Instruktionssatz• einfach, bietet alle wichtigen Konzepte
Kapitel 2 Assemblerprogrammierung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 5
swap(int v[], int k){int temp;
temp =v[k];v[k] =v[k+1];v[k+1] = temp;
}
swap:muli $2, $5,4add $2, $4,$2lw $15, 0($2)lw $16, 4($2)sw $16, 0($2)sw $15, 4($2)jr $31
00000000101000010000000000011000000000001000111000011000001000011000110001100010000000000000000010001100111100100000000000000100101011001111001000000000000000001010110001100010000000000000010000000011111000000000000000001000
Binary machinelanguageprogram(for MIPS)
Ccompiler
Assembler
Assemblylanguageprogram(for MIPS)
High-levellanguageprogram(in C)
Instruktionssatz: Schnittstelle (Interface) zwischen Compiler und Rechner
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 6
„ Addiere die Werte der beiden Variablen ‘b‘ und ‘c‘ und weise das Ergebnis der Variablen ‘a‘ zu “
add a, b, c
Assemblerbefehle (instructions) stark formalisiert:
• alle Arithmetikbefehle haben genau 3 Variablen:Zwei Argumente und einen Ergebnisoperanden
• feste Reihenfolge der Variablen (Ergebnis zuerst)
• jede Zeile ein Befehl
MIPS-Arithmetik: Erstes Beispiel
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 7
Pseudobefehle
Maschinensprache umfasst normalerweise nur eine kleine Anzahl an möglichen InstruktionenManche Operationen sind nicht direkt implementiert, sondern müssen
durch andere realisiert werden. Einige Assembler unterstützen sogenannte Pseudobefehle. Dies sind
Befehle, die es in der Maschinensprache nicht gibt, aber häufig gebraucht werden. Der Assembler übersetzt diese dann in eine geeignete Sequenz von
„echten“ Assemblerbefehlen. Aus didaktischen Gründen werden wir im Folgenden gelegentlich
Pseudobefehle verwenden. Diese sind mit eckigen Klammern markiert.Mehr dazu später …
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 8
a = b + c; add a, b, c
C MIPS-Assembler
d = a - e; sub d, a, e
f=(g+h)–(i+j)
add t0, g, hadd t1, i, jsub f, t0, t1
... oder etwas komplizierter: temporäre Variable
Beachten von Operator-Prioritäten ( Reihenfolge)
Übersetzung einfacher C-Programme
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 9
2.2 Variablen und Register
Variablen• Unterschied zu höheren Programmiersprachen:
Operanden müssen auf begrenzte Anzahl elementarer Speichereinheiten („Register“) des Prozessors abgebildet werden.
Register:• Register sind Teile der Programmierer-Schnittstelle• direkt vom Programm aus zugreifbar• besitzen eine feste, identische Länge (Wortbreite), • derzeit typischerweise noch 32 bit (künftig 64 bit)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 10
2.2 Variablen und Register
MIPS-Architektur besitzt• 32 Register mit je 32 bit,• Register mit spezieller Funktion:
• Register 0 und 31• frei benutzbare Register:
• Register 1, 2, ..., 30• Register besitzen symbolische Namen:
• Benennung: $ <name>
Patterson/Hennessy: Benennung der Register entsprechend der Nutzung im GNU C Compiler
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 11
MIPS GNU C Registerbenutzung
Name Nr. Funktion Gesichert?
$zero 0 der konstante Wert 0 bleibt
$at 1 reserviert für Assembler
$v0, $v1 2, 3 Resultatwerte und Auswertung von
Ausdrücken nein
$a0 ... $a3 4-7 Argumente nein
$t0 ... $t7 8-15 Zwischenwerte (temporär) nein$s0 ... $s7 16-23 gesichert (saved) ja
Beispiel für Nutzung: add $t0, $s2, $t0 addiere Inhalte der Register $t0 und $s2 und speichere das Ergebnis in Register $t0 ab
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 12
MIPS GNU C Registerbenutzung
Name Nr. FunktionGesichert?
$t8 ... $t9 24-25 weitere Zwischenwerte nein
$k0, $k1 26, 27 Betriebssystem (OS kernel)
$gp 28 globaler Zeiger (global pointer) ja
$sp 29 Zeiger auf Kellerspeicher (stack pointer) ja
$fp 30 Rahmenzeiger (frame pointer) ja
$ra 31 Rücksprungadresse (return address) ja
(vgl. Patterson/Hennessy, Seite A-24, Figure A.6.1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 13
Das Beispiel mit Registern
f=(g+h)–(i+j)
add $t0, $s1, $s2add $t1, $s3, $s4sub $s0, $t0, $t1
add t0, g, hadd t1, i, jsub f, t0, t1
Die Variablen der C-Anweisung wurden der Reihe nach den Registern $s0 - $s4 zugeordnet.
Aber: Wie kommen die Variablenwerte in die Register?
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 14
Register versus Speicher
Problem: Arithmetische Instruktionsoperanden müssen Register sein —nur 32 Register verfügbar
• Übersetzer weist den Variablen Register zu• Was aber bei Programmen mit vielen Variablen ?
• d.h. Datenstrukturen müssen im Speicher gehalten werden: wo, wie? Und wie kommen sie in Register?
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 15
Speicher: sehr großes, eindimensionales Bit-Feld
• Elemente des Feldes sind über Adressen identifizierbar
• Eine Speicheradresse ist als ein Index in das Feld zu interpretieren
• „Byte Adressierung“ bedeutet, der Index zeigt auf ein Byte (=8 Bit)
Antwort: Ablage im Speicher, Zugriff über Adresse,Load/Store Befehle im Assembler
2.3.1 Byte-Adressierung
2.3 Speicherorganisation
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 16
Byte: relativ kleine Einheit Zur einfacheren Handhabung: größere Einheiten, die „Worte“, häufig:
1 word = 32 Bit (4 Byte)MIPS-Befehlssatz: jedes Wort besteht aus 4 Byte
2.3.2 Worte
• Ein Register enthält 32 Bit an Daten
• Mit dem Inhalt eines 32-bit Registers lassen sich 232
Byte mit Byte-Adressen von 0 bis 232–1 adressieren
• 230 Worte mit Byte-Adressen 0, 4, 8, ... 232–4
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 17
Worte sind sequentiell abgelegt und dürfen nur an Adressen beginnen, die durch die Wortgröße teilbar sind: diese Eigenschaft heißt Alignment
Dadurch erreicht man effizientere Speicherzugriffe: pro Wort ist nur eine Adressberechnung erforderlich
Ausnutzen dieser Organisation: • z.B. bei der Verarbeitung von Feldern
• Array-Elemente werden sequentiell abgelegt• Ein Register z.B. $s3 enthält die Anfangsadresse (Basisadresse) • Element-Adresse A[i]: i-tes Element des Feldes A:
Basisadresse + 4* i
2.3.2 Worte
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 18
Big Endian: das Byte mit höchstwertigsten Bits wird zuerst gespeichert, d.h. an der
kleinsten Speicheradresse.
Little-Endian das Byte mit niederwertigsten Bits wird zuerst gespeichert
Beispiel aus dem täglichen Leben: Datumsformat yyyy-mm-dd : Big Endian dd-mm-yyyy : Little Endian
Bem.: MIPS kennt Big- und Little Endian Order MARS-Simulator: arbeitet mit Little Endian
2.3.3 Byte-Order
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 19
2.4 MIPS Speicherbefehle: Lade und Speichere
lw: load word (lade Wort), sw: save word (speichere Wort) Beispiel: C: A[8] = h + A[8]
MIPS: lw $t0, 32($s3) ($s3 enthalt Startadresse von A)add $t0, $s2, $t0sw $t0, 32($s3)
bei sw Zieladresse am Schluss Arithmetikoperanden müssen Register, können nicht Speicheradressen
sein! MIPS-Adressierungsmodus: Konstante (Basisregister): Adresse = Konstante + Inhalt des Basisregisters z.B. 32($s3) = Offset/Index (32) + Basis-(Index-)Register ($s3) lw und sw einzige Befehlstypen, die auf Speicher zugreifen!
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 20
2.4 MIPS Speicherbefehle (Beispiel 1)
Beispiel: C: int V[6];a = V[2]; V[4] = a;
MIPS: $s1: Basisadresse von V$s0: a
Ladebefehl: Datenübertragung Speicher Register
lw $s0, 8($s1)
Speicherbefehl: Datenübertragung Register Speicher
sw $s0, 16($s1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 21
2.4 MIPS Speicherbefehle (Beispiel 2)
swap(int v[], int k);{int temp;
temp = v[k]v[k] = v[k+1]v[k+1]= temp;
}swap:
[mul $2, $5, 4] # $2 = k*4add $2, $4, $2 # $2 = v + k*4lw $16, 0($2) # lade Inhalt von v[k]lw $17, 4($2) # lade Inhalt v[k+1]sw $17, 0($2) # v[k] = v[k+1]sw $16, 4($2)jr $31 # fahre beim Aufrufer fort
Wert von k steht in Register $5Startwert von v steht in Register $4
Adressberechnungvon v[k]
Datentransport
Rücksprung
Erinnerung: Befehle in eckigen Klammern
bezeichnen Pseudobefehle
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 22
Beispiel: C: g = h + A[i]
MIPS Registerzuweisung: $s1: g$s2: h$s3: Basis von A$s4: i
Index auf Speicheradressen abbilden (mit 4 multiplizieren):
mul: Normale Multiplikation [mul $2, $5, 4] (effizienter) sll: Shift 2 Stellen nach links sll $t1, $s4, 2
Wortadresse zu Basisadresse addieren add $t1, $t1, $s3
Array-Element laden lw $t0, 0($t1)
Addition ausführen add $s1, $s2, $t0
2.4 C-Programme mit variablen Array-Indizes
(Adresse von A(i) in $t1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 23
2.4 Zwischenbilanz
MIPS Laden von Worten, Adressieren von Bytes Arithmetik nur auf Registern
Instruktionen Bedeutung
add $s1, $s2, $s3 $s1 = $s2 + $s3sub $s1, $s2, $s3 $s1 = $s2 - $s3lw $s1, 100($s2) $s1 = Memory[$s2+100]sw $s1, 100($s2) Memory[$s2+100] = $s1
und auch bereits: Immediate Befehle, Shift
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 24
2.5 MIPS Befehlsformate
Background• Auch Instruktionen sind 32 Bits lang• Beispiel: Repräsentation eines Additionsbefehls• Beispiel: MIPS-Assembler: add $t0, $s1, $s2• Jedes Register hat eigene Nummer:
$t0=8, ..., $t7=15, $s0=16, ..., $s7=23• Dezimaldarstellung des Additionsbefehls:
0 17 18 8 0 32
AdditionZielregisterOperandenregister hier unbenutzt
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 25
2.5 MIPS Befehlsformate
0 17 18 8 0 32
AdditionZielregisterOperandenregister hier unbenutzt
In Binärdarstellung:
000000 10001 10010 01000 00000 100000
6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
Beispiel:10010binär = 1×24 + 0×23 + 0×22 + 1×21 + 0×20 = 18dezl
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 26
op rs rt rd shamt funct
6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
• op: „opcode“; Grundtyp des Befehls (instruction)• rs: erster Operand (Register!)• rt: zweiter Operand (Register!)• rd: Ziel (Register!)• shamt: „shift amount“, für sogenannte Schiebeoperationen wichtig
(siehe später)• funct: „Funktionscode“; Ergänzung zu op: genaue Spezifikation der
durchzuführenden OperationZusammenfassung der MIPS-Architektur bis hierher siehe:
Patterson/Hennessy, Seite 67, Figure 2.7
2.5.1 MIPS-Befehlsformat „R“ (für Register)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 27
adressrtrsop
6 Bit 5 Bit 5 Bit 16 Bit
• op: „opcode“; Grundtyp des Befehls (instruction)• rs: Basisadressregister• rt: Zielregister• adress: Konstante, die Offset bzgl. Basisregister angibt
• lw, sw benötigen 2 Register und 1 Konstante als Array-Offset
• Konstante kann länger als 5 oder 6 Bit sein
• op-Kodierung von lw ist 35 (dezimal) bzw. 100011 (binär)
• op-Kodierung von sw ist 43 (dezimal) bzw. 101011 (binär)
2.5.2 MIPS-Befehlsformat „I“ (Immediate)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 28
Beispiel
A[300] = h + A[300]
C-Programmtext MIPS-Assembler
lw $t0, 1200($t1)add $t0, $s2, $t0sw $t0, 1200($t1)Maschinencode dezimal
Maschinencode binär
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 29
adressop
6 Bit 26 Bit
• op: „opcode“; Grundtyp des Befehls (instruction)• adress: Zieladresse
2.5.3 MIPS-Befehlsformat „J“ (Jump)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 30
Speicher
2.6 Konzept der universellen Interpretierbarkeit
Hintergrund: • Programme sind gespeicherte Daten• Befehle sind Bitfolgen bzw. BinärzahlenKonsequenz:• Programme werden im Speicher als Maschinencode abgelegt und sie
werden gelesen und geschrieben wie Daten
Speicher für Daten, Programme, Compiler, Editoren, etc.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 31
Uniforme Verwaltung (Programme, Daten)keine speziellen Verwaltungsoperationen für Befehls-und Datenspeicher notwendig
Bem:• Es gibt spezielle Architekturen, die explizit zwischenBefehls- und Datenspeicher unterscheiden
• welche Vorteile hätte das ggf. doch?
Uniformität• Speicher ist als uniformer Bit-Container realisiert• vereinheitlichte, einfache Abläufe, z.B. Grundzyklus der CPU
2.6.1 Uniforme Verwaltung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 32
2.6.1 Uniforme Verwaltung
Grundzyklus der CPU
Fetch and Execute
• Befehle werden aus dem Speicher geladen (fetch) und in ein spezielles Register abgelegt
• Die Bits in diesem Register „steuern“ die nachfolgenden Aktionen(vgl. Kontrollpfad der CPU wie in Technischer Informatik behandelt)
• Befehl wird ausgeführt (execute)
• Holen des „nächsten“ Befehls etc.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 33
2.6.2 Mögliche Probleme
Mögliche Probleme durch universelle Interpretierbarkeit
kein Schutz der Daten und Programme Daten können als Befehle interpretiert werden, auch wenn das so
eigentlich nicht vorgesehen ist Beispiel: Buffer-Overflow-Exploits
Programme können verändert werden und inkorrektes (schädliches) Verhalten aufweisen Beispiel: Schadsoftware: Viren, Trojaner
Lösungsansatz: Aufteilung des Speicherbereichs eines Programms in Daten und Code-Bereich
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 34
Code
Daten
Typisches Speicherlayout eines Programms
0
0xff…f
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 35
64-bit Adressraum
- 64-bit Adressräume erlauben es, gut 16 Millionen Terabyte Speicher zu adressieren => immenser Verwaltungsaufwand
-Lösung: Adresse auf weniger Bits reduzieren
-Beispiel (AMD64): Höchstes Bit wird entweder als 0xF..F bzw. als 0x0..0 interpretiert
Bild: Wikipedia
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 36
Bedeutung für die Assemblerprogrammierung
Konzept der Segmentierung
Trennen in Daten-, Code- (Text) und Stack-Segment Datensegment enthält die Daten Textsegment den Programmcode Stacksegment wird für Prozeduraufrufe benötigt dies ist eine übliche Aufteilung des Adressraums
eines Prozesses in heutigen Betriebssystemen
Frage: woher weiß der Assembler, welche Assemblerbefehle in welches Segment zu speichern sind? Antwort: über Direktiven: .text , .data Assembler sortiert dann automatisch
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 37
2.7 Übersetzung von Kontrollstrukturen
2.7.1 Background: In höheren Programmiersprachen gibt es programmiersprachliche Konzepte, um die sequentielle Ausführung von Befehlen zu beeinflussen
bedingte Programmausführung: u.a. if ... then ... [else ...] switch ... case ...
wiederholte Programmausführung: u.a. for ... while ... repeat … until
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 38
2.7.1 Background
Auf der Maschinenbefehlsebene gibt es keine Befehle, um Kontrollstrukturen direkt abzubilden Es stehen lediglich bedingte und unbedingte Sprungbefehle zur
Verfügung
Sprungbefehle im MIPS-Befehlssatz: beq reg1, reg2, label (branch if equal) bne reg1, reg2, label (branch if not equal) j addr (jump to address), unbedingter Sprung
Problem: Die Semantik der Kontrollstrukturen muss mit den Sprungbefehlen
effizient nachgebildet werden
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 39
2.7.2 Übersetzung einfacher Kontrollstrukturen in Assemblercode
Hier betrachtet: if-then-else, while
IF-Anweisung einer höheren Programmiersprache:if <bedingung> then <statement1> else <statement2>
Übersetzungsschritte: Variablen und Werte, die zur Auswertung der Bedingung benötigt
werden, in Register ablegen Beginn der Befehlsfolge <statement2> mit Marke <marke> versehen Sprung zu <marke>, falls Bedingung nicht erfüllt
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 40
if (i==j)f = g + h;
elsef = g - h;
C-Programmtext
MIPS-Assembler
bne $s3, $s4, ElseTesten und Verzweigen
add $s0, $s1, $s2Addition (im TRUE-Fall)
Else: sub $s0, $s1, $s2Subtraktion (im FALSE-Fall)
j ExitElse-Fall überspringen
Exit:Ausgang
Beispiel: If .. then .. else Anweisung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 41
Schleifen, z.B. while SchleifeWhile <bedingung> do <statementlist> endwhile
Übersetzungsschritte: analog zur If-Anweisung: Variablen und Werte zur Auswertung der Bedingung werden in Register geladen
markiere den ersten Befehl der Statementlist mit einer Marke, z.B. LOOP
füge als letzten Befehl der Statementliste einen bedingten Sprung zur Marke LOOP ein
Beispiel: while Schleife
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 42
Bem.: Die MIPS-Architektur verwendet ein spezielles Register, das konstant den Wert „0“ enthält. Es wird in der Assemblersprache als $zero bezeichnet.
Weitere Kontrollfluss-Steuerungen
Wie realisiert man einen Vergleich der Art if a < b ?
Neuer Befehl: slt $t0, $s1, $s2 (set on less than)Bedeutung: if $s1 < $s2 then
$t0 = 1else
$t0 = 0 Damit lässt sich if a < b goto less wie folgt übersetzen:
slt $t0, $s1, $s2bne $t0, $zero, less
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 43
Die MIPS-Architektur bis hierher
Instruktion Bedeutungadd $s1,$s2,$s3 $s1 = $s2 + $s3sub $s1,$s2,$s3 $s1 = $s2 – $s3lw $s1,100($s2) $s1 = Memory[$s2+100]sw $s1,100($s2) Memory[$s2+100] = $s1bne $s4,$s5,L nächste Instruktion ist bei L,
wenn $s4 != $s5beq $s4,$s5,L nächste Instruktion ist bei L,
wenn $s4 = $s5 slt $t0,$s1,$s2 wenn $s1 < $s2, dann $t0=1,
sonst $t0=0j Label nächste Instruktion ist bei Label
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 44
Die MIPS-Architektur bis hierher
add immediate | addi $s1,$s2,100| $s1= $s2+100 | used to add constants
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 45
Quelle: Buch von Patterson/Hennessy, Seite 131, Figure 3.9 (2. A)
addi | I | 8 | 18 | 19 | 100 | addi $s1,$s2,100
op rs rt rd shamt functop rs rt 16 Bit Adresse
op 26 Bit Adresse
R
I
J
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 46
Grundprinzipien heutiger Rechnerarchitekturen:• Instruktionen als (binäre) Zahlen repräsentiert.• Programme im Speicher abgelegt und können dort gelesen und geschrieben werden wie Zahlen.
• Dies ist das Prinzip des speicherprogrammierbaren Rechners (stored program computer)
• Daten und Programme können beliebig im Speicher angeordnet werden.
• Programme können auch als Daten interpretiert wer-den (z.B. Compiler betrachten Programme als Daten.)
Zwischenfazit
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 47
2.8.1 Darstellung von Zeichen: • eine Möglichkeit: ASCII-Format (siehe nächste Folie)
• Darstellung eines Zeichens durch einen 8Bit Code• Zugriffe auf einzelne Zeichen: Assemblerbefehle:
• Lade Byte (lb), speichere Byte (sb)• Ladeoperation: lb $t0, 0($sp) (load byte)
Lädt ein Byte aus dem Speicher und platziert es in die niederwertigen Bits eines Registers
• Speicheroperation: sb $t0, 0($a1) (save byte)niederwertiges Byte in Speicherposition speichern
2.8 Verarbeitung von Zeichen
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 48
Darstellung von Zeichen: ASCII-Tabelle
Mit acht Bit (ein Byte) lassen sich in ASCII (American Standard Code for Information Interchange) 28=256 Zeichen darstellen gemäß Konvention:
• Groß- und Kleinbuchstaben unterscheiden sich um 32= 25
• Nicht angegeben: u.a. Formatierungszeichen wie „Tab“ (9), „Carriage Return“ (13), „Backspace“ (8), „Null“ (0) (in C zur Markierung des Endes einer Zeichenkette verwendet).
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 49
Kombination von Zeichen zu Zeichenketten (strings)
•Darstellung von Zeichenketten: 3 typische Varianten • Die erste Position der Zeichenkette wird reserviert
für die Länge der Zeichenkette.• Eine zweite, zusätzliche Variable enthält die
Länge der Zeichenkette.• Die letzte Position einer Zeichenkette wird durch ein Sonderzeichen markiert. (z.B. in C verwendet)
• Beispiel: Zeichenkette „GdI3“ in C dargestellt durch5 Byte mit den ASCII-Werten: 71, 100, 73, 51, 0.
2.8.2 Zeichenketten
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 50
void strcpy (char x[], char y[]){
int i;i = 0;while ((x[i]=y[i]) != 0) /* Kopieren, Prüfen des i-ten Byte*/
i = i + 1;}
• Typische Operation auf Strings: Kopieren• Beispiel: Kopieren eines Zeichenstrings unter
Prozedur strcpy kopiert Zeichenkette y auf x
Festlegung:• Basisadresse des Feldes (array) x steht in $a0 und Adresse von y in $a1
• $s0 wird für i verwendet.
2.8.2 Zeichenketten
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 52
2.9 „Höhere Kontrollstrukturen“: Prozeduren
2.9.1 Allgemeines
• Prozeduren (Unterprogramme, Methoden) wichtigstes Strukturierungskonzept moderner Programmiersprachen
• Moderne Rechner-Architekturen bieten Hardware-Unterstützung zur effizienten Bearbeitung von Prozeduren
Konzept: Prozedurrahmen (procedure frame):• Speicherblock, in dem alles abgelegt wird, was zur Verwaltung des
Prozeduraufrufs notwendig ist.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 53
2.9.1 Allgemeines
Vorteile des Konzeptes: Einheitliche Behandlung von Prozeduraufrufen, d.h. Abstraktion von unterschiedlichen Aufrufkonzepten:
• iterative und rekursive Prozeduren• geschachtelte Prozeduren• Im Prinzip wird auch ein entfernter Prozeduraufrufe (RPC, RMI) analog
bearbeitet
Bem.: Prinzip wird auch an anderer Stelle eingesetzt:u.a. beim Prozess- und Kontextwechsel durch das BSRetten von Zuständen, Kontrollwechsel etc.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 54
Schritte zur Ausführung einer Prozedur• Parameter so bereit stellen, dass Prozedur darauf zugreifen kann:
• Argumentregister $a0, $a1, $a2, $a3• Eingangsparameter bleiben durch Prozedur unverändert
• Ablaufsteuerung (control) der Prozedur übergeben: • jal Prozeduradresse (jump and link)• Sonderbefehl für Prozedurausführung: springt zur angegebenen Adresse und speichert die Adresse der folgenden Instruktion in $ra
2.9.1 Allgemeines
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 55
Schritte zur Ausführung einer Prozedur (Forts.)
•Benötigten Speicherbereich für Prozedur bereit stellen• Prozedur ausführen• Ergebniswert so bereit stellen, dass aufrufendes Programm darauf zugreifen kann:
• Ergebniswertregister $v0,$v1• Ablaufsteuerung an Aufrufstelle zurückgeben durch Sprung zurück zum Ausgangspunkt:
• jr $ra (jr: jump register, ra: return address)
2.9.1 Allgemeines
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 56
2.9.1 Allgemeines
Nutzung des speicherprogrammierbaren Rechners:• zur Realisierung einer Prozedur wird ein Register mit Adresse der aktuell
ausgeführten Instruktion benötigt• Dieses Register nennt man traditionell program counter (PC), gemeint ist
das „instruction address register“
Problem: nach der Prozedurausführung muss bei derkorrekten Instruktion beim Aufrufer weitergearbeitetwerden: d.h. alter PC-Stand muss bewahrt werden
Lösung: Befehl jal speichert PC+4 in Register $ra.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 57
2.9.2 Übersetzung von Prozeduren in Assembler
Einfache Parameterübergabe über Register:• Die Register $a0-$a3 dienen zur Übergabe der ersten vier Parameter• $v0-$v1 dienen zur Speicherung der Return-Werte• $ra enthält die Rücksprungadresse zum Aufrufer
Probleme: • Was ist bei mehr als 4 Parametern?• Zur Bearbeitung der Prozedur werden auch Register benötigt, die
enthalten ggf, noch Werte des Aufrufers: was soll damit geschehen? Retten? Überschreiben?
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 58
Antworten:• gespeicherte Registerwerte des Aufrufers (Zustand) werden in Form
einer Keller-Datenstruktur (stack) im Speicher verwaltet (LIFO-Prinzip)• Bem.: Stack-Verwaltung muss explizit in Assembler programmiert
werden
Ein Keller enthält:• Argumentwerte, bei mehr als 4 Parametern • die vor dem Prozeduraufruf gültigen Inhalte derjenigen Register, die von
der Prozedur verwendet werden.
2.9.2 Übersetzung von Prozeduren in Assembler
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 59
Kellerverwaltung:
Ein Register weist auf das letzte Element imKellerspeicher ($sp: stack pointer)
Der Keller ist am „oberen Ende“ des Speichers angeordnet und wächst in Richtung kleinerer Speicheradressen (von oben nach unten) Push: erniedrigt den Stack-Pointer Pop: erhöht ihn
Synonyme Begriffe: Keller, Stapel, stack
2.9.2 Übersetzung von Prozeduren in Assembler
$sp
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 60
Notwendig für Verwaltung:
• Kellerpegel (engl. stack pointer) $sp muss vom Assemblerprogrammierer manuell verwaltet werden
• Anpassung des Kellerpegels in 1-Wort-Schritten für Speicherung oder Zurückspeicherung eines Registerwerts
2.9.2 Übersetzung von Prozeduren in Assembler
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 61
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
C-Programmtext
Phase 1: Registerinhalte auf den Stack retten
Phase 2: Berechnungen durchführen
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
$sp (vor Phase 1)
hohe Adresse
niedrige Adresse
Keller (stack)
MIPS-Assemblerfirst_proc:
Phase 5: Rücksprung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 62
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
Phase 2: Berechnungen durchführen
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
Phase 5: Rücksprung
$sp (vor Phase 1)
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)
Phase 1: Registerinhalte auf den Stack retten
sub ist ein Pseudobefehl, der mit Registern bzw. kleinen
Konstanten arbeiten kann (siehe MIPS-R2000 Befehlssatz).
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 63
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
Phase 2: Berechnungen durchführen
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0$sp (nach Phase 1)
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)
Phase 1: Registerinhalte auf den Stack retten
$sp (vor Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 64
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
Phase 2: Berechnungen durchführen
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)
Phase 1: Registerinhalte auf den Stack retten
$sp (vor Phase 1)
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 65
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
Phase 1:
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)
Phase 2: Berechnungen durchführen
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 66
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
Phase 1:
Phase 3: Resultatwert speichernPhase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1
Phase 2: Berechnungen durchführen
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 67
Phase 1:
Phase 2:
Phase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1
Phase 3: Resultatwert speichern
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 68
Phase 1:
Phase 2:
Phase 4: Register zurückspeichern
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1[move $v0, $s0]
Phase 3: Resultatwert speichern
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 69
Phase 1:
Phase 2:
Phase 3:
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1[move $v0, $s0]
Phase 4: Register zurückspeichern
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 70
Phase 1:
Phase 2:
Phase 3:
Phase 5: Rücksprung
$t1
$t0
$s0
hohe Adresse
niedrige Adresse
Keller (stack)
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1[move $v0, $s0]lw $s0, 0($sp)lw $t0, 4($sp)lw $t1, 8($sp)[add $sp, $sp, 12]
Phase 4: Register zurückspeichern
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
$sp (nach Phase 4)
$sp (nach Phase 1)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 71
hohe Adresse
niedrige Adresse
Keller (stack)
Phase 1:
Phase 2:
Phase 3:
add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1
Phase 4:
Phase 5: Rücksprung
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)
[move $v0, $s0]lw $s0, 0($sp)lw $t0, 4($sp)lw $t1, 8($sp)[add $sp, $sp, 12]
$sp (nach Phase 4)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 72
$sp (nach Phase 4)
hohe Adresse
niedrige Adresse
Keller (stack)
jr $ra
Phase 1:
Phase 2:
Phase 3:Phase 4:
Phase 5: Rücksprung
Einfaches Beispiel für Prozedur
int first_proc (int g, int h, int i, int j){ int f;
f = (g + h) – (i + j);return f;
}
[sub $sp, $sp, 12]sw $t1, 8($sp)sw $t0, 4($sp)sw $s0, 0($sp)add $t0, $a0, $a1add $t1, $a2, $a3sub $s0, $t0, $t1
lw $s0, 0($sp)lw $t0, 4($sp)lw $t1, 8($sp)[add $sp, $sp, 12]
[move $v0, $s0]
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 73
Anmerkungen zum Beispiel:• Annahme war: die Werte der verwendeten Register
$t0, $t1, $s0 werden gesichert und müssen nach Beendigung der Prozedur zurück gespeichert werden.
• Zur Vermeidung von Speicheroperationen für Register, deren Werte nicht verwendet: zwei Klassen von Registern:
• $t0 - $t9: 10 Register für temporäre Variablen, deren Inhalte von der aufgerufenen Prozedur verändert werden können und nicht gesichert werden müssen.
• $s0 - $s7: 8 Register für langlebige Variablen, die von auf-gerufenen Prozeduren nicht verändert werden dürfen.
D.h. Inhalte müssen nach Aufruf und Abarbeitung einer Prozedur gesichert bzw. wiederhergestellt sein.
Einfaches Beispiel für Prozedur
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 74
Beispiel zur Motivation der Problematik
• Hauptprogramm (main) ruft Prozedur A auf: Effekt: main belegt Argumentregister $a0 und
Rücksprungregister $ra• Prozedur A ruft Prozedur B auf:
Effekt: A belegt Argumentregister $a0 und Rücksprungadresse $ra.
Probleme: Konflikte in $a0 und Register $ra !• Rücksprungadresse in das Hauptprogramm
main geht verloren!
2.9.3 Geschachtelte Prozeduren (nested)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 75
Schwierigkeiten:• Alle Prozeduren verwenden dieselben Register für ihre Argumente ($a0 - $a3).
• Alle Prozeduren verwenden ein einziges (dasselbe) Rücksprungregister ($ra).
• Alle Prozeduren verwenden die Register ($s0 - $s7).
Eine mögliche Lösung:• Die aufrufende Prozedur (caller) sichert die jeweils benötigten der Argumentregister ($a0 - $a3) und temporären Register ($t0 - $t9) auf den Stack(„push“-Operation).
2.9.3 Geschachtelte Prozeduren (nested)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 76
Eine mögliche Lösung: (Forts.)• Die aufgerufene Prozedur (callee) sichert aufdem Stack die Rücksprungregister ($ra) und die von ihr zu verwendenden langlebigen Register ($s0 - $s7)
• Der Kellerpegel (stack pointer) $sp wird angepasst gemäß der Anzahl der gespeicherten Register
• Beim Rücksprung aus der aufgerufenen Prozedur werden alle gesicherten Register zurück geladen(„pop“-Operation) und der Kellerpegel zurück gesetzt.
Bem.: Rekursive Prozeduraufrufe sind ein Spezialfall von geschachtelten Aufrufen, analoge Behandlung
2.9.3 Geschachtelte Prozeduren (nested)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 77
int fact (int n){
if (n < 1) return (1);else return (n * fact(n-1));
}
Beispiel: Rekursiver Prozeduraufruf
C-Programmtext: Berechnung der Fakultät n!
Zwischenüberlegung: Umformung in Cint fact (int n){ int t0;
if (n < 1) t0 = 1;else t0 = 0;
if (t0 == 0) goto L1;return (1);
L1: return (n * fact(n-1));}
2.9.3 Geschachtelte Prozeduren (nested)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 78
fact:[sub $sp,$sp,8] # Anpassung des Kellerpegels um 2 Wortesw $ra, 4($sp) # Speicherung der Rücksprungadressesw $a0, 0($sp) # Speicherung des Arguments n
[slt $t0,$a0,1] # Test auf n < 1beq $t0,$zero,L1 # falls n >=1, gehe zu L1
[add $v0,$zero,1] # Ergebnis ist 1# Zurückspeichern von $a0, $ra unnötig bei n<1
[add $sp,$sp,8] # Entfernen („pop“) zweier Worte vom Stapeljr $ra # Rücksprung hinter jal
L1: [sub $a0,$a0,1] # falls n>=1: ersetze Argument n durch n-1jal fact # Aufruf von fact mit (n-1)
lw $a0, 0($sp) # Rückkehr von jal; Rückspeicherung Argument nlw $ra, 4($sp) # Rückspeicherung der Rücksprungadresse
[add $sp,$sp,8] # Entfernen zweier Worte vom Kellerpegel
mul $v0,$a0,$v0 # Ergebnis ist n * fact(n-1); Multiplikation s.Kap.4
jr $ra # Rücksprung zum aufrufenden Programm
Beispiel (Forts.): MIPS-Assembler (mit Verwendung direkter Addition/Subtration von Konstanten)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 79
langlebig (bzw. zu erhalten)
temporär(bzw. nicht zu erhalten)
langlebige Register: $s0 - $s7 temporäre Register: $t0 - $t9
Kellerpegelregister: $sp Argumentregister: $a0 - $a3
Rücksprungadressregister: $ra Ergebniswertregister: $v0
Keller (stack) oberhalb des Kellerpegels (stack pointer)
Keller (stack) unterhalb des Kellerpegels (stack pointer)
Langlebige und temporäre Registerwerte
Inhalte der Register nach Aufruf einer Prozedur:
Die Inhalte von Rahmenzeigerregister (frame pointer register) $fp und Globalem-Zeiger-Register (global pointer register) $gp sind gegebenenfalls auch zu erhalten.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 80
• Speicherung aller lokalen Variablen und Datenstrukturen einer Prozedur, die nicht in die verfügbaren Register passen, auf dem Stack
• Das Kellersegment (stack segment) mit den Daten eines Prozeduraufrufs heißt Prozedurrahmen (procedure frame, activation record).
• Rahmenzeiger (frame pointer) $fp zeigt auf Anfang des Prozedurrahmens.
• Über $fp sind lokale Prozedurdaten unabhängig vom aktuellen Kellerpegel ($sp) adressierbar
2.9.4 Speicherverwaltung: Prozedurrahmen
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 81
• Rahmenzeiger $fp zeigt auf erstes Wort des Rahmens; er verändert sich während Prozedurausführung nicht.
• Kellerpegel $sp zeigt auf Anfang des Stacks; er kann sich während Prozedurausführung verändern.
Verwaltung der Prozedurrahmen
vor Prozeduraufruf
während Prozedurausführung
nach Prozeduraufruf
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 82
Frage: Welche Informationen schreibt Aufrufender (caller) welche Aufgerufener (callee) in den Rahmen ?Antwort: allgemeine Konvention
Aufgabenverteilung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 83
Prolog des Aufrufers
• Sichern aller Register, die der Aufrufer auch nach dem Aufruf benötigt.• MARS: Register: $a0 - $a3, $t0 - $t9, $v0,$v1
• Übergabe der Eingabeparameter beim MARS:• Die ersten 4 Argumente in den Registern $a0, ..., $a3• Die restlichen in umgekehrter Reihenfolge auf den Keller
• Bei „Call-by-Value“-Parametern: Laden des Wertes• Bei „Call-by-Reference“-Parametern: • Laden der Adresse (mit la-Befehl)
Prolog des Aufrufers (caller)(vor Prozeduraufruf)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 84
Beispiel für Prolog-Schema für Caller
main: <...> # Berechnungen im Hauptprogramm# --- Prolog des Aufrufers: ---
[sub $sp,$sp,8] # Platz auf Stack reservieren (2 Worte f. 2 Regist.)sw $t0, 4($sp) # Speicherung des noch benötigten Inhalts vonsw $t1, 0($sp) # $t-Registern (hier: $t0, $t1) vom Aufrufer selbst
[move $a0, $t5] # Argumente übergeben (hier nur eines)
Aufruf der Prozedur mit jal-Befehl, • d.h. Start der Prozedur durch Sprung zu deren erstem Befehl.
• Wichtig: jal sichert automatisch die Rücksprung-adresse des Aufrufers im Register $ra.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 85
Epilog des Aufrufers
• Wiederherstellen der gesicherten Register• Wiederherstellen des ursprünglichen Kellerpegels
(stack pointer) (durch „Pop“ der Einträge):$sp := $sp + (|Argumente| + |gesicherte Register|) × 4
Epilog des Aufrufers (caller)(nach Rückkehr vom Prozeduraufruf)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 86
main: <...> # irgendwelche Berechnungen im Hauptprogramm# --- Prolog des Aufrufers: ---
[sub $sp,$sp,8] # Platz auf Stack reservieren (2 Worte f. 2 Regist.)sw $t0, 4($sp) # Speicherung des noch benötigten Inhalts vonsw $t1, 0($sp) # $t-Registern (hier: $t0, $t1) vom Aufrufer selbst
[move $a0, $t5] # Argumente übergeben (hier nur 1)
jal proc # --- Aufruf der Prozedur ---
# --- Epilog des Aufrufers: ---lw $t1, 0($sp) # Registerinhalte wiederherstellenlw $t0, 4($sp) #[add $sp,$sp,8] # Kellerpegel zurücksetzen
# Aufruf der Prozedur ist beendet
Beispiel für Prolog/Epilog-Schema
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 87
Prolog des Aufgerufenen
Prolog des Aufgerufenen (callee)(vor Ausführung der Prozeduranweisungen)
• Speicherplatz reservieren: Versetzen des Kellerpegels:$sp := $sp – (|zu sichernde Register| + |lokale Variablen|) × 4
• Sichern aller Register, die von der Prozedur verändert werden; MARS:
• zuerst $fp sichern, • restliche Register in beliebiger Reihenfolge,• $ra sichern, falls weiterer Prozeduraufruf erfolgt!
• Rahmenzeiger $fp setzen: Element nach Eingabepar.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 88
Beispiel für Prolog-Schema (Callee)
proc: # Einsprungadresse der Prozedur# --- Prolog des Aufgerufenen: ---
[sub $sp,$sp,20] # Platz auf Stack reservieren (hier: 5 Worte)# hier: 5 Register sichern
sw $fp, 16($sp)# “alten“ Rahmenzeiger sichernsw $ra, 12($sp)# Rücksprungadresse sichernsw $s0, 8($sp)# die benötigten $s-Register müssen von dersw $s1, 4($sp)# aufgerufenen Prozedur gesichert werdensw $s2, 0($sp)#[add $fp, $sp,20]# Rahmenzeiger erstellen<...> # Prozedurkörper mit eigentlichen Befehlen
# --- Epilog des Aufgerufenen: ---
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 89
Epilog des Aufgerufenen
Epilog des Aufgerufenen (callee)(nach Ausführung des Prozedurkörpers)
• Rückgabe des Funktionswertes• MARS: in den Registern $v0 bzw. $v1
• Wiederherstellen der gesicherten Registerinhalte • z.B. Rahmenzeiger $fp, Rücksprungadresse $ra
• „Pop“ der für die Prozedur angelegten Werte durch Zurücksetzen des Kellerpegels (stack pointer) $sp
• $sp := $sp + (|gesicherte Register| + |lokale Variablen|) × 4• Rücksprung zum Aufrufer: im MARS durch: jr $ra
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 90
Beispiel für Prolog/Epilog-Schema (Forts.)
proc: # Einsprungadresse der Prozedur# --- Prolog des Aufgerufenen: ---
[sub $sp,$sp, 20] # Platz auf Stack reservieren (hier: 5 Worte)# hier: 5 Register sichern
sw $fp, 16($sp) # “alten“ Rahmenzeiger sichernsw $ra, 12($sp) # Rücksprungadresse sichernsw $s0, 8($sp) # die benötigten $s-Register müssen von dersw $s1, 4($sp) # aufgerufenen Prozedur gesichert werdensw $s2, 0($sp) #[add $fp, $sp,20] # Rahmenzeiger erstellen<...> # Prozedurkörper mit eigentlichen Befehlen
# --- Epilog des Aufgerufenen: ---lw $s2, 0($sp) # $s-Registerinhalte wiederherstellenlw $s1, 4($sp) #lw $s0, 8($sp) #lw $ra, 12($sp) # Rücksprungadresse wiederherstellenlw $fp, 16($sp) # Rahmenzeiger wiederherstellen
[add $sp, $sp,20] # Kellerpegel zurücksetzen (pop)jr $ra # Rücksprung zum Aufrufenden
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 91
Pseudobefehle
In den bisherigen Beispielen wurden unter anderem Pseuobefehle verwendet. Diese waren durch Klammern („[…]“) markiert. Pseudobefehle sind Befehle, die es nicht im Maschinenbefehlssatz gibt. Einige Assembler unterstützen bestimmte Pseudobefehle, um die
Programmierung zu erleichtern. Beispiel: move $t0, $t1 (Kopiere Inhalt eines Registers ($t1) in ein
anderes ($t0)) Einen solchen Befehl gibt es nicht!Mögliche Realisierung: add $t0, $t1, $zero (Addiere Null auf $t1 und
schreibe das Ergebnis in $t0)Weiteres Beispiel: Arithmetik mit Konstanten (siehe folgende Folien)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 92
MIPS-Befehlsformat „R“: • Operanden sind immer Register• Beispiele: add und sub
Schwächen der bisherigen Instruktionen:• Die Verwendung von Konstanten ist unhandlich:
• über ein spezielles Register ($zero) oder• Ablage der Konstante im Speicher an bekannter Stelle, bzw. erst Laden in ein Register
2.10 Adressierung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 93
2.10 Adressierung
• Konstanten (z.B. für Inkrement/Dekrement-Operatio-nen bei Datenzugriffen in Schleifen) treten häufig auf,z.B. C Compiler gcc: > 52% aller arithmetischen
Befehle nutzen Konstanten Effizienter Zugriff speziell auf kleine Konstanten ist
wünschenswert !
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 94
2.10.1 Konstanten als unmittelbare Operanden
Lösung: I- Befehlsformat (immediate): • Konstanten als unmittelbare Operanden
immediatertrsop
6 Bit 5 Bit 5 Bit 16 Bit
Beispiel: addi $sp, $sp, 4 # $sp = $sp + 4
429298Dezimal-darstellung
Binär-darstellung
0000 0000 0000 01001110111101001000
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 95
Frage: Was tun, wenn Konstante größer als 216-1 = 65535 ist,und mehr als 16 Bit zur Darstellung benötigt ?
Weiteres Beispiel
MIPS: slt $t0, $s1, $s2 # falls $s1 < $s2: $t0=1, sonst $t0=0
unmittelbare Adressierung in MIPS:slti $t0, $s1, 10 # falls $s1 < 10: $t0=1, sonst $t0=0
1081710Dezimal-darstellung
Binär-darstellung
0000 0000 0000 10100100010001001010
Vorteil der direkten Adressierung: Die Verwendung häufig vorkommender, kleiner Konstanten wird effizient (schnell) ausgeführt !
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 96
Behandlung großer Konstanten
maximal 32 Bits große Konstanten (d.h. 232-1 = 4,29... ×109) Der Befehl lui (load upper half word immediate) lädt angegebene
Konstante in die höherwertigen 16 Bits des Zielregisters. Beispiel: lui $t0, 255
Binär-darstellung
0000 0000 1111 11110100000000001111
Setzen der niederwertigen 16 Bits von $t0 z.B. mitaddi $t0, $t0, 2304
0000 1001 0000 00000000 0000 1111 1111Inhalt von $t0
0000 0000 0000 00000000 0000 1111 1111Inhalt von $t0
Laden einer Zahl mit lui in höherwertige 16 Bits entspricht Multiplikation mit 216 !
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 97
2.10.2 Adressierung von Sprungzielen
Einfachste Sprungzieladressierung in MIPS im J-Format:j 10000 # go to Position 10000
10000 (eigentlich: 2500)2Dezimal-darstellung
6 Bit 26 Bit (für Sprungadresse)
Bedingte Verzweigung mit bne oder beq benötigt neben der Sprungadresse zwei Operanden:Beispiel: bne $s0,$s1,Exit # go to Exit, if $s0 != $s1
Exit17165
6 Bit 5 Bit 5 Bit 16 Bit (für Sprungadresse)
Dezimal-darstellung
Problem: Wie kann man größere Adressen als 216-1 realisieren? Beobachtung: Verzweigungen in Schleifen und Fallunterscheidungen haben
Sprungadressen „in der Nähe“ der aktuellen Instruktion Idee: Verwende relative Adressierung zum Instruktionsadress-Register PC
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 98
Beispiel: Erneut: While-Schleife while (save[i] == k)i = i + j;
MIPS:Loop: add $t1, $s3, $s3 # $t1=2×i
add $t1, $t1, $t1 # $t1=4×iadd $t1, $t1, $s6 # $t1=Adresse[save(i)]lw $t0, 0($t1) # $t0=save[i]bne $t0, $s5, Exit # falls save[i] != k, go to Exitadd $s3, $s3, $s4 # i = i + j j Loop # go to Loop
Exit:
80000
Darstellung in Maschinencode (symbolisch):
320919190
3209990
32092290
08935
82185
3201920190
800002
80000
80004
80008
80012
80016
80020
80024
80028 ...
PC=PC+8 (Byte)(oderPC+2 (words))
Achtung: PC wird jeweils vor eigentlicher Befehlsausführung um 4 erhöht.
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 99
Verzweigungen mit Zielen, die weiter entfernt sind
• Verzweigungsbefehle können Verzweigungen um ± 216-1 Speicherworte realisieren.
• Für weit entfernte Verzweigungen wird vom Assembler eine indirekte Verzweigungsmethode implementiert:• invertierter Verzweigungsbefehl• unbedingter Sprung zum Sprungziel (26 statt 16 Bit Adresse)
Beispiel: beq $s0, $s1, L1 wird ersetzt durch
bne $s0, $s1, L2 # j L1 # unbedingter Sprung, ‚weite Entfernung‘
L2:
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 100
1. Unmittelbare Adressierung: Operand ist Konstante im Befehl selbst.
2. Registeradressierung: Operand ist Register
3. Basisadressierung: Operandenadresse ist Summe von Registerinhalt und Konstante im Befehl
Zusammenfassung der Adressierungsmodi
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 101
4. PC-relative Adressierung: Operandenadresse ist Summe von PC und Konstante im Befehl
5. Pseudodirekte Adressierung: Sprungadresse setzt sich aus 26 Bits im Befehl und (!) den oberen 4 Bits im PC zusammen
Zusammenfassung der Adressierungsmodi
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 102
Zusammenfassung: MIPS-Operanden
• einfache Befehle mit je 32 Bits• sehr strukturiert, kein überflüssiges „Gepäck“• nur drei Befehlsformate
Aufgabe des Compilers ist es, Leistung zu erbringen: • Als Programmierer dem Compiler wo immer möglich helfen!
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 103
Bisherige MIPS-Instruktionen
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 104
Design Alternative: CISC
• Bereitstellung leistungsfähigerer Operationenmit Ziel der Reduktion der auszuführenden Befehle
• Gefahr ist eine langsamere Taktzeit und/oder eine höhere, durchschnittliche Anzahl von Takten per Instruktion
• RISC (reduced instruction set computer) versus • CISC (complex instruction set computer):• fast alle neuen Instruktionssätze seit 1982 waren RISCz.B. MIPS, Sun SPARC, Hewlett-Packard PA-RISC, IBM/Motorola PowerPC, DEC Alpha
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 105
Assemblerprogramm
2.11 Fazit: Vom C-Programm zur Ausführung
C-Programm
Objektcode:Maschinensprachmodul
Executable:Maschinenprogramm
Speicher
Compiler
Assembler
Binder(Linker)
Lader (Loader)
Objektcode:Bibliotheksroutinen
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 106
2.11 Fazit: Assemblerprogrammierung
• über Adressierung: Zugriff auf beliebige Objekte im Speicher: flexibel, hoch performant
• Aber: kein Schutz durch Typisierung, z.B. Integer-Wert kann beliebig als Adresse interpretiert werden
• Assemblerprogramme sind maschinenabhängig, d.h. nicht portierbar
• Assemblersprache:• viel einfacher als mit Binärzahlen umzugehen• niedriges Niveau der Konzepte, darum Programm-entwicklung schwierig (bzw. herausfordernd!)
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 107
• Programmtext in Assembler wird schnell sehr lang und unübersichtlich und damit fehleranfällig
• nur wenige Konzepte für Kontrollstrukturen, Programmsteuerungsfluss: schwer wartbarbar
• kein „Information Hiding“: z.B. bei geschachtelten Prozeduren über Rahmenzeiger-Kette beliebiger Zugriff auf Daten der vorherigen Prozeduraufrufe!
Einsatzbereiche für Assemblerprogrammierung:• Bereiche die sehr effizienten Code benötigen, wie
• Eingebettete Systeme, Controller, • elektronische Steuerungen: Auto, Flugzeug, …
2.11 Fazit: Assemblerprogrammierung
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 108
2.11 Fazit: Eingebettete Systeme: Die Spitze des Eisbergs
• In Vorlesung betrachtet: Hochleistungsprozessoren für allgemeine Computeranwendungen.
• Aber: Die meisten Anwendungen der digitalen Datenverarbeitung findet man in Geräte des täglichen Lebens (embedded)• Markt für eingebettete (Computer-)Systeme wächst sehr stark
• Deutschland hat eine führende Position bei der Entwicklung eingebetteter Systeme!
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 109
2.11 Fazit: Prozessorklassen
General Purpose Prozessoren – Hohe Leistung• Pentiums, Alphas, SPARC, …• nützlich für allgemeine Software• komplexe Betriebssysteme – Unix, Win XP• Workstations, PCs
Eingebettete Prozessoren und Prozessorkerne• ARM, 486SX, Hitachi SH7000, …• nur ein Programm• einfache, oft Realzeit-Betriebssysteme• Mobiltelefone, Consumerelektronik
Microcontroller• extrem Kosten sensitiv• geringe Wortbreite – 8-bit üblich• bei weitem die höchsten Stückzahlen• Automobil, Fahrstühle, Rolläden, Klimaanlage, Toaster, ..
Zune
hmen
de K
oste
n
Zune
hmen
deSt
ückz
ahl
Fachbereich Informatik | Prof. Dr. Frederik Armknecht | 110
2.11 Fazit: Der Prozessor-Design-Raum
Kosten
Leis
tung
Microcontroller
EingebetteteProzessoren
Mikroprozessoren
Kosten sind alles!
Anwendungsspezifi-sche Architekturen für hohe Leistung
Leistung ist alles & Software regiert