• Keine Ergebnisse gefunden

GanzzahligFloating Point ‐

N/A
N/A
Protected

Academic year: 2022

Aktie "GanzzahligFloating Point ‐"

Copied!
33
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Zusammenfassung der Sprung‐Instruktionen

Instruktion Beispiel Bedeutung des Beispiels

Ganzz ahlig

beq, bne beq $s1, $s2, x Springe nach x wenn $s1 = 

$s2

j j label Springe immer nach 

„label“

jr jr $s1 Springe nach in $s1 

gespeicherte Adresse slt, slti, sltu, sltiu slt $s1,$s2,$s3 $s1=1 wenn $s2<$s3 

(signed)

Floa ting ‐ Po in t bc1t, bc1f bc1t label Springe nach „label“ wenn  letzter Floating‐Point‐

Vergleich true ergab c.x.s (x=eq, lt, le), 

c.x.d (x=eq, lt, le)

c.eq.s $f1, $f2 Teste auf $f1=$f2 (single

precision)

(2)

Quiz

Im folgenden Codeabschnitt soll nach continue gesprungen werden,  wenn $s1 kleiner gleich $s2 ist:

loop: ...

j loop continue: ...

Tipp: wir brauchen

beq, slt und bne

(3)

Und noch ein Quiz

Annahme:

$s1 = 0xFFFFFFFF

$s2 = 0x00000001

In welchem der beiden Code‐Abschnitte wird gesprungen?

...

slt $t0,$s1,$s2

bne $t0,$zero, lab ...

...

lab: ...

...

...

sltu $t0,$s1,$s2 beq $t0,$zero, lab ...

...

lab: ...

Sprung: ...

ja nein

Sprung:

ja nein

(4)

Prozeduren

(5)

Das Prinzip von Prozeduren

Hauptprogramm:

. . .

x = 2*fakultät(10) .

. . Programm‐

abarbeitung

Prozedur mit dem  Namen fakultät

. .

Berechne n!

. . Prozeduraufruf

mit Parameter n=10

Prozedurrücksprung mit Ergebnis n!

Randbemerkung: was ist n! ?

(6)

Programmzähler und Rücksprungadresse

0x0040000 : 0011 ... 1001 0x0040004 : 0001 ... 1000 0x0040008 : 1001 ... 1111 0x004000c : 1011 ... 0001 0x0040010 : 0011 ... 1000 0x0040014 : 1001 ... 1111 0x0040018 : 0001 ... 0001 0x004001c : 1011 ... 0011 0x0040020 : 1011 ... 1100 0x0040024 : 0101 ... 1001 0x0040028 : 1000 ... 0011 0x004002c : 1000 ... 1011 0x0040030 : 0001 ... 1100 0x0040034 : 1001 ... 1111 0x0040038 : 1001 ... 1111

Startadresse des Hauptprogramms Aufruf der Prozedur

Register $pc

Prozedur Fakultät

Rücksprung aus der Prozedur

Adresse Maschineninstruktion

Register $ra

(7)

Assembler‐Beispiel

Hauptprogramm: ...

0x004000c addi $a0,$zero,10 # setze $a0 auf 10 0x0040010 jal Fakultaet # rufe Prozedur auf 0x0040014 sll $v0,2 # Berechne Rückgabe*2

...

Fakultaet:

# Die Prozedur Fakultaet

# erwartet den Übergabeparameter in $a0

# gibt das Ergebnis in $v0 zurück

0x0040024 ... # Berechnung der Fakultät ... # Das Ergebnis sei in $a0 0x004002c add $v0,$a0,$zero # speichere Ergebnis in $v0 0x0040030 jr $ra

Register $pc Register $ra Register $a0 Register $v0

(8)

Problem

Hauptprogramm:

. .

$s0 = 42 vor Aufruf

. .

x = 2*fakultät(10) .

.

Annahme immer  noch $s0=42 !?!

. . Programm‐

abarbeitung

Prozedur mit dem  Namen fakultät

. .

Berechne n!

Überschreibe dabei 

$s0 mit 114 .

. Prozeduraufruf

mit Parameter n=10

Prozedurrücksprung mit Ergebnis n!

Register $s0

(9)

Lösung

Hauptprogramm:

