Formate für Sprungbefehle - userpages.uni-koblenz.deunikorn/lehre/gdra/ss18/03 MIPS... · Formate...

Post on 27-Aug-2019

236 views 0 download

Transcript of Formate für Sprungbefehle - userpages.uni-koblenz.deunikorn/lehre/gdra/ss18/03 MIPS... · Formate...

Formate für Sprungbefehle

Grundlagen der Rechnerarchitektur ‐ Assembler 48

Bedingte Sprünge beq und bne haben das Format I‐Typ (Immediate):

beq $s1, $s2, Label

4 18 17 LabelOpcode6 Bit

Source5 Bit

Dest5 Bit

Konstante oder Adresse16 Bit

I‐Typ

Unbedingter Sprung hat das Format J‐Typ (Jump‐Format):

j addr # Springe nach Adresse addr

2 addrOpcode6 Bit

Adresse26 Bit

J‐Typ

Anwendungsbeispiel if‐then‐else

Grundlagen der Rechnerarchitektur ‐ Assembler 49

if (i == j) thenf = g + h;

elsef = g - h;

Es sei f,…,j in $s0,…,$s4 gespeichert:

bne $s3,$s4,Else # gehe nach Else wenn i!=jadd $s0,$s1,$s2 # f = g + h (bei i!=j übersprungen)j Exit # gehe nach Exit

Else: sub $s0,$s1,$s2 # f = g – h (bei i==j übersprungen)Exit:

Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012

Anwendungsbeispiel while

Grundlagen der Rechnerarchitektur ‐ Assembler 50

while (safe[i] == k)i += 1;

Es sei i und k in $s3 und $s5 gespeichert und die Basis von safe sei $s6:

Loop: sll $t1,$s3,2 # Temp-Reg $t1 = i * 4add $t1,$t1,$s6 # $t1 = Adresse von safe[i]lw $t0,0($t1) # Temp-Reg $t0 = save[i]bne $t0,$s5,Exit # gehe nach Exit, wenn save[i]!=kaddi $s3,$s3,1 # i = i + 1j Loop # gehe wieder nach Loop

Exit:

safe[i]b0 b1 b2 b3 b4 b5 …

Test auf Größer und Kleiner?

Grundlagen der Rechnerarchitektur ‐ Assembler 51

slt $t0, $s3, $s4 # $t0 = 1 wenn $s3 < $s4

slti $t0, $s2, 10 # $t0 = 1 wenn $s2 < 10

Beispiel: springe nach Exit, wenn $s2 < 42

...slti $t0, $s2, 42bne $t0, $zero, Exit...

Exit:

Signed und unsigned Vergleiche 

Grundlagen der Rechnerarchitektur ‐ Assembler 52

Registerinhalt von $s0 sei:1111 1111 1111 1111 1111 1111 1111 1111

Registerinhalt von $s1 sei:0000 0000 0000 0000 0000 0000 0000 0001

Was ist der Wert von $t0 nach Ausführung der folgenden Zeile:slt $t0, $s0, $s1 # Signed-Vergleich $s0<$s1

Was ist der Wert von $t1 nach Ausführung der folgenden Zeile:sltu $t0, $s0, $s1 # Unsigned-Vergleich $s0<$s1

Beispiel: Test auf 0 <= $s0 < $s1 in einer Code‐Zeile

Grundlagen der Rechnerarchitektur ‐ Assembler 53

Umständlicher Test in zwei Zeilen:

slti $t0, $s0, 0 # $t0=1 wenn $s0<0 sonst $t0=0bne $t0, $zero, OutOfBound # gehe nach OutOfBound wenn $t0!=0slt $t0, $s0, $s1 # $t0=1 wenn $s0<$s1 sonst $t0=0beq $t0, $zero, OutOfBound # gehe nach OutOfBound wenn $t0==0...OutOfBound:

Test in einer Zeile wenn $s1 immer größer oder gleich 0 ist?

Unterstützung von Jump‐Tables

Grundlagen der Rechnerarchitektur ‐ Assembler 54

Assembler‐Code:

Label_1: ...

...

Label_2: ...

...

Label_n: ...

Nr Label Adresse

0 Label_1 0x05342120

1 Label_2 0x05443004

... ...

n‐2

n‐1 Label_n 0x06756900

Jump‐Table

# Gewünschter Label sei in $s0 gespeichert und# Startadresse der Jump-Table sei in $s1

# Lade Adresse für gewünschtes Label in $t0sll $t0, $s0, 2add $t0, $t0, $s1lw $t0, 0($t0)

# Springe an die in $t0 gespeicherte Adressejr $t0

Maschinen‐Code:

0x05342120: 1011010110...

...

