• Keine Ergebnisse gefunden

Zusammenfassung der neuen Befehle

N/A
N/A
Protected

Academic year: 2022

Aktie "Zusammenfassung der neuen Befehle"

Copied!
41
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

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

(2)

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

U d d h üb Bl k i ill?

Und wenn man doch über Blockgrenzen springen will?

Beispiel: Sprung aus beliebigem Speicherbereich nach 0x20002000:

Beispiel: Sprung aus beliebigem Speicherbereich nach 0x20002000:

(3)

Zusammenfassung der neuen Befehle

Instruktion Beispiel Beduetung

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

(4)

Quiz

80000 L ll $t1 $ 3 2 # T R $t1 i * 4

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

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

Was steht hier?

80024 ...

(5)

Synchronisation

(6)

Data‐Race

Prozessor 1: berechne x = x + 2 Prozessor 1:  berechne x = x + 2

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, 2 # $t0 = $t0 + 2

Gemeinsamer Speicher addi $t0, $t0, 2 # $t0   $t0   2

sw $t0, 0($s0) # speichere $t0 nach x

Variable x Prozessor 2:  berechne x = x – 1

$ $ $

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x

Es gelte zu Beginn: x=10g g Gilt nach Durchlauf beider  Code‐Abschnitte immer  x=11?

(7)

Problem: Zugriff auf x ist nicht atomar

Prozessor 1: berechne x = x + 2

Inhalt von x 10

Prozessor 1:  berechne x = x + 2

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, 2 # $t0 = $t0 + 2 addi $t0, $t0, 2 # $t0   $t0   2

sw $t0, 0($s0) # speichere $t0 nach x

Prozessor 2:  berechne x = x – 1

$ $ $

lw $t0, 0($s0) # lade x nach $t0 addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x

Zeit

(8)

Mögliche Lösung: Atomic‐Swap

Speicher

swap $t1, lock

Speicher 1.) Speicherinhalt lock in Register $t1 kopieren

2.) Alten Wert von $t1 nach lock kopieren

Variable lock Beispiel

$t1 lock

Vor Ausführung von swap 1 0

Nach Ausführung von swap 0 1

swap ist hierbei atomar, d.h. während des swap wird jeglicher Speicherzugriff anderer  MIPS‐ISA hat kein swap, dennoch gibt es andere ISAs die so einen Befehl haben.

Also zunächst ein Beispiel wie man mittels swap synchronisieren kann Prozesse verzögert bis swap vollständig ausgeführt wurde!

Also, zunächst ein Beispiel, wie man mittels swap synchronisieren kann.

(9)

Mögliche Lösung: Atomic‐Swap

Prozessor 1:  berechne x = x + 2

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0

lw $t0, 0($s0) # lade x nach $t0 Gemeinsamer Speicher addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

Variable x Variable x

Variable lock (initial=0) Prozessor 2:  berechne x = x – 1

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

(10)

Mögliche Lösung: Atomic‐Swap

x Prozessor 1:  berechne x = x + 2 lock

addi $t1, $zero, 1 # setze $t1 auf 1

x 10 lock

0 loop: swap $t1, lock # tausche $t1 und lock

bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, 2 # $t0 = $t0 + 2

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei Prozessor 2:  berechne x = x – 1

addi $t1, $zero, 1 # setze $t1 auf 1

loop: swap $t1, lock # tausche $t1 und lock bne $t1, $zero, loop # nochmal wenn $t1!=0 lw $t0, 0($s0) # lade x nach $t0

addi $t0, $t0, -1 # $t0 = $t0 – 1

sw $t0, 0($s0) # speichere $t0 nach x swap $t1, lock # gib lock wieder frei

Zeit

(11)

Weitere Lösung: Load Linked und Store Conditional

Speicher ll $t1, 0($s1) # load linked Speicher Lade den Inhalt der Speicherstelle 0($s1) in das 

Register $t1 

ll $t1, 0($s1) # load linked

Variable lock sc $t0, 0($s1) # store conditional

1 Wenn seit dem letztem load linked keiner 1. Wenn seit dem letztem load linked keiner 

auf den Speicherblock zugegriffen hat , dann  Speichere den Inhalt von Register $t0 auf die  Speicherstelle 0($s1) und setze $t0 auf 1.

Speicherstelle 0($s1) und setze $t0 auf 1.

2. Sonst lasse den Speicherblock unberührt  und setze $t0 auf 0.

MIPS‐ISA hat ein Load‐Linked (ll) und Store‐Conditional (sc).

Also, wie kann man mit ll und sc synchronisieren?

(12)

Weitere Lösung: Load Linked und Store Conditional