. .

$s0 = 42 vor Aufruf

.

x = 2*fakultät(10) .

.

Es gilt immer  noch $s0=42 !!!

. .

Prozedur mit dem  Namen fakultät

Rette Inhalt von $s0  auf dem Stack

.

Berechne n!

($s0 wird dabei  überschrieben) Restauriere Inhalt  von $s0 mittels Stack

. Register $s0 .

0x7fffffff : ...

0x7ffffffe : ...

0x7ffffffd : ...

0x7ffffffc : ...

0x7ffffffb : ...

0x7ffffffa : ...

0x7ffffff9 : ...

0x7ffffff8 : ...

0x7ffffff7 : ...

0x7ffffff6 : ...

0x7ffffff5 : ...

0x7ffffff4 : ...

0x7ffffff3 : 0x7ffffff2 : 0x7ffffff1 : 0x7ffffff0 : 0x7fffffef : 0x7fffffee : 0x7fffffec :

.

Register $sp

Stack

(10)

Assembler‐Beispiel

Fakultaet: addi $sp, $sp, -4 # erhöhe Stack-Pointer um ein Word sw $s0, 0($sp) # rette $s0 auf Stack

# berechne Fakultät

# $s0 wird dabei überschrieben

lw $s0, 0($sp) # restauriere $s0 vom Stack addi $sp, $sp, 4 # dekrementiere Stack-Pointer jr $ra # Springe zurück zum Aufrufer

...

0x7ffffff7 : ...

0x7ffffff6 : ...

0x7ffffff5 : ...

0x7ffffff4 : ...

0x7ffffff3 : 0x7ffffff2 : 0x7ffffff1 : 0x7ffffff0 : 0x7fffffef : 0x7fffffee : 0x7fffffec :

...

Register $s0 Register $sp

(sei $s0=0xffef2314 vor Aufruf von Fakultaet)

(11)

Registerkonvention

Name Nummer Verwendung Wird über Aufrufgrenzen bewahrt?

$zero 0 Konstante 0 n.a.

$at 1 nein

$v0‐$v1 2‐3 Prozedur‐Rückgabe nein

$a0‐$a3 4‐7 Prozedur‐Parameter nein

$t0‐$t7 8‐15 Temporäre nein

$s0‐$s7 16‐23 Temporär gesicherte ja

$t8‐$t9 24‐25 Temporäre nein

$k0‐$k1 26‐27 nein

$gp 28 ja

$sp 29 Stack‐Pointer ja

$fp 30 ja

$ra 31 Return‐Adresse ja

(12)

Rekursive Prozeduren

Hauptprogramm:

. . .

x = 2*fakultät(10) .

. .

Prozedur mit dem  Namen fakultät

. .

Berechne n!

. . Prozeduraufruf

Letzter Rücksprung mit Gesamtergebnis

Wenn Rekursionsende noch nicht erreicht, dann erneuter Prozeduraufruf

(„mit kleinerem Parameter“)

Alle vorigen Rücksprünge

(13)

Verwendung des Stacks

Haupt‐

programm

Fakultät

Fakultät

Fakultät

Rekursionsende Stack

$sp

Fakultät

(14)

Assembler‐Beispiel

Auf der nächste Folie wollen wir die Fakultät n! nach folgendem  Algorithmus berechnen

int fact (int n) { if (n < 1) {

return 1;

}

else {

return n * fact(n-1);

}

}

(15)

Assembler‐Beispiel

# Berechnung der Fakultät von n (also n!)

# Eingabeparameter n ist in $a0 gespeichert

# Rückgabeparameter der Berechnung ist $v0

fact: addi $sp, $sp, -8 # push Stack-Pointer um zwei Word sw $ra, 4($sp) # rette Rücksprungadresse auf Stack sw $a0, 0($sp) # rette Eingabeparameter auf Stack slti $t0, $a0, 1 # teste n < 1

beq $t0, $zero, L1 # wenn n >= 1 dann gehe nach L1 addi $v0, $zero, 1 # es wird 1 zurückgegeben

addi $sp, $sp, 8 # pop Stack-Pointer um zwei Word jr $ra # Rücksprung zum Prozedur-Aufrufer L1: addi $a0, $a0, -1 # setze Argument auf n-1