0x05443004: 0001011101...

...

0x06756900: 0000111000...

Floating‐Point und Branches

Grundlagen der Rechnerarchitektur ‐ Assembler 55

MIPS‐Floating‐Point‐Instruktionen erlauben Vergleiche der Form:c.x.s $f2,$f3 # Vergleiche Single $f2 mit $f3 c.x.d $f2,$f4 # Vergleiche Double $f2 mit $f4

Hierbei kann x in c.x.s bzw. c.x.d stehen für:eq = equallt = less thanle = less or equal

Beispiele:c.eq.s $f2,$f3 # $f2 = $f3 ? c.lt.d $f2,$f4 # ($f2,$f3) < ($f4,$f5)?c.le.s $f2,$f3 # $f2 <= $f3?

Und dann findet der Branch wie statt?

Grundlagen der Rechnerarchitektur ‐ Assembler 56

Instruktion bc1t und bc1f nach dem Floating‐Point‐Vergleich:bc1t Label # springe nach Label, wenn der

# vorige Floating-Point-Vergleich# erfüllt ist

bc1f Label # springe nach Label, wenn der # vorige Floating-Point-Vergleich# nicht erfüllt ist

(Bemerkung c1 steht für Coprozessor 1; Erinnerung: die FPU ist dort)

Beispiel:c.lt.d $f2,$f4 # ($f2,$f3) < ($f4,$f5)?bc1t Label # springe nach Label, wenn

# ($f2,$f3) < ($f4,$f5) gilt....Label: ...

Condition‐Flags

Grundlagen der Rechnerarchitektur ‐ Assembler 57

CPU Coprocessor 1 (FPU)

$f0...

$f31

ArithmeticUnit

Registers

Memory

0 0 0 1 0 0 1 00 1 2 3 4 5 6 7

Condition‐Flags

Die Floating‐Point‐Vergleichsbefehle c.x.s und c.x.d setzen Default‐mäßig das Condition‐Flag 0.

Die Floating‐Point‐Sprungbefehle bc1t und bc1fspringen, wenn das Flag 0 gesetzt bzw. nicht gesetzt ist.

Alternativ kann man auch die anderen Flags verwenden. Dann gibt man diese mit den Instruktionen an. Beispiel:

c.eq.s 2 $f2,$f3 # Setze Cond.-Flag# 2, wenn $f2=$f3.

bc1t 2 Lab # springe nach Lab# wenn Cond.-Flag# 2 gesetzt ist.

Zusammenfassung der Sprung‐Instruktionen

Grundlagen der Rechnerarchitektur ‐ Assembler 58

Instruktion Beispiel Bedeutung des BeispielsGanzzahlig

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)

Floatin

g‐Po

int 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 (singleprecision)

Quiz

Grundlagen der Rechnerarchitektur ‐ Assembler 59

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

loop: ...

j loopcontinue: ...

Tipp: wir brauchenbeq, slt und bne

Und noch ein Quiz

Grundlagen der Rechnerarchitektur ‐ Assembler 60

Annahme:$s1 = 0xFFFFFFFF$s2 = 0x00000001

In welchem der beiden Code‐Abschnitte wird gesprungen?

...slt $t0,$s1,$s2bne $t0,$zero, lab...

...lab: ...

...

...sltu $t0,$s1,$s2beq $t0,$zero, lab...

...lab: ...

...Sprung:ja

nein

Sprung:ja

nein

Prozeduren

Grundlagen der Rechnerarchitektur ‐ Assembler 61

Das Prinzip von Prozeduren

Grundlagen der Rechnerarchitektur ‐ Assembler 62

Hauptprogramm:

.

.

.

x = 2*fakultät(10)

.

.

.

Programm‐abarbeitung

Prozedur mit dem Namen fakultät

.

.Berechne n!

.

.

Prozeduraufrufmit Parameter n=10

Prozedurrücksprungmit Ergebnis n!

Randbemerkung: was ist n! ?

Programmzähler und Rücksprungadresse

Grundlagen der Rechnerarchitektur ‐ Assembler 63

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 desHauptprogramms

Aufruf der Prozedur

Register $pcProzedur Fakultät

Rücksprung aus derProzedur

Adresse Maschineninstruktion

Register $ra

Assembler‐Beispiel

Grundlagen der Rechnerarchitektur ‐ Assembler 64

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

...

Fakultaet: # Die Prozedur Fakultaet# erwartet den Übergabeparameter in $a0# gibt das Ergebnis in $v0 zurück0x0040024 ... # Berechnung der Fakultät

... # Das Ergebnis sei in $a00x004002c add $v0,$a0,$zero # speichere Ergebnis in $v00x0040030 jr $ra

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

