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
© Copyright 2024 ExpyDoc