jal fact # rufe fact rekursiv mit n-1 auf

lw $a0, 0($sp) # restauriere Eingabeparam vom Stack lw $ra, 4($sp) # restauriere Rücksprungadr vom Stack addi $sp, $sp, 8 # pop Stack-Pointer um zwei Word

(16)

Procedure‐Frame und Frame‐Pointer

Null bis vier Argument‐

Register ($a0‐$a3) Return‐Adresse $ra Null bis acht Saved‐

Register ($s0‐$s7) Möglicher zusätzlicher 

Speicher der während  der Ausführung der 

Prozedur  benötigt  wird und nach  Prozedurrückkehr nicht 

mehr

Hohe Adresse

Niedrige Adresse Stack‐Pointer $sp

Frame‐Pointer $fp

Unbenutzer Stack‐Speicher

Benutzer Stack‐Speicher

Procedure‐Frame

Argument 5 Argument 6

(17)

Speicherbelegungskonvention

Reserviert

Text (d.h. das Programm  in Form von Maschinen‐

instruktionen) Statische Daten (z.B. 

Konstanten oder  statische Variablen)

Stack

Der Heap speichert alle  dynamischen (d.h. 

während der Laufzeit  angelegten) Daten.

Heap

0x00400000 0x10000000 0x10008000 0x7ffffffc

0x00000000

$pc

$sp

$gp

(18)

Die Sprunginstruktionen zusammengefasst

Instruktion Beispiel Beduetung

j j Label $pc = Sprungadresse

jal jal Label $ra = $pc+4, $pc = Sprungadresse jr jr $s1 $pc = Registerinhalt

$pc ist der Program‐Counter

$ra ist das 32te CPU‐Register 

(19)

Schwieriges Quiz

Rmul: addi $sp, $sp, -4 # rette Rücksprungadresse sw $ra, 0($sp) #

add $t0, $a0, $zero # $t0 = n addi $a1, $a1, -1 # m = m - 1

beq $a1, $zero, End # wenn m=0, dann Ende jal Rmul # $v0 = Rmul(n,m-1) add $t0, $t0, $v0 # $t0 = $t0 + $v0 End: add $v0, $t0, $zero # $v0 = $t0

lw $ra, 0($sp) # springe zurück addi $sp, $sp, 4 #

Rekursive Berechnung von n*m in der Form Rmul(n,m) = n+Rmul(n,m‐1) Eingabeparameter: $a0 für n und $a1 für m>0

Rückgabeparameter: $v0 Temporäre Berechnung: $t0

$a0, $a1, $v0, $t0 brauchen  nach Registerkonvention alle  nicht über Aufrufgrenzen  bewahrt zu werden.

(20)

Registerkonvention, dass ein Register über Aufrufgrenzen nicht  bewahrt wird bedeutet:

• Register darf nach belieben überschreiben werden.

• Register muss vor dem Rücksprung nicht restauriert werden.

• Prozedur muss aber das Register für sich selbst sichern!

• Beispiel:

Verwendung von $t0 Sichern von $t0

Aufruf einer anderen Prozedur Restaurieren von $t0

• Ausnahme: wir wissen genau, dass das Register in keiner der aufgerufenen Prozeduren verwendet wird.

• Prozeduren, die keine anderen aufruft muss natürlich temporäre Register nie sichern.

Prozedur, die keine andere aufruft nennt man auch Leaf‐Procedure

Bemerkung zu vorigem Quiz

(21)

32‐Bit‐Konstanten und Adressierung

(22)

Immediate kann nur 16‐Bit lang sein

Erinnerung: Laden einer Konstante in ein Register addi $t0, $zero, 200

Als Maschinen‐Instruktion:

001000 00000 01000 0000000011001000 addi $zero $t0 200

Inhalt von $t0 nach Instruktionsausführung:

00000000|00000000|00000000|11001000 Byte 3 Byte 2 Byte 1 Byte 0

Also, Byte 0 und Byte 1 von $t0 kann man so mit einem Wert initialisieren.

Was ist mit Byte 2 und 3?

(23)

Lösung: Load‐Upper‐Immediate

Aufgabe: Lade folgende 32‐Bit‐Konstante in Register $s0