Problem

Grundlagen der Rechnerarchitektur ‐ Assembler 65

Hauptprogramm:..

$s0 = 42vor 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

.

.

Prozeduraufrufmit Parameter n=10

Prozedurrücksprungmit Ergebnis n!Register $s0

Lösung

Grundlagen der Rechnerarchitektur ‐ Assembler 66

Hauptprogramm:..

$s0 = 42vor Aufruf

.x = 2*fakultät(10)

.

.Es gilt immer 

noch $s0=42 !!!..

Prozedur mit dem Namen fakultätRette 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

Assembler‐Beispiel

Grundlagen der Rechnerarchitektur ‐ Assembler 67

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

# berechne Fakultät# $s0 wird dabei überschrieben

lw $s0, 0($sp) # restauriere $s0 vom Stackaddi $sp, $sp, 4 # dekrementiere Stack-Pointerjr $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)

Registerkonvention

Grundlagen der Rechnerarchitektur ‐ Assembler 68

Name Nummer Verwendung Wird über Aufrufgrenzenbewahrt?

$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

Rekursive Prozeduren

Grundlagen der Rechnerarchitektur ‐ Assembler 69

Hauptprogramm:

.

.

.

x = 2*fakultät(10)

.

.

.

Prozedur mit dem Namen fakultät

.

.Berechne n!

.

.

Prozeduraufruf

Letzter Rücksprungmit Gesamtergebnis

Wenn Rekursionsende noch nicht erreicht,dann erneuter Prozeduraufruf(„mit kleinerem Parameter“)

Alle vorigen Rücksprünge

Verwendung des Stacks

Grundlagen der Rechnerarchitektur ‐ Assembler 70

Haupt‐programm

Fakultät

Fakultät

Fakultät

Rekursionsende

Stack

$sp

Fakultät

Assembler‐Beispiel

Grundlagen der Rechnerarchitektur ‐ Assembler 71

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);}

}

Assembler‐Beispiel

Grundlagen der Rechnerarchitektur ‐ Assembler 72

# Berechnung der Fakultät von n (also n!)# Eingabeparameter n ist in $a0 gespeichert# Rückgabeparameter der Berechnung ist $v0fact: addi $sp, $sp, -8 # push Stack-Pointer um zwei Word

sw $ra, 4($sp) # rette Rücksprungadresse auf Stacksw $a0, 0($sp) # rette Eingabeparameter auf Stack

slti $t0, $a0, 1 # teste n < 1beq $t0, $zero, L1 # wenn n >= 1 dann gehe nach L1

addi $v0, $zero, 1 # es wird 1 zurückgegebenaddi $sp, $sp, 8 # pop Stack-Pointer um zwei Wordjr $ra # Rücksprung zum Prozedur-Aufrufer

L1: addi $a0, $a0, -1 # setze Argument auf n-1jal fact # rufe fact rekursiv mit n-1 auf

lw $a0, 0($sp) # restauriere Eingabeparam vom Stacklw $ra, 4($sp) # restauriere Rücksprungadr vom Stackaddi $sp, $sp, 8 # pop Stack-Pointer um zwei Wordmul $v0, $a0, $v0 # es wird n * fact(n-1) zurück gegebenjr $ra

Procedure‐Frame und Frame‐Pointer

Grundlagen der Rechnerarchitektur ‐ Assembler 73

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 AdresseStack‐Pointer $sp

Frame‐Pointer $fp

UnbenutzerStack‐Speicher

BenutzerStack‐Speicher

Procedure‐Frame

Argument 5Argument 6

Speicherbelegungskonvention

Grundlagen der Rechnerarchitektur ‐ Assembler 74

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

Die Sprunginstruktionen zusammengefasst

Grundlagen der Rechnerarchitektur ‐ Assembler 75

Instruktion Beispiel Beduetungj j Label $pc = Sprungadressejal jal Label $ra = $pc+4, $pc = Sprungadressejr jr $s1 $pc = Registerinhalt

$pc ist der Program‐Counter$ra ist das 32te CPU‐Register 

Schwieriges Quiz

Grundlagen der Rechnerarchitektur ‐ Assembler 76

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

add $t0, $a0, $zero # $t0 = naddi $a1, $a1, -1 # m = m - 1beq $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 = $t0lw $ra, 0($sp) # springe zurückaddi $sp, $sp, 4 #jr $ra #

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>0Rückgabeparameter: $v0Temporäre Berechnung: $t0

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

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 $t0Sichern von $t0Aufruf einer anderen ProzedurRestaurieren von $t0

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

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

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

Bemerkung zu vorigem Quiz

Grundlagen der Rechnerarchitektur ‐ Assembler 77