fakultät für informatik - Lehrstuhl für Rechnertechnik und

FAKULTÄT FÜR INFORMATIK
TECHNISCHE UNIVERSITÄT MÜNCHEN
Lehrstuhl für Rechnertechnik und Rechnerorganisation
Prof. Dr. Arndt Bode
Einführung in die Rechnerarchitektur
Wintersemester 2015/2016
Tutorübung 7 – MI (1) – Lösungsvorschläge
30.11–04.12.2015
Aufgabe 1.1 (Von-Neumann-Komponenten)
•
•
•
•
Speicherwerk: Hauptspeicher, Hintergundspeicher, Caches
Rechenwerk: Mikroprozessor, Coprozessoren, evtl. z. B. auch Grafikkarte
Leitwerk: Mikroprozessor
E/A-Werk:
– verschiedene Busse, z. B. ISA, PCI (PCI-X, PCI Express), IDE, SCSI, Infiniband
– darüber angebunden:
∗ Bildschirm, Drucker, Maus, Tastatur usw.
∗ Hintergrundspeicher, Wechseldatenträger, Netzwerkkarte, Modem
• Nicht einordnen lassen sich: Mehrkernsysteme und Systeme mit mehreren Prozessoren
(Die von-Neumann-Architektur sieht nur ein Leitwerk vor.)
Aufgabe 1.2 (Von-Neumann-Prinzipien)
Warum stehen Programm und Daten bei einer von-Neumann-Maschine im selben Speicher?
• Sonst evtl. Programmspeicher voll, aber in Datenspeicher noch Platz (oder umgekehrt).
Unter Umständen kann die Maschine Problem nicht lösen, obwohl noch Speicher frei.
• Programm kann als Datum für anderes Programm angesehen werden. Dies ist z. B. Voraussetzung für Übersetzer.
• Möglichkeit von sich selbst modifizierenden Programmen bzw. Programmen mit Codegeneratoren, deren Code nach Generierung ausgeführt wird. Heutzutage zu finden in sogenannten JIT-tern“ (Just-In-Time Compilern), die Code direkt vor der Ausführung aus
”
einem Zwischencode generieren. JIT-Compiler sind in jeder JavaVM und in .NET zu finden, werden inzwischen aber auch bei Ausführung von Skriptsprachen benutzt (Python,
Ruby, aber auch für JavaScript in jedem aktuellen Webbrowser). Selbstmodifizierender
Code ist auch beim Laufzeitbinden von Programmen mit Funktionsbibliotheken ( Shared
”
Libraries“) zu finden.
1
Aufgabe 2.1 (Endliche Automaten)
λ(z1) = B1; λ(z2) = B2; λ(z3) = nichts;
Aufgabe 2.2 (Zustandsübergangsfunktion)
δ=
A
G
!G
z1
z2
z1
z1
z2
z2
z3
z1
z3
z1
z1
z1
Aufgabe 3.1 (Maschinenbefehlsformat)
• Arithmetische Befehle 01, 05, 06
• Speicherzugriffsbefehle 0E, 0F
• Sprungbefehle A1, A2
Aufgabe 3.2 (Befehlslängen)
Einige Befehle haben nur Register als Operanden. Es gibt nur 16-Register, d. h. Operandenauswahl ist ld(16) = 4 Bit. Ein Befehl braucht also 8 Bit für Opcode, 2 · 4 Bit für Operand.
Insgesamt 16 Bit.
Einige Befehle besitzen entweder eine 16-Bit Adresse oder einen 16-Bit Direktoperanden. Diese
Befehle brauchen also 8 Bit für Opcode, 16 Bit für Operanden, insgesamt also mindestens 24
Bit. Bei einer Von-Neumann-Maschine gilt: Alle Zellen im Hauptspeicher haben die gleiche
Größe (hier 16 Bit). Es müssen also mindestens 2 Zellen verwendet werden, d. h. 32 Bit. Ein
32-Bit Befehl kann aber zusätzlich noch 2 Register als Operanden verwenden. Z.B. verwenden
die Befehle 0E unf 0F noch jeweils 1 Register als Operand. Die letzten 4 Bit bleiben in beiden
Fällen unberücksichtigt und sind daher verschwendet.
Aufgabe 3.3 (Disassemblieren)
MOV 0x0000, r2
schleife: CMP r0
JZ ende
ADD r1, r2
DEC r0
JMP schleife
ende:
...
Hinweis: Zuerst Opcodes entziffern (mit Beachtung der Befehlslänge), dann die Registeroperanden, und schließlich die Direktoperanden (inklusive Sprungziele). Es zeigt sich, dass einige
Bits aus dem Speicherauszug irrelevant für die Interpretation als Assemblerprogramm sind.
2
Aufgabe 3.4 (Wirkung)
R2 = R1 * R0
Aufgabe 3.5 (Aufgaben der Werke)
Schritt 1-3 im folgenden identisch (IFETCH), Rest ist Implementierung des Maschinenbefehls.
CMP RB
1.
2.
3.
4.
5.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Rechenwerk: berechne 0 + RB, setze Zeroflag entsprechend
Rücksprung zu IFETCH
Schritte 4 und 5 gleichzeitig möglich.
ADD RA, RB
1.
2.
3.
4.
5.
6.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Rechenwerk: berechne RA + RB, setze Flags entsprechend
Rechenwerk: speichere Ergebnis in RB
Rücksprung zu IFETCH
Schritte 4 bis 6 gleichzeitig möglich.
DEC RB
1.
2.
3.
4.
5.
6.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Rechenwerk: berechne RB - 1, setze Flags entsprechend
Rechenwerk: speichere Ergebnis in RB
Rücksprung zu IFETCH
Schritte 4 bis 6 gleichzeitig möglich.
3
MOV imm, RB
1.
2.
3.
4.
5.
6.
7.
8.
9.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere imm-Wert (Datenbus)
Rechenwerk: berechne imm + 0, Flags werden nicht geändert
Rechenwerk: Speichere Ergebnis in RB
Leitwerk: inkrementiere Befehlszähler
Rücksprung zu IFETCH
Schritt 4 nur einzeln, da Schritt 5 auf den Speicher warten muss. Schritte 5 bis 9 gleichzeitig
möglich.
MOV RA, addr
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere addr-Wert (Datenbus)
Rechenwerk: sende addr an Speicher (Adressbus)
Rechenwerk: berechne RA + 0, Flags werden nicht geändert
Rechenwerk: sende Ergebnis an Speicher (Datenbus)
Speicher: speichere Ergebnis
Leitwerk: inkrementiere Befehlszähler
Rücksprung zu IFETCH
Schritt 4 nur einzeln, da Schritt 5 auf den Speicher warten muss. Schritt 5 einzeln, da Schritt
6 neuen Speicherzugriff (Schreiben) startet. Schritt 6 einzeln, da Schritt 7 auf Speicher warten
muss, um zu schreibendes Datum entgegennehmen zu können. Schritte 7 bis 11 gleichzeitig
möglich.
JZ addr
1.
2.
3.
4.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
falls Zeroflag nicht gesetzt:
(a) Leitwerk: inkrementiere Befehlszähler
(b) Rücksprung zu IFETCH
5. Sonst:
(a)
(b)
(c)
(d)
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere addr-Wert (Datenbus)
Leitwerk: setze Befehlszähler auf addr
Rücksprung zu IFETCH
4
Schritt 4 (Abfrage) einzeln, da 4(a) in eigenem Kontrollflusspfad ausgeführt werden soll (nur,
wenn Z nicht gesetzt). Schritte 4(a) und 4(b) gleichzeitig möglich. Schritt 5(a) einzeln, da 5(b)
auf Speicher wartet. Schritte 5(b) bis 5(d) gleichzeitig.
JMP addr
1.
2.
3.
4.
5.
6.
7.
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere Befehl (Datenbus)
Leitwerk: inkrementiere Befehlszähler
Leitwerk: sende Befehlszähler an Speicher (Adressbus)
Speicher: liefere addr (Datenbus)
Leitwerk: setze Befehlszähler auf addr
Rücksprung zu IFETCH
Schritt 4 einzeln, da 5 auf Speicher wartet. Schritte 5 bis 7 gleichzeitig.
5