0000 0000 0011 1101 0000 1001 0000 0000 Neuer Befehl: Lade 16‐Bit‐Wert in obere 16 Bits von Register $s0

lui $s0, 61 # 61 dezimal = 0000 0000 0011 1101 binär Registerinhalt von $s0 ist danach:

0000 0000 0011 1101 0000 0000 0000 0000 Füge anschließend die unteren 16 Bits ein:

ori $s0, $s0, 2304 # 2304 dez = 0000 1001 0000 0000 bin Registerinhalt von $s0 ist danach:

0000 0000 0011 1101 0000 1001 0000 0000

(24)

Immediate in Branches sind nur 16 Bit lang

Erinnerung: Bedingter Sprung

bne $s0, $s1, Exit # gehe nach Exit, wenn $s0!=$s1 Als Maschinen‐Instruktion (I‐Typ):

000101 10001 10000 1010001011001000 bne $s1 $s0 Exit (immediate) Also, nur 16‐Bit für die Branch‐Adresse verfügbar!

Konsequenz, wenn Exit eine absolute Adresse wäre:

0x00000000 : ...

...

0x0000EFF0 : bne $s0, $s1, 0x00010000 # ?!?

...

0x0000FFFF : ...

0x00010000 : ...

(25)

Lösung: Branches sind PC‐Relativ

Betrachte folgendes Beispiel (Adressen seien Dezimal dargestellt):

80012 : bne $s0, $s1, Exit 80016 : addi $s3,$s3,1

80020 : j Loop 80024 : Exit:

Label Exit könnte doch nur die Sprungdifferenz 80024‐80012 = 12 codieren, d.h.

80012 : bne $s0, $s1, 12 80016 : addi $s3,$s3,1 80020 : j Loop

80024 : Exit:

Noch besser, codiere nur die Anzahl zu überspringender Befehle (also 3 = 12/4):

80012 : bne $s0, $s1, 3 80016 : addi $s3,$s3,1 80020 : j Loop

80024 : Exit:

(Erinnerung: Instruktionen haben immer Word‐Länge, also 32‐Bit)

(26)

Lösung: Branches sind PC‐Relativ

Sei der Program‐Counter $pc= 80012 und $s0!=$s1 sei erfüllt:

80012 : bne $s0, $s1, 3 80016 : addi $s3,$s3,1 80020 : j Loop

80024 : Exit:

Auf welchen Wert muss der Program‐Counter als nächstes gesetzt werden?

Achtung: obiges Beispiel ist nicht korrekt. MIPS setzt $pc=$pc+4 schon vor  Abarbeitung des Befehls. Wie muss damit Zeile 80012 korrekt lauten?

(27)

Immediate in Jumps sind nur 26 Bit lang

Erinnerung: Unbedingter Sprung

j Exit # spinge immer nach Exit Als Maschinen‐Instruktion (J‐Typ):

000010 10001100001010001011001000 j Exit (address)

Also, nur 26 Bit für die Adresse verfügbar! Also folgender Adressbereich:

von 0x00000000 bis 0x03FFFFFF Konsequenz, wenn Exit eine absolute Adresse wäre:

0x10000000 : j 0x10000010 # ?!?

...

0x10000010 : ...

(28)

Lösung: Jumps sind Pseudo‐Direkt

Betrachte voriges Beispiel aber mit korrektem 26‐Bit Adressfeld:

0x10000000 : j 0x10 # 00 0000 0000 0000 0000 0001 0000 0x10000004 : ...

...

0x10000010 : ...

Der Program‐Counter sei $pc=0x10000004. Wie kommt man nach  0x10000010?

(0x10000004 = 0001 0000 0000 0000 0000 0000 0000 0100 0xFC000000 = 1111 1100 0000 0000 0000 0000 0000 0000 0x00000010 = 00 0000 0000 0000 0000 0001 0000 0x10000010 = 0001 0000 0000 0000 0000 0000 0001 0000)

(29)

Lösung: Jumps sind Pseudo‐Direkt

Auch hier wieder, nutze die Tatsache, dass Befehle immer 4 Bytes lang sind:

0x10000000 : j 0x4 # 00 0000 0000 0000 0000 0000 0100 0x10000004 : ...

