Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Wie ein Prozessor jeden Befehl abarbeitet (Befehlszyklus)

Nach dieser Lektion: Ich kann Holen, Decodieren und Ausführen für einen Befehl verfolgen.

Lektion, 50 Min.10 BefehleLab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Drei Milliarden Mal in der Sekunde

Der Laptop am Empfang einer Arztpraxis macht etwa drei Milliarden Schritte in der Sekunde. Jeder davon folgt demselben kleinen Ablauf.

Den nächsten Befehl lesen, herausfinden, was er verlangt, es tun und weitermachen. Wer diesen Ablauf für einen Befehl verfolgen kann, kann ihn für jedes Programm verfolgen.

Am Ende dieser Lektion

Notiz

Ich kann Holen, Decodieren und Ausführen für einen Befehl verfolgen.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Befehlszählerdas Register mit der Adresse des nächsten Befehlspc
Befehlsregisterhier liegt der gerade geholte Befehl
Holenden nächsten Befehl aus dem Speicher lesen
Decodierenden Befehl in seine Felder zerlegen
Ausführendie Arbeit tun, die der Befehl verlangt
Opcodedas Feld, das sagt, welche Art von Befehl es ist

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Ein Ablauf, immer wieder

Der Befehlszähler, pc, hält die Adresse des nächsten Befehls. Beim Holen liest der Prozessor das Wort an dieser Adresse ins Befehlsregister und zählt 4 zu pc dazu.

Beim Decodieren zerlegt er das Wort in Felder: welche Art von Befehl, welche Register. Beim Ausführen tut er die Arbeit und schreibt das Ergebnis zurück. Dann holt er wieder.

In den Architektur-Ordner wechseln

Befehl
cd ~/arch

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ein Programm, das 9 minus 4 rechnet

Befehl
printf '.globl _start\n_start:\n  li a0, 9\n  li a1, 4\n  sub a0, a0, a1\n  li a7, 93\n  ecall\n' > takt.s

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Assemblieren

Befehl
riscv64-linux-gnu-as takt.s -o takt.o

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Linken

Befehl
riscv64-linux-gnu-ld takt.o -o takt

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Dem Emulator beim Holen zusehen

Befehl
qemu-riscv64 -d in_asm ./takt

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Was der Emulator geholt hat

qemu hat fünf Wörter aus dem Speicher geholt und jedes decodiert. Jede Zeile zeigt die Adresse, das Wort in Hex und den decodierten Befehl.

Die Adressen steigen um 4, von 0x000100b0 bis 0x000100c0, weil jeder Befehl hier 4 Bytes hat. Beachten Sie: li ist verschwunden. Der Prozessor sieht nur addi a0,zero,9.

Decodieren zerlegt das Wort in Felder

Ein sub besteht aus 32 Bits in sechs Feldern. Die untersten sieben Bits sind der Opcode: 51, also Rechnen mit zwei Registern.

Dann folgen fünf Bits für rd, das Zielregister, drei Bits für Details und je fünf Bits für die Eingaben rs1 und rs2. Die obersten sieben Bits, funct7, unterscheiden sub von add. a0 ist x10 und a1 ist x11.

Beispiel: die Felder von 40b50533

BitsFeldWertBedeutung
31 bis 25funct70100000 (32)Subtrahieren, nicht addieren
24 bis 20rs201011 (11)Zweite Eingabe: x11, a1
19 bis 15rs101010 (10)Erste Eingabe: x10, a0
14 bis 12funct3000Addieren oder subtrahieren
11 bis 7rd01010 (10)Ergebnis nach x10, a0
6 bis 0opcode0110011 (51)Rechnen mit zwei Registern

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Der Befehl als 32 Bits

Befehl
python3 -c "print(format(0x40b50533, '032b'))"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Opcode, rd, rs1, rs2 und funct7 herausziehen

Befehl
python3 -c "print(0x40b50533 & 127, (0x40b50533 >> 7) & 31, (0x40b50533 >> 15) & 31, (0x40b50533 >> 20) & 31, 0x40b50533 >> 25)"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ausführen, dann rückt pc weiter

Beim Ausführen geschieht die Arbeit: eine Subtraktion, ein Laden, ein Vergleich. Die meisten Befehle lassen pc dort, wo das Holen ihn hingesetzt hat. Eine genommene Verzweigung schreibt stattdessen eine neue Adresse in pc. Mehr ist ein Sprung nicht.

Mit -d exec druckt qemu eine Zeile für jeden ausgeführten Befehl. Die zweite Zahl in den eckigen Klammern ist der RISC-V-pc.

Eine Zeile je ausgeführtem Befehl

Befehl
qemu-riscv64 -one-insn-per-tb -d exec,nochain ./takt

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ein häufiger Fehler

Warnung

Viele glauben, der Befehlszähler zähle, wie viele Befehle gelaufen sind. Er zählt gar nichts. Er hält eine Adresse: wo der nächste Befehl liegt. In einer Schleife kehrt er immer wieder zu denselben Adressen zurück.

Den eigenen Prozessor schrittweise verfolgen

gdb kann ein Programm dieser Maschine anhalten und Befehl für Befehl ausführen. Von Hand getippt wartet es auf Sie. Mit -batch und einer Liste von Kommandos arbeitet es die Liste ab und endet, also passt es in einen Run.

Der Run hält bei main, zeigt pc, führt mit stepi einen Befehl aus und zeigt pc noch einmal. Auf einem Arm-Prozessor rückt die Adresse um 4. Auf x86 sind Befehle 1 bis 15 Bytes lang, der Schritt ist also verschieden.

Das Programm loop des Labs bauen

Befehl
gcc -O2 -o loop loop.c

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Bei main anhalten und einen Schritt gehen

Befehl
gdb -batch -iex 'set debuginfod enabled off' -ex 'break main' -ex run -ex 'info registers pc' -ex stepi -ex 'info registers pc' ./loop

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Weiterführend: die Befehle einer Schleife zählen

Bauen Sie gerade.s aus der Lektion über Befehle, aber mit li t1, 12. Rechnen Sie vorher aus, wie viele Befehle laufen: drei vor der Schleife, drei je Durchlauf, fünf Durchläufe und zwei danach.

Tippen Sie dann qemu-riscv64 -one-insn-per-tb -d exec,nochain ./gerade 2>&1 | wc -l und vergleichen Sie. Welche Adressen erscheinen fünfmal?

Über dieses Lab und seinen Quellcode: Lab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.