• Keine Ergebnisse gefunden

GanzzahligFloating Point ‐

N/A
N/A
Protected

Academic year: 2022

Aktie "GanzzahligFloating Point ‐"

Copied!
27
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Test auf Größer und Kleiner?

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, 42

bne $t0, $zero, Exit ...

Exit:

(2)

Signed und unsigned Vergleiche 

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

(3)

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

Umständlicher Test in zwei Zeilen:

slti $t0, $s0, 0 # $t0=1 wenn $s0<0 sonst $t0=0

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

OutOfBound:

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

(4)

Unterstützung von Jump‐Tables

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 $t0 sll $t0, $s0, 2

add $t0, $t0, $s1 lw $t0, 0($t0)

# Springe an die in $t0 gespeicherte Adresse jr $t0

Maschinen‐Code:

0x05342120: 1011010110...

...

0x05443004: 0001011101...

...

0x06756900: 0000111000...

(5)

Floating‐Point und Branches

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 $f3 Hierbei ist kann  x in  c.x.s bzw.  c.x.d stehen für:

eq = equal

lt = less than

le = 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?

(6)

Und dann findet der Branch wie statt?

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: ...

(7)

Condition‐Flags

CPU Coprocessor 1 (FPU)

$f0 . . .

$f31

Arithmetic Unit Registers Memory

0 0 0 1 0 0 1 0 0 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 bc1tund bc1f springen, 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

# wenn $f2=$f3.

bc1t 2 Lab # springe nach Lab

# wenn Cond.-Flag

# gesetzt ist.

(8)

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)

(9)

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

(10)

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

(11)

Prozeduren

(12)

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! ?

(13)

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

(14)

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

(15)

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

(16)

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

(17)

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

(18)

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

(19)

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“)

(20)

Verwendung des Stacks

Haupt‐

programm

Fakultät

Fakultät

Fakultät

Rekursionsende Stack

$sp

Fakultät

(21)

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

}

}

(22)

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

mul $v0, $a0, $v0 # es wird n * fact(n-1) zurück gegeben

(23)

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

(24)

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  dynamisch (d.h. während  der Laufzeit angelegten)  Daten.

Heap

0x00400000 0x10000000 0x10008000 0x7ffffffc

0x00000000

$pc

$sp

$gp

(25)

Die Sprunginstruktionen zusammengefasst

Instruktion Beispiel Beduetung

j j Label $pc = Sprungadresse

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

$pc ist der Program‐Counter

$ra ist das 32te CPU‐Register 

(26)

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 #

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>0

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

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

(27)

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 muss 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

Referenzen

ÄHNLICHE DOKUMENTE

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

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

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

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

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

→ 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

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