• Keine Ergebnisse gefunden

32‐Bit‐Konstanten und Adressierung

N/A
N/A
Protected

Academic year: 2022

Aktie "32‐Bit‐Konstanten und Adressierung"

Copied!
28
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

32‐Bit‐Konstanten und Adressierung

(2)

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.

(3)

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

(4)

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

...

(5)

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)

(6)

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?

(7)

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

(8)

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)

(9)

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)

(10)

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.

(11)

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:

(12)

Zusammenfassung der neuen Befehle

Instruktion Beispiel Beduetung

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

von Register $s1

(13)

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?

(14)

Synchronisation

(15)

Data‐Race

Prozessor 1:  berechne x = x + 2

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

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

Gemeinsamer Speicher

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=10 Gilt nach Durchlauf beider  Code‐Abschnitte immer  x=11?

(16)

Problem: Zugriff auf x ist nicht atomar

Prozessor 1:  berechne x = x + 2

lw $t0, 0($s0) # lade x nach $t0 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

Inhalt von x 10

(17)

Mögliche Lösung: Atomic‐Swap

Speicher

Variable lock 1.) Speicherinhalt lock in Register $t1 kopieren

2.) Alten Wert von $t1 nach lock kopieren

swap $t1, lock

Beispiel

$t1 lock

Vor Ausführung von swap 1 0

Nach Ausführung von swap 0 1

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.

swap ist hierbei atomar, d.h. während des swap wird jeglicher Speicherzugriff anderer  Prozesse verzögert bis swap vollständig ausgeführt wurde!

(18)

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

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

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

Gemeinsamer Speicher

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

(19)

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

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 x 10 lock

0

(20)

Weitere Lösung: Load Linked und Store Conditional

Speicher

Variable lock Lade den Inhalt der Speicherstelle 0($s1) in das 

Register $t1 

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

sc $t0, 0($s1) # store conditional 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.

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

(21)

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 sc $t0, 0($s0) # x = $t0

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

Gemeinsamer Speicher

Variable x

Prozessor 2:  berechne x = x – 1

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

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

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

(22)

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 sc $t0, 0($s0) # x = $t0

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

Prozessor 2:  berechne x = x – 1

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

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

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

x 10

(23)

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 

letzten ll nicht von einem anderen  Prozess auf den Speicherblock 

zugegriffen wurde, der das 

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

Ansonsten überschreibe den 

Speicherbereich nicht und setze $t0 

auf 0.

(24)

Quiz für den Quizmaster

Realisiere  swap Register, Adresse mit  ll und  sc .

Erinnerung:

swap tauscht Speicher‐

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

Register sei $t0

(25)

Exceptions

(26)

Motivation: Behandlung von Overflows

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

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

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

addaddi und  sub ) können Overflow erzeugen.

Was wenn so ein Overflow auftritt? Einfach ignorieren?

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

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

(27)

Beispiele für Exceptions

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

Ereignistyp Ausgelöst durch

den Prozessor?

Interrupt Anfrage eines I/O Gerätes nein X

System‐Call ja

Arithmetischer Overflow ja Verwendung einer undefinierten

Instruktion

ja

Hardwarefehler ja/nein (X)

... ...

(28)

Behandlung von Exceptions

Genereller Ablauf:

Exception‐Handler

Aktuell laufendes 

Programm (1) Exception

(2) Sichere $pc (3) Springe zum

Exception‐Handler (4) Behandle die 

Exception (5) springe ggf.

wieder zurück.

Rücksprung mit gesichertem $pc möglich.

Woher weis die CPU 

wo der Exception‐

Referenzen

ÄHNLICHE DOKUMENTE

AdpcmSpeak() expands and reproduces ADPCM data AdpcmListen() compresses and records ADPCM data vsxSpeak() expands and reproduces VSX data vsxListen() compresses and records VSX

The CODE sections of all relocatable object files specified in { } are linked by resolving the symbol addresses in such a way that they can be located and executed in the same area

This state remains intact until an event is issued, the task is caused to resume (freed from a wait state) by some other task being executed or by an interrupt handler, or the task

At higher cutoff frequencies, quantization noise centering around the sampling frequency becomes conspicuous, degrading audio quality. Due to their low attenuation, the safe course

Now that an object file is created by the Make in an executable format (srf33), debugging of the program can be performed. Although more sophisticated debugging could be done using

: Operational amplifier based fourth-order low-pass filter circuit output (default) : Differential amplifier circuit (piezoelectric speaker) output. JP12 Operational amplifier

Seiko Epson does not assume any liability of any kind arising out of any inaccuracies contained in this material or due to its application or use in any product or circuit and,

A full 32 bit DMA Controller supporting data trans- fers to/from VMEbus memory as well as to/from local system RAM is provided by a FORCE specific 280 pin Gate