Prozessor 1:  berechne x = x + 2

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, 2 # $t0 = $t0 + 2 Gemeinsamer Speicher sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Variable x Variable x

Prozessor 2: berechne x = x – 1 Prozessor 2:  berechne x = x  1

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, -1 # $t0 = $t0 – 1 addi $t0, $t0, 1 # $t0   $t0  1 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

(13)

Weitere Lösung: Load Linked und Store Conditional

x

Prozessor 1:  berechne x = x + 2

x 10

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, 2 # $t0 = $t0 + 2 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Prozessor 2: berechne x = x – 1 Prozessor 2:  berechne x = x  1

loop: ll $t0, 0($s0) # $t0 = x

addi $t0, $t0, -1 # $t0 = $t0 – 1 addi $t0, $t0, 1 # $t0   $t0  1 sc $t0, 0($s0) # x = $t0

beq $t0, $zero, loop # nochmal bei failure

Zeit

(14)

Zusammenfassung der neuen Befehle

Instruktuion Beispiel Bedeutung

ll ll $s1, 0($s0)$ , ($ ) Lade den Inhalt von Adresse 0($s0) in ($ )

$s1 und starte eine atomare Read‐

Modify‐Write‐Operation.

sc sc $t0, 0($s0)  Speichere den Inhalt von $t0 auf  Adresse 0($s0), wenn seit dem 

l t t ll i ht i d

letzten ll nicht von einem anderen  Prozess auf den Speicherblock 

zugegriffen wurde der das zugegriffen wurde, der das 

adressierte Word enthält. Setze $t0  auf 1 in diesem Fall. 

Ansonsten überschreibe den 

Speicherbereich nicht und setze $t0  f 0

auf 0.

(15)

Quiz für den Quizmaster

R li i R i t Ad it it ll d

Realisiere swap Register, Adresse mit mit ll und sc. Das Register sei $s0

i d i ($ )

Die Adresse sei 0($s1) Das temporäre

Register sei $t0 Register sei $t0

Erinnerung:

Erinnerung:

swap tauscht Speicher‐

inhalt und Registerinhalt  atomar aus.

(16)

Exceptions

(17)

Motivation: Behandlung von Overflows

Was war nochmal ein Overflow? Beispiel mit 8‐Bit‐Zahlen:

01011010 (= 90) + 01100111 ( 103) + 01100111 (=103) --- 11000001 (=-63) 11000001 ( 63)

Die bisher behandelten ganzzahligen Arithmetik‐Instruktionen (z.B. 

dd ddi d b ) kö O fl

addaddi und sub ) können Overflow erzeugen.

Was wenn so ein Overflow auftritt? Einfach ignorieren?g

Für jeden Overflow sollte eine Ausnahmebehandlungsroutine  aufgerufen werden die dann entscheidet was zu tun ist

aufgerufen werden, die dann entscheidet was zu tun ist. 

Anschließend kann der normale Code wieder ausgeführt werden.

Eine solche Ausnahmebehandlung wird über Exceptions realisiert.

(18)

Beispiele für Exceptions

Ereignistyp Ausgelöst durch Interrupt den Prozessor?

Anfrage eines I/O Gerätes nein X

System‐Call ja

Arithmetischer Overflow ja Verwendung einer undefinierten

Instruktion

ja

Hardwarefehler ja/nein (X)

... ...

Von außen ausgelöste Exceptions nennt man auch Interrupts

(19)

Behandlung von Exceptions

Genereller Ablauf:

Exception‐Handler

(3) Springe zum

Exception‐Handler (4) Handle Exception

(5) i f

Aktuell laufendes 

(2) Sichere $pc (5) springe ggf.

wieder zurück.

Rücksprung mit

Programm (1) Exception Rücksprung mit

gesichertem $pc möglich.

Woher weis die CPU  wo der Exception‐

dl l ? Speicher Handler liegt?

(20)

Behandlung von Exceptions

Möglichkeit 1: Interrupt‐Vektor‐Tabelle

Speichere Adresse der aktuellen Speichere Adresse der aktuellen 

Programmausführung in einem 

speziellen Register EPC. Exception‐

Typ

Adresse des  Exception‐

Wähle aus der Interrupt‐Vektor‐

yp p

Handlers

Undefinde 0x8000 0000

Tabelle die Adresse des Handlers  für diesen Exception‐Typ  und 

springe dort hin.

Instruction

Arithmetic 0x8000 0180

p g

Overflow

... ...

Handler‐Routine springt nach  Exception Behandlung ggf zurück Exception‐Behandlung ggf. zurück  in den normalen Code, d.h. an die  Programminstruktion auf die EPC 

