Grundlagen der Rechnerarchitektur
MIPS‐Assembler
Übersicht• Arithmetik, Register und Speicherzugriff• Darstellung von Instruktionen• Logische Operationen• Weitere Arithmetik• Branches und Jumps• Prozeduren• 32‐Bit‐Konstanten und Adressierung• Synchronisation• Exceptions• Pseudoinstruktionen, Direktiven und Makros
2Grundlagen der Rechnerarchitektur ‐ Assembler
Motivation
Grundlagen der Rechnerarchitektur ‐ Assembler 3
Warum ein Assembler‐Kurs?• Wir wollen etwas über Rechnerarchitektur lernen. Assembler ist ein Teil davon.
• Nach dem Erlernen von Assembler eines Systems, lernt man Assembler anderer Rechner kinderleicht
• Während wir uns mit Assembler beschäftigen lernen wir auch generelle Konzepte kennen, wie die Hardware in Computern und eingebetteten Systemen organisiert ist
Grundlagen der Rechnerarchitektur ‐ Assembler 4
Vor‐ und Nachteile von Assembler• Wann sollte man Assembler programmieren?
– Code‐Größe oder Geschwindigkeit sollen bis auf das äußerste ausgereizt werden
– Verwendung spezieller Maschineninstruktionen, die ein Compiler nicht nutzt (in der Regel bei CISC)
– Es gibt für die Computer‐Hardware keine höhere Sprache• Meist wird ein hybrider Ansatz gewählt
– Man programmiert das meiste in einer High‐Level‐Sprache– Nur kleine Teile des gesamten Codes werden direkt in Assembler
optimiert• Nachteil von Assembler
– Programme laufen nur für den Hardwaretyp für den diese programmiert sind
– Assembler‐Code ist im Vergleich zu High‐Level‐Sprachen deutlich länger
• Programmieren dauert deutlich länger• Programmieren ist fehleranfälliger (insbesondere wegen fehlender Struktur)
Grundlagen der Rechnerarchitektur ‐ Assembler 5
Assembler am Beispiel der MIPS‐Architektur• Frühere Einsatzgebiete MIPS
– Silicon Graphics Unix‐Workstations (z. B. SGI Indigo2) – Silicon Graphics Unix‐Server (z. B. SGI Origin2000) – DEC Workstations (z.B. DECstation‐Familie und DECsystem)– Siemens bzw. SNI Server der RM‐Serie– Control Data Corporation Computer des Typs CDC 4680
• Heutiger Einsatz von MIPS in eingebetteten Systemen– Cobalt‐Server bis RaQ/Qube2– BMW‐Navigationssysteme– die Fritz!Box– Satellitenreceiver– Dreambox– Konica Minolta DSLRs – Sony‐ und Nintendo‐Spielkonsolen
Grundlagen der Rechnerarchitektur ‐ Assembler 6Quelle der Liste: de.wikipedia.org/wiki/MIPS‐Architektur
7
Warum gerade MIPS (und nicht Intel x86)?• MIPS‐Instruktionssatz ist klar und einfach (RISC)• Sehr gut in Lehrbüchern beschrieben• Sehr ähnlich zu vielen modernen Prozessoren (z.B. ARM; schauen
wir uns eventuell auch noch kurz an)• MIPS ist eine kommerziell relevante Instruktionssatzarchitektur.
(z.B. 2002 wurden fast 100 Millionen MIPS Prozessoren hergestellt)
Grundlagen der Rechnerarchitektur ‐ Assembler
Begleitend: SPIM‐ und MARS‐Simulator
Grundlagen der Rechnerarchitektur ‐ Assembler 8
Programmieren lernt man nicht durch zuschauen!Alle Konzepte sollte man hier selber ausprobieren!
Arithmetik, Register und Speicherzugriff
Grundlagen der Rechnerarchitektur ‐ Assembler 9
Arithmetik und Zuweisungen
Grundlagen der Rechnerarchitektur ‐ Assembler 10
C Programm:
a = b + c;
d = a – e;
MIPS Instruktionen:
Einfache Arithmetik mit Zuweisung
C Programm:
f = (g + h) – (i + j);
MIPS Instruktionen (verwende temporäre Variablen t0 und t1):
Komplexere Arithmetik mit Zuweisung
Die Operanden sind Register
Grundlagen der Rechnerarchitektur ‐ Assembler 11
C Programm:
f = (g + h) – (i + j);
Sei hierbei:g in Register $s1 gespeicherth in Register $s2 gespeicherti in Register $s3 gespeichertj in Register $s4 gespeichertf in Register $s0 gespeichert
MIPS Instruktionen (verwende temporäre Register $t0 und $t1):
add $t0, $s1, $s2 # t0=g+hadd $t1, $s3, $s4 # t1=i+jsub $s0, $t0, $t1 # f=t0-t1
Voriges Beispiel: Komplexere Arithmetik mit Zuweisung
MIPS Registergröße = 32 Bit
Assembler‐Syntax:Das Zeichen # leitet für den Rest der Zeile einen Kommentar ein. Der Text wird vom Assembler einfach ignoriert.
Speicher‐Operanden
Grundlagen der Rechnerarchitektur ‐ Assembler 12
C Programm:
g = h + A[8];
Sei hierbei:g in Register $s1 gespeicherth in Register $s2 gespeichertBasisadresse von A in Register $s3
MIPS Instruktionen (verwende temporäres Register $t0):
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Alignment‐Restriction
Grundlagen der Rechnerarchitektur ‐ Assembler 13
Zugriff auf A[8], wenn Basisadresse von A in Register $s3 gespeichert?
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Laden und Speichern
Grundlagen der Rechnerarchitektur ‐ Assembler 14
C Programm:
A[12] = h + A[8];
Sei hierbei:Basisadresse von A in Register $s3 und h in Register $s2 gespeichert
MIPS Instruktionen (verwende temporäre Register $t0):
Laden und Speichern von Bytes
Grundlagen der Rechnerarchitektur ‐ Assembler 15
C Programm:
A[12] = h + A[8];
Sei hierbei:Basisadresse von A in Register $s3h in Register $s2 gespeichert
MIPS Instruktionen (verwende temporäre Register $t0):
Sei A[8] = 01110010. Was passiert im obigen Beispiel bei lb mit $t0 genau?
LSB$t0
MSB
Sei A[8] = 11110010. Was passiert im obigen Beispiel bei lb mit $t0 genau?
LSB$t0
MSB
Weitere Befehle zum Laden und Speichern
Grundlagen der Rechnerarchitektur ‐ Assembler 16
Laden von Byte ohne Sign‐Extension:lbu { Beispiel: lbu $t0, 27($s3) }
Was passiert im obigen Beispiel mit $t0, wenn 27($s3) = 11001000?
LSB$t0
MSB
Laden von Halfword mit Sign‐Extension:lh { Beispiel: lh $t0, 22($s3) }
Laden von Halfword ohne Sign‐Extension:lhu { Beispiel: lhu $t0, 22($s3) }
Speichern von Halfword:sh { Beispiel: sh $t0, 22($s3) }
Addieren und Laden von Konstanten
Grundlagen der Rechnerarchitektur ‐ Assembler 17
C Programm:
x = x + 4;
Sei hierbei:x in Register $s3 gespeichert
MIPS Instruktion:
MIPS erlaubt negative Konstanten und braucht damit kein ‚subi‘.
MIPS hat ein spezielles Register $zero, welches 0 ‘hart verdrahtet‘ speichert.
C Programm:
x = 42;
Sei hierbei:x in Register $s3 gespeichert
MIPS Instruktion:
Zwischenbilanz der MIPS Architektur
Grundlagen der Rechnerarchitektur ‐ Assembler 18
CPU
$0...
$31
ArithmeticUnit
Registers
Memory
Name Nummer Verwendung
$zero 0 Konstante 0
$at 1
$v0‐$v1 2‐3
$a0‐$a3 4‐7
$t0‐$t7 8‐15 Temporäre Register
$s0‐$s7 16‐23 „saved“ temporäre Reg.
$t8‐$t9 24‐25 Temporäre Register
$k0‐$k1 26‐27
$gp 28
$sp 29
$fp 30
$ra 31
Zusammenfassung der behandelten Instruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 19
Instruktion BedeutungArith
metik add rd, rs, rt Register rd = Register rs + Register rt
addi rt, rs, imm Register rt = Register rs + Konstante immsub rd, rs, rt Register rd = Register rs –Register rt
Lade
n
lb rt, address Lade Byte an der Adresse address in Register rt.Das Byte ist sign‐extended.
lbu rt, address Lade Byte an der Adresse address in Register rt.lh rt, address Lade Half‐Word an der Adresse address in Register rt.
Das Half‐Word ist sign‐extended.lhu rt, address Lade Half‐Word an der Adresse address in Register rt.lw rt, address Lade Word an der Adresse address in Register rt.
Speichern sb rt, address Speichere unterstes Byte des Registers rt an Adresse address
sh rt, address Speichere unteres Half‐Word des Registers rt an Adresse address
sw rt, address Speichere Inhalt des Registers rt an Adresse address.
Quiz
Grundlagen der Rechnerarchitektur ‐ Assembler 20
addi $s0, $zero, 4 #lw $s1, 0($s0) #lw $s2, 4($s0) #add $s1, $s1, $s1 #add $s1, $s1, $s2 #addi $s1, $s1, 1 #sw $s1, 0($s0) #
0 4214 128 4
12 33
…
Adresse
Inhalt (Word)
Speicher zu Beginn048
12
…
Adresse
Inhalt (Word)
Speicher nach Instruktionsdurchlauf
Darstellung von Instruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 21
Übersetzung aus Assembler in Maschinensprache
Grundlagen der Rechnerarchitektur ‐ Assembler 22
add $t0, $s1, $s2
0 17 18 8 0 326 Bit
Opcode5 Bit
Source15 Bit
Source25 BitDest
5 BitShamt
6 BitFunct
00000010001100100100000000100000
Assembler‐Instruktion
Maschinen‐Instruktion
Name Nr
$t0 8
$t1 9
$t2 10
$t3 11
$t4 12
$t5 13
$t6 14
$t7 15
Name Nr
$s0 16
$s1 17
$s2 18
$s3 19
$s4 20
$s5 21
$s6 22
$s7 23
Notwendigkeit für andere Instruktionsformate
Grundlagen der Rechnerarchitektur ‐ Assembler 23
op rs rt rd shamt funct6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
add $t0, $s1, $s2
lw $t0, 32($s3)
?
R‐Typ
Opcode6 Bit
Source5 Bit
Dest5 Bit
Konstante oder Adresse16 Bit
I‐Typ
Zwischenbilanz
Grundlagen der Rechnerarchitektur ‐ Assembler 24
Instruktion Format op rs rt rd shamt funct
add R 0 reg reg reg 0 32
sub R 0 reg reg reg 0 34
addi (immediate) I 8 reg reg constant
lw (load word) I 35 reg reg offset
sw (store word) I 43 reg reg offset6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
16 Bit
Beispiel: A[300] = h + A[300]
Grundlagen der Rechnerarchitektur ‐ Assembler 25
$t1 sei Basisadresse von A und h in $s2 gespeichert. Assembler‐Code?
Maschinen‐Code (der Einfachheit halber mit Dezimalzahlen)?
op rs rt rd adr/shamt funct Name Nr
$t0 8
$t1 9
$t2 10
$t3 11
$t4 12
$t5 13
$t6 14
$t7 15
Name Nr
$s0 16
$s1 17
$s2 18
$s3 19
$s4 20
$s5 21
$s6 22
$s7 23
Instruktion Format op rs rt rd shamt funct
add R 0 reg reg reg 0 32
lw (load word) I 35 reg reg offset
sw (store word) I 43 reg reg offset
Logische Operationen
Grundlagen der Rechnerarchitektur ‐ Assembler 26
Erinnerung: Logischer Shift. Beispiel:
Logischer Links‐ und Rechts‐Shift
Grundlagen der Rechnerarchitektur ‐ Assembler 27
Links‐Shift um 4 Stellen Rechts‐Shift um 4 Stellen
MIPS‐Shift‐Instruktionen sll und srl, sllv, srlv:
sll $t2,$s0,4 # $t2 = $s0 << 4 Bitssrl $t2,$s0,7 # $t2 = $s0 >> 7 Bitssllv $t2,$s0,$s1 # $t2 = $s0 << $s1 Bitssrlv $t2,$s0,$s1 # $t2 = $s0 >> $s1 Bits
Beispiel: Maschineninstruktion für obige sll Assembler‐Instruktion:
R‐Typ0 0 16 10 4 06 Bit
Opcode5 Bit
Source15 Bit
Source25 BitDest
5 BitShamt
5 BitFunct
Erinnerung: Arithmetischer Rechts‐Shift. Beispiel mit 8‐Bit:
0011 0000 1101 0111
Arithmetischer Rechts‐Shift
Grundlagen der Rechnerarchitektur ‐ Assembler 28
Rechts‐Shift um 4 Stellen Rechts‐Shift um 3 Stellen
Arithmetischer Rechts‐Shift in MIPS:
sra $t2,$s0,4 # $t2 = $s0 arithmetisch# um 4 Bits geshiftet
srav $t2,$s0,$s1 # $t2 = $s0 arithmetisch# um $s1 Bits geshiftet
Erinnerung: AND.
AND, OR, NOR und XOR
Grundlagen der Rechnerarchitektur ‐ Assembler 29
MIPS‐Instruktionen (R‐Typ), Beispiel:and $t0,$t1,$t2 # $t0 = $t1 AND $t2or $t0,$t1,$t2 # $t0 = $t1 OR $t2nor $t0,$t1,$t2 # $t0 = $t1 NOR $t2xor $t0,$t1,$t2 # $t0 = $t1 XOR $t2
MIPS‐Instruktionen (I‐Typ), Beispiel:andi $t0,$t1,0111 # $t0 = $t1 AND 0111ori $t0,$t1,1100 # $t0 = $t1 OR 1100xori $t0,$t1,1100 # $t0 = $t1 XOR 1100
Erinnerung: OR. Erinnerung NOR. Erinnerung XOR.
Es gibt gar kein NOT?!
Grundlagen der Rechnerarchitektur ‐ Assembler 30
Erinnerung NOT (auf Folie zu Zweierkomplement kurz eingeführt):
Beobachtung:
Wie kann man also „NOT($t0)“ in MIPS realisieren?
Zusammenfassung der behandelten Instruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 31
Instruktion BedeutungShift
sll rd, rs, shamt Register rd = Register rs logisch links um den Wert shamt geshiftet.
sllv rd, rt, rs Register rd = Register rs logisch links um den in Register rs gespeicherten Wert geshiftet.
srl rd, rs, shamt Register rd = Register rs logisch rechts um den Wert shamt geshiftet.
srlv rd, rt, rs Register rd = Register rs logisch rechts um den in Register rs gespeicherten Wert geshiftet.
sra rd, rs, shamt Register rd = Register rs arithmetisch rechts um den Wert shamt geshiftet.
srav rd, rt, rs Register rd = Register rs arithmetisch rechts um den in Register rsgespeicherten Wert geshiftet.
Logische
Verkn
üpfung
and rd, rs, rt Register rd = Register rs AND Register rt.
or rd, rs, rt Register rd = Register rs AND Register rt.
nor rd, rs, rt Register rd = Register rs AND Register rt.
xor rd, rs, rt Register rd = Register rsAND Register rt.
andi rt, rs, imm Register rt = Register rs AND Konstante imm
ori rt, rs, imm Register rt = Register rs AND Konstante imm
xori rt, rs, imm Register rt = Register rs AND Konstante imm
MIPS‐Assemblercode um folgende Funktion zu berechnen:
$s1 = die ersten 8 Bits von 4 * NOT($s1 AND $s2)
Schwieriges Quiz
Grundlagen der Rechnerarchitektur ‐ Assembler 32
Tipp: wir brauchen and, nor und sll
Weitere Arithmetik
Grundlagen der Rechnerarchitektur ‐ Assembler 33
Die speziellen Register lo und hi
Grundlagen der Rechnerarchitektur ‐ Assembler 34
Erinnerung: ganzzahliges Produkt von zwei n‐Bit‐Zahlen benötigt bis zu 2n Bits.
Eine MIPS‐Instruktion zur ganzzahligen Multiplikation von zwei Registern der Länge 32‐Bits benötigt damit ein Register der Länge 64 Bit, um das Ergebnis abzuspeichern.
MIPS hat für die ganzzahlige Multiplikation zwei spezielle Register, lound hi, in denen das Ergebnis abgespeichert wird:
lo : Low‐Order‐Word des Produktshi : Hi‐Order‐Word des Produkts.
Zugriff auf lo und hi erfolgt mittels mflo und mfhi. Beispiel:mflo $s1 # lade Inhalt von lo nach $s1mfhi $s2 # lade Inhalt von hi nach $s2
Ganzzahlige Multiplikation und Division
Grundlagen der Rechnerarchitektur ‐ Assembler 35
Ganzzahlige Multiplikation. Beispiel:mult $s1, $s2 # (hi,lo) = $s1 * $s2
Ganzzahlige Division. Beispiel:div $s1, $s2 # berechnet $s2 / $s1
# lo speichert den Quotienten# hi speichert den Rest
Register hi und lo können auch beschrieben werden. Beispiel:mtlo $s1 # Lade Inhalt von $s1 nach lomthi $s2 # Lade Inhalt von $s2 nach hi
Das ist sinnvoll für madd und msub. Beispiele:madd $s1,$s2 # (hi,lo)=(hi,lo)+$s1*$s2msub $s1,$s2 # (hi,lo)=(hi,lo)-$s1*$s2
Ganzzahlige Multiplikation ohne hi und lo
Grundlagen der Rechnerarchitektur ‐ Assembler 36
Es gibt eine weitere Instruktion, zur Multiplikation, die kein hi und loverwendet:
mul $s1, $s2, $s3 # $s1 = die low-order 32# Bits des Produkts von# $s2 und $s3.
Zwischenbilanz der MIPS‐Architektur
Grundlagen der Rechnerarchitektur ‐ Assembler 37
CPU
$0...
$31
ArithmeticUnit
MultiplyDivide
Registers
Lo Hi
Memory
Neu
Die speziellen Register $f01 bis $f31
Grundlagen der Rechnerarchitektur ‐ Assembler 38
MIPS unterstützt mit einem separaten FPU‐Coprozessor Gleitkommaarithmetik auf Zahlen im IEEE 754‐Single‐Precision (32‐Bit) und Double‐Precision‐Format (64 Bit).
Die MIPS‐Floating‐Point‐Befehle nutzen die speziellen 32‐Bit‐Floating‐Point‐Register (die Register des FPU‐Coprozessors):$f0, $f1, $f3, ..., $f31
Single‐Precision‐Zahlen können in jedem der Register gespeichert werden (also $f0, $f1, ..., $f31).
Double‐Precision‐Zahlen können nur in Paaren von aufeinander folgenden Registern ($f0,$f1), ($f2,$3), ..., ($f30,$f31) gespeichert werden. Zugriff erfolgt immer über die geradzahligen Register (also $f0, $f2, ..., $f30).
Floating‐Point‐Befehle
Grundlagen der Rechnerarchitektur ‐ Assembler 39
Laden/speichern von Daten in die Register $f0,...,$f31 am Beispiel:mtc1 $s1,$f3 # $f3 = $s1mfc1 $s1,$f3 # $s1 = $f3lwc1 $f3,8($s1) # $f3 = Memory[8+$s1]ldc1 $f2,8($s1) # ($f2,$f3) = Memory[8+$s1]swc1 $f3,8($s1) # Memory[8+$s1] = $f3sdc1 $f2,8($s1) # Memory[8+$s1] = ($f2,$f3)
Verschieben von Registerinhalten von $f0,...,$f31 am Beispiel:mov.s $f6,$f3 # $f6 = $f3mov.d $s4,$f6 # ($f4,$f5) = ($f6,$f7)
Floating‐Point‐Befehle
Grundlagen der Rechnerarchitektur ‐ Assembler 40
Die MIPS‐Single‐Precision‐Operationen am Beispiel:add.s $f1,$f2,$f3 # $f1 = $f2 + $f3sub.s $f1,$f2,$f3 # $f1 = $f2 - $f3mul.s $f1,$f2,$f3 # $f1 = $f2 * $f3div.s $f1,$f2,$f3 # $f1 = $f2 / $f3
Die MIPS‐Double‐Precision‐Operationen am Beispiel:add.d $f2,$f4,$f6 # ($f2,$f3) = ($f4,$f5)
+ ($f6,$f7)sub.d $f2,$f4,$f6 # ($f2,$f3) = ($f4,$f5)
- ($f6,$f7)mul.d $f2,$f4,$f6 # ($f2,$f3) = ($f4,$f5)
* ($f6,$f7)div.d $f2,$f4,$f6 # ($f2,$f3) = ($f4,$f5)
/ ($f6,$f7)
Zwischenbilanz der MIPS‐Architektur
Grundlagen der Rechnerarchitektur ‐ Assembler 41
CPU Coprocessor 1 (FPU)
$0...
$31
ArithmeticUnit
MultiplyDivide
$f0...
$f31
ArithmeticUnit
RegistersRegisters
Lo Hi
Memory
Neu
Arithmetische Operationen zusammengefasst
Grundlagen der Rechnerarchitektur ‐ Assembler 42
Instruktion Beispiel BemerkungGan
zzah
lig
mult, div,madd, msub
mult $s1, $s2 Ergebnis wird in den speziellen Registern lo und hi abgelegt.
add , sub add $s1, $s2, $s3 Operieren auf den 32 standard CPU‐Registern
addi addi $s1, $s2, 42 Ein Parameter ist eine Konstante
mflo, mfhi,mtlo, mthi
mflo $s1 ZumLaden und Speichern der Inhalte von lo‐ und hi‐Register
mul mul $s1, $s2, $s3 $s1 = 32 Low‐order Bits von $s2 * $s3
Gleitk
omma
add.s, sub.s, mul.s, div.s,
add.s $f0, $f1, $f2 Instruktionen arbeiten auf den speziellen Registern $f0,...,$f31. Single‐Precision.
add.d, sub.d, mul.d, div.d
add.d $f0, $f1, $f2 Instruktionen arbeiten auf den speziellen Registern ($f0,$f1),...,($f30,$f31). Double‐Precision.
lwc1, swc1,ldc1, sdc1
lwc1 $f0, 4($s1) Zum Laden und Speichern der Inhalte von $f0,...,$f31 über den Speicher.
mfc1, mtc2 mtc1 $s1, $f0 Zum Laden und Speichern der Inhalte von $f0,...,$f31 über die standard CPU‐Register.
mov.s, mov.d mov.s $f1, $f2 Verschieben der Inhalte von $f0,...,$f31
Einfaches Quiz
Grundlagen der Rechnerarchitektur ‐ Assembler 43
MIPS‐Assemblercode, um die Eingabe in Single‐Precision aus Fahrenheit in Celsius umzurechnen:
$f0 = (5.0 / 9.0) * (Eingabe – 32.0)
0 Eingabe4 5.08 9.0
12 32.0
…
Adresse
Inhalt (Word)
Speicher
Tipp: wir brauchen:lwc1 zum laden unddiv.s, sub.s, mul.s
Branches und Jumps
Grundlagen der Rechnerarchitektur ‐ Assembler 44
Der Program‐Counter
Grundlagen der Rechnerarchitektur ‐ Assembler 45
CPU Coprocessor 1 (FPU)
$0...
$31
ArithmeticUnit
MultiplyDivide
Registers
Lo Hi
Memory
PC
Unsere bisherigen Assemblerprogrammewaren rein sequentiell. Beispiel:0x4000000 : addi $s0, $zero, 40x4000004 : lw $s1, 0($s0)0x4000008 : lw $s2, 4($s0)0x400000c : add $s1, $s1, $s10x4000010 : ...
Welche nächste Instruktion abgearbeitetwerden soll, steht im Program‐Counter.
Zur Abarbeitung der nächsten Instruktion wirdder Program‐Counter von der CPU auf dienächste Instruktion gesetzt, d.h. $pc = $pc + 4.
Zur Abarbeitung einer Instruktion zeigt der $pcschon auf die nachfolgende Instruktion.
Der Program‐Counter ist einweiteres Register, genannt $pc.
Aus der Sequentiellen Abarbeitung springen
Grundlagen der Rechnerarchitektur ‐ Assembler 46
0x4000100 : addi $s0, $zero, 40x4000104 : lw $s1, 0($s0)0x4000108 : lw $s2, 4($s0)0x400010c : add $s1, $s1, $s10x4000110 : add $s1, $s1, $s20x4000114 : addi $s1, $zero, 10x4000118 : sw $s1, 0($s0)
0x40000204 : mult $s1, $s2 0x40000208 : div $s1, $s2 0x4000020c : mtlo $s1 0x40000210 : mthi $s20x40000214 : madd $s1,$s2
Gilt $s1 < $s2? ja
nein
Program‐Counter $pc
0x40000004 : addi $s1, $s1, 420x40000008 : addi $s2, $s2, 24
Start: ...beq register1, register2, Label3...bne register1, register2, Label1...j Label2...
Label1: ......
Label2: ......
Label3: ...
Bedingte Sprünge und unbedingte Sprünge
Grundlagen der Rechnerarchitektur ‐ Assembler 47
Ein Label (oder Sprungmarke zu deutsch) ist eine mit einem Namen markierte Stelle im Code, an die man per Branchbzw. Jump hin springen möchte.Assembler‐Syntax: „Name des Labels“ gefolgt von einem „:“.
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
32‐Bit‐Konstanten und Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 78
Immediate kann nur 16‐Bit lang sein
Grundlagen der Rechnerarchitektur ‐ Assembler 79
Erinnerung: Laden einer Konstante in ein Register
addi $t0, $zero, 200
Als Maschinen‐Instruktion:
001000 00000 01000 0000000011001000addi $zero $t0 200
Inhalt von $t0 nach Instruktionsausführung:
00000000|00000000|00000000|11001000Byte 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?
Lösung: Load‐Upper‐Immediate
Grundlagen der Rechnerarchitektur ‐ Assembler 80
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
Immediate in Branches sind nur 16 Bit lang
Grundlagen der Rechnerarchitektur ‐ Assembler 81
Erinnerung: Bedingter Sprung
bne $s0, $s1, Exit # gehe nach Exit, wenn $s0!=$s1
Als Maschinen‐Instruktion (I‐Typ):
000101 10001 10000 1010001011001000bne $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 : ...
Lösung: Branches sind PC‐Relativ
Grundlagen der Rechnerarchitektur ‐ Assembler 82
Betrachte folgendes Beispiel (Adressen seien Dezimal dargestellt):80012 : bne $s0, $s1, Exit80016 : addi $s3,$s3,180020 : j Loop80024 : Exit:
Label Exit könnte doch nur die Sprungdifferenz 80024‐80012 = 12 codieren, d.h.80012 : bne $s0, $s1, 1280016 : addi $s3,$s3,180020 : j Loop80024 : Exit:
Noch besser, codiere nur die Anzahl zu überspringender Befehle (also 3 = 12/4):80012 : bne $s0, $s1, 380016 : addi $s3,$s3,180020 : j Loop80024 : Exit:(Erinnerung: Instruktionen haben immer Word‐Länge, also 32‐Bit)
Lösung: Branches sind PC‐Relativ
Grundlagen der Rechnerarchitektur ‐ Assembler 83
Sei der Program‐Counter $pc= 80012 und $s0!=$s1 sei erfüllt:80012 : bne $s0, $s1, 380016 : addi $s3,$s3,180020 : j Loop80024 : 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?
Immediate in Jumps sind nur 26 Bit lang
Grundlagen der Rechnerarchitektur ‐ Assembler 84
Erinnerung: Unbedingter Sprung
j Exit # spinge immer nach Exit
Als Maschinen‐Instruktion (J‐Typ):
000010 10001100001010001011001000j 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 : ...
Lösung: Jumps sind Pseudo‐Direkt
Grundlagen der Rechnerarchitektur ‐ Assembler 85
Betrachte voriges Beispiel aber mit korrektem 26‐Bit Adressfeld:0x10000000 : j 0x10 # 00 0000 0000 0000 0000 0001 00000x10000004 : ......0x10000010 : ...
Der Program‐Counter sei $pc=0x10000004. Wie kommt man nach 0x10000010?
(0x10000004 = 0001 0000 0000 0000 0000 0000 0000 01000xFC000000 = 1111 1100 0000 0000 0000 0000 0000 00000x00000010 = 00 0000 0000 0000 0000 0001 0000 0x10000010 = 0001 0000 0000 0000 0000 0000 0001 0000)
Lösung: Jumps sind Pseudo‐Direkt
Grundlagen der Rechnerarchitektur ‐ Assembler 86
Auch hier wieder, nutze die Tatsache, dass Befehle immer 4 Bytes lang sind:0x10000000 : j 0x4 # 00 0000 0000 0000 0000 0000 01000x10000004 : ......0x10000010 : ...
Der Program‐Counter sei $pc=0x10000004. Wie kommt man nach 0x10000010?
(0x10000004 = 0001 0000 0000 0000 0000 0000 0000 01000xF0000000 = 1111 0000 0000 0000 0000 0000 0000 00000x00000004 = 00 0000 0000 0000 0000 0000 01000x00000010 = 0000 0000 0000 0000 0000 0001 0000 0x10000010 = 0001 0000 0000 0000 0000 0000 0001 0000)
Achtung: Programm‐Address‐Boundary
Grundlagen der Rechnerarchitektur ‐ Assembler 87
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 01000xF0000000 = 1111 0000 0000 0000 0000 0000 0000 00000x20000000 = 0010 0000 0000 0000 0000 0000 0000 0000)
Also, Sprung von 0x1??????? Nach 0x2??????? So nicht möglich.
Achtung: Programm‐Address‐Boundary
Grundlagen der Rechnerarchitektur ‐ Assembler 88
Allgemein: Sprünge in der Form beschränkt auf die 256MB Speicherblöcke0x00000000 bis 0x0FFFFFFF0x10000000 bis 0x1FFFFFFF...0xF0000000 bis 0xFFFFFFFF
Und wenn man doch über Blockgrenzen springen will?
Beispiel: Sprung aus beliebigem Speicherbereich nach 0x20002000:
Zusammenfassung der neuen Befehle
Grundlagen der Rechnerarchitektur ‐ Assembler 89
Instruktion Beispiel Beduetunglui lui $s1, 61 Lade 16‐Bit‐Wert in obere 16 Bits
von Register $s1
Quiz
Grundlagen der Rechnerarchitektur ‐ Assembler 90
80000 : Loop: sll $t1,$s3,2 # Temp-Reg $t1 = i * 480004 : 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]!=k80016 : addi $s3,$s3,1 # i = i + 180020 : j Loop # gehe wieder nach Loop80024 : 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?
Synchronisation
Grundlagen der Rechnerarchitektur ‐ Assembler 91
Data‐Race
Grundlagen der Rechnerarchitektur ‐ Assembler 92
Prozessor 1: berechne x = x + 2
lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, 2 # $t0 = $t0 + 2sw $t0, 0($s0) # speichere $t0 nach x
Gemeinsamer Speicher
Variable x
Prozessor 2: berechne x = x – 1
lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, -1 # $t0 = $t0 – 1sw $t0, 0($s0) # speichere $t0 nach x Es gelte zu Beginn: x=10
Gilt nach Durchlauf beider Code‐Abschnitte immer x=11?
Problem: Zugriff auf x ist nicht atomar
Grundlagen der Rechnerarchitektur ‐ Assembler 93
Prozessor 1: berechne x = x + 2
lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, 2 # $t0 = $t0 + 2sw $t0, 0($s0) # speichere $t0 nach x
Prozessor 2: berechne x = x – 1
lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, -1 # $t0 = $t0 – 1sw $t0, 0($s0) # speichere $t0 nach x
Zeit
Inhalt von x10
Mögliche Lösung: Atomic‐Swap
Grundlagen der Rechnerarchitektur ‐ Assembler 94
Speicher
Variable lock
1.) Speicherinhalt lock in Register $t1 kopieren2.) 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!
Mögliche Lösung: Atomic‐Swap
Grundlagen der Rechnerarchitektur ‐ Assembler 95
Prozessor 1: berechne x = x + 2
addi $t1, $zero, 1 # setze $t1 auf 1loop: swap $t1, lock # tausche $t1 und lock
bne $t1, $zero, loop # nochmal wenn $t1!=0lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, 2 # $t0 = $t0 + 2sw $t0, 0($s0) # speichere $t0 nach xswap $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 1loop: swap $t1, lock # tausche $t1 und lock
bne $t1, $zero, loop # nochmal wenn $t1!=0lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, -1 # $t0 = $t0 – 1sw $t0, 0($s0) # speichere $t0 nach xswap $t1, lock # gib lock wieder frei
Mögliche Lösung: Atomic‐Swap
Grundlagen der Rechnerarchitektur ‐ Assembler 96
Prozessor 1: berechne x = x + 2
addi $t1, $zero, 1 # setze $t1 auf 1loop: swap $t1, lock # tausche $t1 und lock
bne $t1, $zero, loop # nochmal wenn $t1!=0lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, 2 # $t0 = $t0 + 2sw $t0, 0($s0) # speichere $t0 nach xswap $t1, lock # gib lock wieder frei
Prozessor 2: berechne x = x – 1
addi $t1, $zero, 1 # setze $t1 auf 1loop: swap $t1, lock # tausche $t1 und lock
bne $t1, $zero, loop # nochmal wenn $t1!=0lw $t0, 0($s0) # lade x nach $t0addi $t0, $t0, -1 # $t0 = $t0 – 1sw $t0, 0($s0) # speichere $t0 nach xswap $t1, lock # gib lock wieder frei Zeit
x
10
lock
0
Weitere Lösung: Load Linked und Store Conditional
Grundlagen der Rechnerarchitektur ‐ Assembler 97
MIPS‐ISA hat ein Load‐Linked (ll) und Store‐Conditional (sc).Also, wie kann man mit ll und sc synchronisieren?
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 conditional1. 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.
Weitere Lösung: Load Linked und Store Conditional
Grundlagen der Rechnerarchitektur ‐ Assembler 98
Prozessor 1: berechne x = x + 2
loop: ll $t0, 0($s0) # $t0 = xaddi $t0, $t0, 2 # $t0 = $t0 + 2sc $t0, 0($s0) # x = $t0beq $t0, $zero, loop # nochmal bei failure
Gemeinsamer Speicher
Variable x
Prozessor 2: berechne x = x – 1
loop: ll $t0, 0($s0) # $t0 = xaddi $t0, $t0, -1 # $t0 = $t0 – 1sc $t0, 0($s0) # x = $t0beq $t0, $zero, loop # nochmal bei failure
Weitere Lösung: Load Linked und Store Conditional
Grundlagen der Rechnerarchitektur ‐ Assembler 99
Prozessor 1: berechne x = x + 2
loop: ll $t0, 0($s0) # $t0 = xaddi $t0, $t0, 2 # $t0 = $t0 + 2sc $t0, 0($s0) # x = $t0beq $t0, $zero, loop # nochmal bei failure
Prozessor 2: berechne x = x – 1
loop: ll $t0, 0($s0) # $t0 = xaddi $t0, $t0, -1 # $t0 = $t0 – 1sc $t0, 0($s0) # x = $t0beq $t0, $zero, loop # nochmal bei failure
Zeit
x
10
Zusammenfassung der neuen Befehle
Grundlagen der Rechnerarchitektur ‐ Assembler 100
Instruktuion Beispiel Bedeutungll 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.
Quiz für den Quizmaster
Grundlagen der Rechnerarchitektur ‐ Assembler 101
Realisiere swap Register, Adresse mit ll und sc.
Erinnerung:swap tauscht Speicher‐inhalt und Registerinhalt atomar aus.
Das Register sei $s0Die Adresse sei 0($s1)Das temporäreRegister sei $t0
Exceptions
Grundlagen der Rechnerarchitektur ‐ Assembler 102
Motivation: Behandlung von Overflows
Grundlagen der Rechnerarchitektur ‐ Assembler 103
Was war nochmal ein Overflow? Beispiel mit 8‐Bit‐Zahlen:01011010 (= 90)
+ 01100111 (=103)-----------------11000001 (=-63)
Die bisher behandelten ganzzahligen Arithmetik‐Instruktionen (z.B. add, addi 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.
Eine solche Ausnahmebehandlung wird über Exceptions realisiert.
Beispiele für Exceptions
Grundlagen der Rechnerarchitektur ‐ Assembler 104
Von außen ausgelöste Exceptions nennt man auch Interrupts
Ereignistyp Ausgelöst durchden Prozessor?
Interrupt
Anfrage eines I/O Gerätes nein XSystem‐Call jaArithmetischer Overflow jaVerwendung einer undefiniertenInstruktion
ja
Hardwarefehler ja/nein (X)... ...
Behandlung von Exceptions
Grundlagen der Rechnerarchitektur ‐ Assembler 105
Genereller Ablauf:
Exception‐Handler
Aktuell laufendes Programm
Speicher
(1) Exception
(2) Sichere $pc
(3) Springe zumException‐Handler(4) Behandle die
Exception
(5) springe ggf.wieder zurück.Rücksprung mitgesichertem $pcmöglich.
Woher weis die CPU wo der Exception‐Handler liegt?
Behandlung von Exceptions
Grundlagen der Rechnerarchitektur ‐ Assembler 106
Möglichkeit 1: Interrupt‐Vektor‐Tabelle
Speichere Adresse der aktuellen Programmausführung in einem
speziellen Register EPC.
Wähle aus der Interrupt‐Vektor‐Tabelle die Adresse des Handlers für diesen Exception‐Typ und
springe dort hin.
Exception‐Typ
Adresse des Exception‐Handlers
UndefindedInstruction
0x8000 0000
ArithmeticOverflow
0x8000 0180
... ...Handler‐Routine springt nach Exception‐Behandlung ggf. zurück in den normalen Code, d.h. an die Programminstruktion auf die EPC
zeigt.
Interrupt‐Vektor‐Tabelle
Behandlung von Exceptions
Grundlagen der Rechnerarchitektur ‐ Assembler 107
Möglichkeit 2: Cause‐Register (das ist die MIPS‐Variante)Speichere Adresse der aktuellen Programmausführung in einem
speziellen Register EPC.Speichere den Exception‐Typ in einem speziellen Cause‐Register.
Springe an die Adresse des einen Exception‐Handlers.
Der Exception‐Handler behandelt den im Cause‐Register
beschriebenen Exception‐Typ. Routine springt nach Exception‐Behandlung ggf. zurück in den normalen Code, d.h. an die Programminstruktion auf die
EPC zeigt.
Nummer Exception‐Typ (Grund)
0 Interrupt (Hardware)
4 Address‐Error (load or fetch)
5 Address‐Error (store)
6 Bus‐Error (fetch)
7 Bus‐Error (store)
8 System‐Call
9 Break‐Point
10 Reserved Instruction
11 Coprocessor Unimplemented
12 Arithmetic Overflow
13 Trap
15 Floating‐Point‐ExceptionMIPS Exception‐Codes
PC
MIPS Hardware‐Realisierung von Exceptions?
Grundlagen der Rechnerarchitektur ‐ Assembler 108
CPU Coprocessor 1 (FPU)
Coprocessor 0 (Traps and Memory)
$0...
$31
ArithmeticUnit
MultiplyDivide
$0...
$31
ArithmeticUnit
RegistersRegisters
Lo Hi
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)Registers
Memory
Es gibt einen weiteren Coprozessor
Beispiel: Aufruf des Exception‐Handlers
Grundlagen der Rechnerarchitektur ‐ Assembler 109
Coprocessor 0 (Traps and Memory)Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Exception-Handler beginnt immer hier0x80000180 : ...0x80000184 : ...
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
$pc vor Exception:
6 2 Exception‐Code für Arithmetic Overflow ist 12.
$pc nach Exception:
Beispiel: Handling der Exception
Grundlagen der Rechnerarchitektur ‐ Assembler 110
Coprocessor 0 (Traps and Memory)
40000014
Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Ein fauler Exception-Handler0x80000180 : addi $s2,$zero,0# Problem gelöst0x80000184 : eret # Rücksprung
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
$pc zur Behandlung:
$pc nach Behandlung:
Weitere Exceptions während des Handlings?
Grundlagen der Rechnerarchitektur ‐ Assembler 111
Coprocessor 0 (Traps and Memory)
40000014
Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Ein fauler Exception-Handler0x80000180 : addi $s2,$zero,0# Problem gelöst0x80000184 : eret # Rücksprung
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
$pc zur Behandlung:
$pc nach Behandlung:
Möglichkeiten, z.B.:• Exception‐Handler erzeugtselber eine Exception
• Anfrage eines IO‐Gerätes
Exceptions während des Handlings abgeschaltet
Grundlagen der Rechnerarchitektur ‐ Assembler 112
Coprocessor 0 (Traps and Memory)Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Ein fauler Exception-Handler0x80000180 : addi $s2,$zero,0# Problem gelöst0x80000184 : eret # Rücksprung
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
15 8 1 0
Exception‐Level‐Bit:0 = Exceptions werden
berücksichtigt1 = Exceptions werden
nicht berücksichtigt
Wird bei Sprung in denException‐Handler immergesetzt.Bei Aufruf von eret wirddas Bit wieder gelöscht
Status erlaubt auch das Maskieren von Interrupts
Grundlagen der Rechnerarchitektur ‐ Assembler 113
Coprocessor 0 (Traps and Memory)Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Ein fauler Exception-Handler0x80000180 : addi $s2,$zero,0# Problem gelöst0x80000184 : eret # Rücksprung
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
15 8 1 0
Interrupt‐Maske
Die Bits einer Interrupt‐Maskebestimmen welche Interrupt‐Level Exceptions erzeugen dür‐fen und welche ignoriert wer‐den.
Jeder mögliche Interrupt isteinem Interrupt‐Level zugeord‐net.
Mit Bit 0 des Status‐Registers können Interrupts generell ein‐ und ausgeschaltet werden.
Pending‐Interrupts
Grundlagen der Rechnerarchitektur ‐ Assembler 114
Coprocessor 0 (Traps and Memory)
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Exception-Handler beginnt immer hier0x80000180 : ...0x80000184 : ...
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
15 8 6 2
Exception‐Code
Registers
PendingInterrupts
Alle ankommenden Interrupts(auch ausmaskierte) setzenim Cause‐Register dasPending‐Flag ihres Interrupt‐Levels.
Wird das Masken‐Bit (oder dasgenerelle Interrupt‐Bit) späterwieder aktiviert, löst dasPending‐Bit dann den Interruptauf der CPU aus.
Zugriff auf die Coprocesor‐0‐Register
Grundlagen der Rechnerarchitektur ‐ Assembler 115
Coprocessor 0 (Traps and Memory)
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)Registers
Erinnerung: Für den FPU‐Coprozessor (Coprozessor 1) hatten wir:mfc1 : laden von FP‐Coprozessor‐Register in CPU‐Registermtc1 : laden von CPU‐Register in FP‐Coprozessor‐Register
Analoge Instruktionen für den Coprozessor 0:mfc0 : laden von Coprozessor0‐Register in CPU‐Registermtc0 : laden von CPU‐Register in Coprozessor0‐Register
Beispiele:mfc0 $s0, $13 # $s0=Coprozessor-Register 13mtc0 $13, $s0 # Coprozessor-Register 13=$s0
Beispiel für Coprocessor 0 Register‐Zugriff
Grundlagen der Rechnerarchitektur ‐ Assembler 116
Coprocessor 0 (Traps and Memory)Registers
# Es gelte $s2 = 0x7fffffff0x40000014 : add $s1,$s2,$s2 # Overflow!0x40000018 : ...
...
# Ein etwas besserer Exception-Handler# Exception auslösende Instruktion einfach überspringen0x80000180 : mfc0 $k0,$14 # $k0 = EPC0x80000184 : addi $k0,$k0,4 # $k0 = EPC+40x80000188 : mtc0 $14,$k0 # EPC=EPC+40x8000018c : eret # Rücksprung
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)
$pc zur Behandlung:
$pc nach Behandlung:
Beachte: Register‐Satz‐Konvention: $k0 und $k1 sind für OS‐Funktionenreserviert. Behandeln vonExceptions ist eine OS‐Funktion.
Traps
Grundlagen der Rechnerarchitektur ‐ Assembler 117
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 = $s1teqi $s0,42 # Trap‐Exception, wenn $s0 = 42tne $s0,$s1 # Trap‐Exception, wenn $s0 != $s1tnei $s0,42 # Trap‐Exception, wenn $s0 != 42tge $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1tgeu $s0,$s1 # Trap‐Exception, wenn $s0 >= $s1 (unsigned)tgei $s0,$42 # Trap‐Exception, wenn $s0 >= 42tgeiu $s0,42 # Trap‐Exception, wenn $s0 >= 42 (unsigned)tlt $s0,$s1 # Trap‐Exception, wenn $s0 < $s1tltu $s0,$s1 # Trap‐Exception, wenn $s0 < $s1 (unsigned)tlti $s0,$42 # Trap‐Exception, wenn $s0 < 42tltiu $s0,42 # Trap‐Exception, wenn $s0 < 42 (unsigned)
System‐Call – Mechanismus zum Aufrufen von Betriebssystem‐funktionen.
Anwendung der Instruktion syscall am Beispiel:addi $v0, $zero, 1 # Lade System‐Call‐Code in $v0
# hier System‐Call‐Code 1 für den# Systemcall print_int
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# dies führt zu einer Exception# vom Typ 8 (System‐Call)
System‐Calls
Grundlagen der Rechnerarchitektur ‐ Assembler 118
In SPIM/MARS verfügbare System‐Calls
Grundlagen der Rechnerarchitektur ‐ Assembler 119Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Zusammenfassung der neuen Befehle
Grundlagen der Rechnerarchitektur ‐ Assembler 120
Instruktuion Bedeutungeret 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, wenn $s0 = $s1 gilt.
syscall Rufe System‐Call mit der in $v0 gespeicherten Nummer auf. Parameter des System‐Callswerden in $a0 und $a1 übergeben.Beispiel: syscall gibt eine 42 auf dem Bildschirm aus, wenn $v0 = 1 (print_int) und $a0 = 42.
Unsigned Arithmetik‐Instruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 121
Zu den bisher behandelten Arithmetik‐Instruktionen gibt es auch noch unsigned Varianten, die keine Overflow‐Exception erzeugen.
Beispiel:# Es gelte $s2 = 0x7fffffff
addu $s1,$s2,$s2 # erzeugt *keine*# Overflow-Exception!
Signed und ihre Unsigend‐Varianten
Grundlagen der Rechnerarchitektur ‐ Assembler 122
SignedInstruktion
kann Overflow erzeugen
UnsignedVertreter
kann Overflow erzeugen
add ja addu neinaddi ja addiu neindiv nein divu neinmult nein multu neinmul neinmadd nein maddu neinmsub nein msubu neinsub ja subu nein
Pseudoinstruktionen, Direktiven und Makros
Grundlagen der Rechnerarchitektur ‐ Assembler 123
Motivation für Pseudoinstruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 124
Wir hatten häufiger schonaddi $s1,$zero,wert # $s1=wert
Eine Instruktion li (Load‐Immediate) wäre doch nachvollziebarerli $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 in der ISA nicht eingebaut. Kann man ja mit einem addi und dem $zeroRegister 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.
Umsetzung von Pseudoinstruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 125
Wie würde folgende move Instruktion vom Assembler umgesetzt?move $s1,$s2 # Pseudoinstruktion $s1=$s2
Wie würde folgende blt Instruktion vom Assembler umgesetzt?blt $s1,$s2, Label # Springe nach Label,
# wenn $s1<$s2 gilt
Beachte: Registerkonvention. Pseudoinstruktionen die ein Register zum Zwischenspeichern von Ergebnissen brauchen, benutzen dazu das Register $at (Assembler‐Temporary)
Einige MIPS‐Assembler Pseudoinstruktioen
Grundlagen der Rechnerarchitektur ‐ Assembler 126
Instruktion Beispiel Erklärung des Beispielblt, 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
$s1 >= $s2 (signed)li li $s1, 42 Lade Immediate 42 in $s1move move $s1, $s2 $s1 = $s2
MARS unterstützt beispielsweise neben den 155 Basisinstruktionen weitere 388 zusätzliche Pseudoinstruktionen.
Direktiven
Grundlagen der Rechnerarchitektur ‐ Assembler 127
Direktiven vereinfachen das Datenlayout eines Programms im Speicher.
Damit der Assembler ein Programm, wie auf der rechten Seite gezeigt, erzeugt, schreiben wir:.text 0x00400010li $v0, 1li $a0, 5syscall
.data 0x10001000str:.asciiz "Hallo Welt!“
0x00400010 : li $v0, 10x00400014 : li $a0, 50x00400014 : syscall
...
0x10001000 : ‘H’0x10001001 : ‘a’0x10001002 : ‘l’0x10001003 : ‘l’0x10001004 : ‘o’
...
Makros (nicht Besandteil von SPIM/MARS)
Grundlagen der Rechnerarchitektur ‐ Assembler 128
Makros definieren in einem Wort eine Folge von Instruktionen. Beim assemblieren wird jedes Auftreten des Makronamens im Code mit den Instruktionen ausgetauscht.
Beispiel:.macro print_int($arg)la $a0, int_strmov $a1, $argjal printf.end_macro
...
.dataint_str: .asciiz „%d“
Code:...print_int($t0)...
wird expandiert zu:...la $a0, int_strmov $a1, $t0jal printf...
Nochmal alles im Überblick
Grundlagen der Rechnerarchitektur ‐ Assembler 129
MIPS R2000 CPU und Coprocessoren
Grundlagen der Rechnerarchitektur ‐ Assembler 130
CPU Coprocessor 1 (FPU)
Coprocessor 0 (Traps and Memory)
$0...
$31
ArithmeticUnit
MultiplyDivide
$0...
$31
ArithmeticUnit
RegistersRegisters
Lo Hi
BadVadr ($8) Status ($12) Cause ($13) EPC ($14)Registers
Memory
PCCondition‐
Flags
Alle Instruktionsformate
Grundlagen der Rechnerarchitektur ‐ Assembler 131
opcode reg1 reg2 Sprungoffset/Wert6 Bit 5 Bit 5 Bit 16 Bit
I‐Typ(Immediate‐Typ)
opcode Adresse6 Bit 26 Bit
J‐Typ(Jump‐Typ)
opcode src1 src2 dest shamt funct6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit
R‐Typ(Register‐Typ)
32 Bit
Kompletter CPU‐Registersatz
Grundlagen der Rechnerarchitektur ‐ Assembler 132
Name Nummer Verwendung Wird über Aufrufgrenzenbewahrt?
$zero 0 Konstante 0 n.a.
$at 1 Assembler Temporary 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 Reserviert für das OS nein
$gp 28 Global‐Pointer ja
$sp 29 Stack‐Pointer ja
$fp 30 Frame‐Pointer ja
$ra 31 Return‐Adresse ja
Grundlagen der Rechnerarchitektur ‐ Assembler 133
Kategorie Unterkategorie Assembler‐Befehlsname (Mnemonic) Typ
Einfache ArithmetikRegister add, addu, sub, subu
mult, multu, div, divu, mfhi, mfloR
Immediate addi, addiu I
Logische OperationenRegister and, or, nor, xor R
Immediate andi, ori, xori I
Bedingte Sprünge beq, bne I
Unbedingte Sprüngej, jal Jjr R
Speicherzugriff
Word lw, sw, ll, sc I
Halfword lh, lhu, sh I
Byte lb, lbu, sb I
Laden von Konstanten lui I
VergleicheRegister slt, sltu R
Immediate slti, sltiu I
Shifts sll, sllv, slr, slrv, sra, srav R
Einige CPU‐Instruktionen
Einige FPU‐Instruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 134
Kategorie Assembler‐Befehlsname (Mnemonic) Typ
Branch bc1f, bc1t I
FPU‐Registerzugriff mtc1, mfc1 R
FPU‐Speicherzugriff lwc1, swc1, ldc1, sdc1 I
Single‐Precision‐Arithmetik add.s, sub.s, mul.s, div.s R
Double‐Precision‐Arithmetik add.d, sub.d, mul.d, div.d R
Verschieben von Registerinhalten der FPU mov.s, mov.d R
Single‐Precision‐Vergleiche c.x.s (x=eq, lt, le) R
Double‐Precision‐Vergleiche c.x.d (x=eq, lt, le) R
Einige Pseudoinstruktionen
Grundlagen der Rechnerarchitektur ‐ Assembler 135
Kategorie MnemonicBranches blt, bltu
bgt, bgtuble, bleubge, bgeu
32‐Bit Immediate laden liRegister kopieren move
Speicherbelegungskonvention
Grundlagen der Rechnerarchitektur ‐ Assembler 136
Reserviert
Text
Statische Daten
Heap
0x00400000
0x10000000
0x10008000
0x7ffffffc
0x00000000
$pc
$sp
$gp
Stack
Hohe
Adresse
Niedrige Ad
resse
$sp
$fp
Procedure‐Frame
SavedRegister
Lokale Variablen
UnbenutzerSpeicher
BenutzerSpeicher
Argument 5
Argument 6
Immediate‐Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 137
Beispiel:
addi $s0, $s2, 42 # $s0 = $s2 + 42
(Instruktionstyp: I‐Typ)
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Register‐Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 138
Beispiel:
add $s0, $s2, $s4 # $s0 = $s2 + $s
(Instruktionstyp: R‐Typ)
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Basis‐Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 139
Beispiel:
lw $t0, 12($s0) # $t0 = Inhalt der Speicherstelle $s2+12
(Instruktionstyp: I‐Typ)
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
PC‐Relative‐Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 140
Beispiel:
beq $s0, $s2, Label # wenn $s0 = $s2 dann springe nach# Label.
(Instruktionstyp: I‐Typ)(Beachte: Address speichert die Anzahl zu überspringender Words und nicht die Bytes)
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Pseudodirekte Adressierung
Grundlagen der Rechnerarchitektur ‐ Assembler 141
Beispiel:
j Label # Springe nach Label
(Instruktionstyp: J‐Typ)(Beachte: Address speichert die untere Basis des PC in Words und nicht in Bytes)
Bildquelle: David A. Patterson und John L. Hennessy, „Computer Organization and Design“, Fourth Edition, 2012
Eine Instruktion haben wir noch vergessen
Grundlagen der Rechnerarchitektur ‐ Assembler 142
nop # tue nichts
So das war‘s:li $v0,10syscall
Zusammenfassung und Literatur
Grundlagen der Rechnerarchitektur ‐ Assembler 143
Zusammenfassung• Assembler als Schnittstelle zwischen höheren Sprachen und den Maschinen‐
Instruktionen– Assembler übersetzt menschenlesbare Assembler‐Instruktionen in
maschinenlesbare Maschineninstruktionen (Zahlen)– Assembler kann die ISA mit sinnvollen Pseudoinstruktionen erweitern
• Wir haben nochmals deutlich das Prinzip des Stored‐Program gesehen– Instruktionen sind ununterscheidbar von Zahlen– Instruktionen liegen im gewöhnlichen Datenspeicher
• Programmieren in Assemblersprache macht alles schneller?– Wenn dann nur kritischste Teile– Compiler kennt die „Intention“ des Programmes nicht– Compiler optimieren heutzutage aber sehr gut;
meist besser als der gewöhnliche Assemblerprogrammierer– Höhere Sprache bedeutet weniger Codezeilen und damit auch schnellere
Programmierzeit– Höhere Sprache bedeutet auch, dass Code schneller auf neue Architektur portierbar
ist• Der Speicher speichert lediglich Bits.
Interpretation des Inhalts hängt von der Instruktion ab die darauf zu greift• Programmieren lernt man nicht durch zuhören. Übung mach den Meister!
Grundlagen der Rechnerarchitektur ‐ Assembler 144
Literatur[PattersonHennessy2012] David A. Patterson und John L. Hennessy, „Computer
Organization and Design“, Fourth Edition, 20122.1 Introduction2.2 Operations of the Computer Hardware2.3 Operands of the Computer Hardware2.5 Representing Instructions in the Computer2.7 Instructions for Making Decisions2.8 Supporting Procedures in Computer Hardware2.9 Communicating with People2.10 MIPS Addressing for 32‐Bit Immediates and Adresses2.11 Parallelism and Instructions: Synchronization4.9 ExceptionsB.1 IntroductionB.2 AssemblersB.5 Memory UsageB.6 Procedure Call ConventionB.7 Exceptions and InterruptsB.9 SPIMB.10 MIPS R2000 Assembly Language
Grundlagen der Rechnerarchitektur ‐ Assembler 145