...

0x10000010 : ...

Der Program‐Counter sei $pc=0x10000004. Wie kommt man nach  0x10000010?

(0x10000004 = 0001 0000 0000 0000 0000 0000 0000 0100 0xF0000000 = 1111 0000 0000 0000 0000 0000 0000 0000 0x00000004 = 00 0000 0000 0000 0000 0000 0100 0x00000010 = 0000 0000 0000 0000 0000 0001 0000 0x10000010 = 0001 0000 0000 0000 0000 0000 0001 0000)

(30)

Achtung: Programm‐Address‐Boundary

Berachte folgendes Beispiel:

0x10EFFF10 : j Label ...

0x20000000 : Label: ...

Wie vorher hergeleitet muss das Label folgendes erfüllen:

$pc = ($pc AND 0xF0000000) OR (Label LSHIFT 2) Wie muss das Label übersetzt werden?

(0x10EFFF14 = 0001 0000 1110 1111 1111 1111 0001 0100 0xF0000000 = 1111 0000 0000 0000 0000 0000 0000 0000 0x20000000 = 0010 0000 0000 0000 0000 0000 0000 0000) Also, Sprung von 0x1??????? Nach 0x2??????? So nicht möglich.

(31)

Achtung: Programm‐Address‐Boundary

Allgemein: Sprünge in der Form beschränkt auf die 256MB Speicherblöcke 0x00000000 bis 0x0FFFFFFF

0x10000000 bis 0x1FFFFFFF ...

0xF0000000 bis 0xFFFFFFFF

Und wenn man doch über Blockgrenzen springen will?

Beispiel: Sprung aus beliebigem Speicherbereich nach 0x20002000:

(32)

Zusammenfassung der neuen Befehle

Instruktion Beispiel Beduetung

lui lui $s1, 61 Lade 16‐Bit‐Wert in obere 16 Bits 

von Register $s1

(33)

Quiz

80000 : Loop: sll $t1,$s3,2 # Temp-Reg $t1 = i * 4

80004 : add $t1,$t1,$s6 # $t1 = Adresse von safe[i]

80008 : lw $t0,0($t1) # Temp-Reg $t0 = save[i]

80012 : bne $t0,$s5,Exit # gehe nach Exit, wenn save[i]!=k 80016 : addi $s3,$s3,1 # i = i + 1

80020 : j Loop # gehe wieder nach Loop 80024 : Exit:

Adresse Opcode rs rt rd shamt Funct

80000 0 0 19 9 2 0

80004 0 9 22 9 0 32

80008 35 9 8 0

80012 5 8 21

80016 8 19 19 1

80020 2

80024 ...

Was steht hier?

Referenzen

ÄHNLICHE DOKUMENTE

Weiterbildungsbefugte so- wie Ärztinnen und Ärzte in der Wei- terbildung können sich innerhalb der nächsten sechs bis acht Wochen an einer bundesweiten Umfrage zur Situation

Zwar könne man mit Fach- wissen zu einem bestimmten Problem viel herausholen, glaubt IT-Experte Steinberger, aber einer der wertvollsten Aspekte moderner KI ist, dass

Für diese sogenannten Neuschöpfungen galt dabei nach Ansicht des Dombaumeisters Tornow, «dass jed- wedes, auch nur das leiseste Hervortreten der künst- lerischen

Wirken zwei Kräfte F und F mit verschiedener Wirkungslinie auf einen Körper, so findet man die resultierende Kraft F wie in den Zeichnungen dargestellt durch

→ Der entstehende Code kann Sprünge aus dem Rumpf einer Funktion in eine andere enthalten ???.. Exkurs 4: Interprozedurale Analyse. Bisher können wir nur jede Funktion

Aufgabe 1: Zeigen Sie mithilfe eines Gegenbeispieles, dass die Rückrichtung in Teil b) von Satz 1 aus der Vorlesung im Allgemeinen nicht gilt. Aufgabe 2: Sei f : (a, b) → R eine

Universit¨ at T¨ ubingen T¨ ubingen, den 07.11.2016 Mathematisches

Endlich bemerke ich noch, dass sich statt fi öfter i geschrieben findet, eine in allen Manuscripten häufige Erscheinung.. Halle,