i

Interrupt‐Vektor‐Tabelle

zeigt.

(21)

Behandlung von Exceptions

Möglichkeit 2: Cause‐Register (das ist die MIPS‐Variante)

Speichere Adresse der aktuellen 

P füh i i

Nummer Exception‐Typ (Grund) Programmausführung in einem 

speziellen Register EPC.

Speichere den Exception‐Typ in 

0 Interrupt (Hardware)

4 Address‐Error (load or fetch)

5 Add E ( t )

einem  speziellen Cause‐Register.

Springe an die Adresse des einen 

5 Address‐Error (store) 6 Bus‐Error (fetch) 7 Bus‐Error (store) Exception‐Handlers.

Der Exception‐Handler führt 

7 Bus Error (store)

8 System‐Call

9 Break‐Point

p

behandelt den im Cause‐Register  beschriebenen Exception‐Typ. 

Routine springt nach Exception‐

10 Reserved Instruction

11 Coprocessor Unimplemented

i h i fl

Routine springt nach Exception Behandlung ggf. zurück in den 

normalen Code, d.h. an die  Programminstruktion auf die

12 Arithmetic Overflow

13 Trap

15 Floating‐Point‐Exception Programminstruktion auf die

EPC zeigt.

15 Floating Point Exception

MIPS Exception‐Codes

(22)

MIPS Hardware‐Realisierung von Exceptions?

CPU Coprocessor 1 (FPU)

Memory

p ( )

$0 .

$0 . Registers Registers

. . .

$31

. . .

$31

$ Arithmetic

Unit

Multiply Divide

$

Arithmetic PC

Unit Divide

Unit

Lo Hi

Coprocessor 0 (Traps and Memory)

Registers Es gibt einen 

weiteren BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

weiteren  Coprozessor

(23)

Beispiel: Aufruf des Exception‐Handlers

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

$pc vor Exception:

0x40000018 : ...

...

$pc nach Exception:

# Exception-Handler beginnt immer hier 0x80000180 : ...

0x80000184 : ...

$pc nach Exception:

0x80000184 : ...

6       2 Exception‐Code für  Arithmetic Overflow 

C 0 (T d M )

ist 12.

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(24)

Beispiel: Handling der Exception

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

$pc zur Behandlung:

0x40000018 : ...

...

$pc nach Behandlung:

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$s2,0 # Problem gelöst 0x80000184 : eret # Rücksprung

$pc nach Behandlung:

0x80000184 : eret # Rücksprung

C 0 (T d M )

Coprocessor 0 (Traps and Memory)

40000014 Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(25)

Weitere Exceptions während des Handlings?

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

$pc zur Behandlung:

0x40000018 : ...

...

$pc nach Behandlung:

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$s2,0 # Problem gelöst 0x80000184 : eret # Rücksprung

$pc nach Behandlung:

0x80000184 : eret # Rücksprung

Möglichkeiten, z.B.:

Exception‐Handler erzeugt

C 0 (T d M )

selber eine Exception

Anfrage eines IO‐Gerätes Coprocessor 0 (Traps and Memory)

40000014 Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(26)

Exceptions während des Handlings abgeschaltet

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

Exception‐Level‐Bit:

0 = Exceptions werden 0x40000018 : ...

...

p

berücksichtigt

1 = Exceptions werden nicht berücksichtigt

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$s2,0 # Problem gelöst

0x80000184 : eret # Rücksprung Wi d b i S i d 0x80000184 : eret # Rücksprung

15       8      1 0

Wird bei Sprung in den Exception‐Handler immer gesetzt.

Bei Aufruf von eretwird

C 0 (T d M )

Bei Aufruf von eretwird das Bit wieder gelöscht

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(27)

Status erlaubt auch das Maskieren von Interrupts

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

Die Bits einer  Interrupt‐Maske bestimmen welche Interrupt‐

Level Exceptions erzeugen dür 0x40000018 : ...

...

Level Exceptions erzeugen dür‐

fen und welche ignoriert wer‐

den.

# Ein fauler Exception-Handler

0x80000180 : addi $s2,$s2,0 # Problem gelöst 0x80000184 : eret # Rücksprung

Jeder mögliche Interrupt ist einem Interrupt‐Level zugeord‐

net 0x80000184 : eret # Rücksprung

15       8      1 0 net.

Mit Bit 0 des Status‐

Registers können  Interrupts generell

C 0 (T d M )

Interrupt‐Maske

Interrupts generell  ein‐ und ausgeschaltet  werden.

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(28)

Pending‐Interrupts

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

Alle ankommenden Interrupts (auch ausmaskierte) setzen im Cause Register das

0x40000018 : ...

...

im Cause‐Register das

Pending‐Flag ihres Interrupt‐

Levels.

# Exception-Handler beginnt immer hier 0x80000180 : ...

0x80000184 : ...

Wird das Masken‐Bit (oder das generelle Interrupt‐Bit) später wieder aktiviert löst das

0x80000184 : ...

15      8       6       2

wieder aktiviert, löst das

Pending‐Bit dann den Interrupt auf der CPU aus.

C 0 (T d M )

Exception‐Code Pending

Interrupts

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(29)

Zugriff auf die Coprocesor‐0‐Register

Erinnerung: Für den FPU‐Coprozessor (Coprozessor 1) hatten wir:

mfc1 : laden von FP‐Coprozessor‐Register in CPU‐Register

t 1 l d CPU R i t i FP C R i t

mtc1 : laden von CPU‐Register in FP‐Coprozessor‐Register Analoge Instruktionen für den Coprozessor 0:

Analoge Instruktionen für den Coprozessor 0:

mfc0 : laden von Coprozessor1‐Register in CPU‐Register mtc0 : laden von CPU‐Register in Coprozessor1‐Register Beispiele:

mfc0 $s0 $13 # $s0 Coprozessor Register 13 mfc0 $s0, $13 # $s0=Coprozessor-Register 13 mtc0 $13, $s0 # Coprozessor-Register 13=$s0

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(30)

Beispiel für Coprocessor 0 Register‐Zugriff

# Es gelte $s2 = 0x7fffffff

0x40000014 : add $s1,$s2,$s2 # Overflow!

0x40000018 :

$pc zur Behandlung:

0x40000018 : ...

... $pc nach Behandlung:

# Ein etwas besserer Exception-Handler

# Exception auslösende Instruktion einfach überspringen

0x80000180 : mfc0 $k0,$14 # $k0 = EPC B ht R i t S t 0x80000180 : mfc0 $k0,$14 # $k0   EPC

0x80000184 : addi $k0,$k0,4 # $k0 = EPC+4 0x80000188 : mtc0 $k0,$k0,4 # EPC=EPC+4 0x8000018c : eret # Rücksprung

Beachte: Register‐Satz‐

Konvention: $k0 und $k1  sind für OS‐Funktionen reserviert Behandeln von

C 0 (T d M )

# p g reserviert. Behandeln von Exceptions ist eine OS‐

Funktion.

Coprocessor 0 (Traps and Memory) Registers

BadVadr ($8)  Status ($12) Cause ($13) EPC ($14)

(31)

Traps

Trap – eine Instruktion, die eine Bedingung testet und eine 

Exception vom Typ 13 (Trap) auslöst, wenn die Bedingung erfüllt ist.

Trap‐Instruktionen am Beispiel:

teq $s0,$s1 # Trap‐Exception, wenn $s0 = $s1 teqi $s0 42 # Trap Exception wenn $s0 = 42 teqi $s0,42 # Trap‐Exception, wenn $s0 = 42 tne $s0,$s1 # Trap‐Exception, wenn $s0 != $s1 tnei $s0,42 #$ , Trap‐Exception, wenn $s0 != 42p p , $ tge $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1

tgeu $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1 (unsigned)

$ $ $

tgei $s0,$42 # Trap‐Exception, wenn $s0 >= 42

tgeiu $s0,42 # Trap‐Exception, wenn $s0 >= 42 (unsigned) tlt $s0 $s1 # Trap‐Exception wenn $s0 < $s1

tlt $s0,$s1 # Trap‐Exception, wenn $s0 < $s1

tltu $s0,$s1 # Trap‐Exception, wenn $s0 < $s1 (unsigned) tlti $s0,$42 #, Trap‐Exception, wenn $s0 < 42p p ,

tltiu $s0,42 # Trap‐Exception, wenn $s0 < 42 (unsigned)

(32)

System‐Calls

System‐Call – Mechanismus zum Aufrufen von Betriebssystem‐

funktionen.

Anwendung der Instruktion syscall am Beispiel:

addi $v0, $zero, 1 # Lade System‐Call‐Code in $v0

# hi S C ll C d 1 fü d

# hier System‐Call‐Code 1 für den

# Systemcall print_int addi $a0 $zero 42 # Lade das Argument für den addi $a0, $zero, 42 # Lade das Argument für den

# System‐Call nach $a0.

# Hier soll die Zahl 42

# ausgegeben werden.

syscall # Rufe den System‐Call auf

# di füh t i E ti

# dies führt zu einer Exception

# vom Typ 8 (System‐Call)

(33)

In SPIM/MARS verfügbare System‐Calls

(34)

Zusammenfassung der neuen Befehle

Instruktuion Bedeutung

eret Springe aus Exception‐Handler zurück. Setzt  Exception‐Level‐Bit im Status‐Register wieder  auf 0.

teq, teqi, tne, tnei, tge, tgeu, tgei, tgeiu, tlt tltu tlti tltiu

Löse Trap‐Exception aus, wenn die Bedingung  erfüllt ist.

Beispiel: teq $s0 $s1 löst einen Trap aus tlt, tltu, tlti, tltiu Beispiel: teq $s0, $s1 löst einen Trap aus, 

wenn $s0 = $s1 gilt.

syscall Rufe System Call mit der in $v0 gespeicherten syscall Rufe System‐Call mit der in $v0 gespeicherten 

Nummer auf. Parameter des Syste‐Calls werden in $a0 uns $a1 übergeben.$ $ g

Beispiel: syscall gibt eine 42 auf dem 

Bildschirm aus, wenn $v0 = 1 (print_int) und 

$

$a0 = 42.

(35)

Unsigned Arithmetik‐Instruktionen

Zu den bisher behandelten Arithmetik‐Instruktionen gibt es auch  noch unsigned Varianten, die keine Overflow‐Exception erzeugen.

Beispiel:

# Es gelte $s2 = 0x7fffffff dd $ 1 $ 2 $ 2 # t *k i *

addu $s1,$s2,$s2 # erzeugt *keine*

# Overflow-Exception!

(36)

Signed und ihre Unsigend‐Varianten

Signed

Instruktion

kann 

Overflow

Unsigned Vertreter

kann 

Overflow Instruktion Overflow 

erzeugen

Vertreter Overflow  erzeugen

add ja addu nein

add ja addu nein

addi ja addiu nein

div nein divu nein

div nein divu nein

mult nein multu nein

mul i

mul nein

madd nein maddu nein

b b

msub nein msubu nein

sub ja subu nein

(37)

Leichtes Quiz

Bi di Z hl 1 bi 100 b

Bitte die Zahlen von 1 bis 100 ausgeben. Tipp:

System‐Call‐Code in $v0 Argument in $a0

A f f

Aufruf von syscall (System‐Call‐Code für

i t i t i t 1) print_int ist 1)

(38)

Pseudoinstruktionen, Direktiven und Makros

(39)

Motivation für Pseudoinstruktionen

Wir hatten häufiger schon

addi $s1,$zero,wert # $s1=wert

Eine Instruktion li (Load‐Immediate) wäre doch nachvollziebarer li $s1,wert # $s1=wert

MIPS als ISA aus dem RISC‐Lager versucht aber den Instruktion‐Set  möglichst klein zu halten. Damit ist so was wie ein li inder ISA 

$

nicht eingebaut. Kann man ja mit einem addi und dem $zero Register ausdrücken.

Dennoch gibt es in MIPS oben genannte Instruktion. Wo kommt die  her?

Das ist eine sogenannte Pseudoinstruktion, die der Assembler in  Instruktionen der MIPS ISA übersetzt.

(40)

Umsetzung von Pseudoinstruktionen

Wie würde folgende move Instruktion vom Assembler umgesetzt?

move $s1,$s2 # Pseudoinstruktion $s1=$s2

Wie würde folgende ble Instruktion vom Assembler umgesetzt?

blt $s1,$s2, Label # Branche nach Label,

# $ $

# wenn $s1<$s2 gilt

Beachte: Registerkonvention. Pseudoinstruktionen die ein Register  zum zwischenspeichern von Ergebnissen brauchen, benutzen dazu 

$ ( )

das Register $at (Assembler‐Temporary)

(41)

Einige MIPS‐Assembler Pseudoinstruktioen

Instruktion Beispiel Erklärung des Beispiel

blt, bltu blt $s1, $s2, Label Springe nach Label, wenn 

$s1 < $s2 (signed)

bgt, bgtu bgt $s1, $s2, Label Springe nach Label, wenn 

$s1 > $s2 (signed)

ble, bleu ble $s1, $s2, Label Springe nach Label, wenn 

$s1 <= $s2 (signed)

bge, bgeu bge $s1, $s2, Label Springe nach Label, wenn 

$ 1 $ 2 ( i d)

$s1 >= $s2 (signed)

li li $s1, 42 Lade Immediate 42 in $s1 move move $s1, $s2 $s1 = $s2

MARS unterstützt beispielsweise neben den 155 Basisinstruktionen p weitere 388 zusätzliche Pseudoinstruktionen.

Referenzen

ÄHNLICHE DOKUMENTE