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
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Befehlszähler | das Register mit der Adresse des nächsten Befehls | pc |
| Befehlsregister | hier liegt der gerade geholte Befehl | |
| Holen | den nächsten Befehl aus dem Speicher lesen | |
| Decodieren | den Befehl in seine Felder zerlegen | |
| Ausführen | die Arbeit tun, die der Befehl verlangt | |
| Opcode | das 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
cd ~/archHier 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
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.sHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Assemblieren
riscv64-linux-gnu-as takt.s -o takt.oHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Linken
riscv64-linux-gnu-ld takt.o -o taktHier 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
qemu-riscv64 -d in_asm ./taktHier 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
| Bits | Feld | Wert | Bedeutung |
|---|---|---|---|
| 31 bis 25 | funct7 | 0100000 (32) | Subtrahieren, nicht addieren |
| 24 bis 20 | rs2 | 01011 (11) | Zweite Eingabe: x11, a1 |
| 19 bis 15 | rs1 | 01010 (10) | Erste Eingabe: x10, a0 |
| 14 bis 12 | funct3 | 000 | Addieren oder subtrahieren |
| 11 bis 7 | rd | 01010 (10) | Ergebnis nach x10, a0 |
| 6 bis 0 | opcode | 0110011 (51) | Rechnen mit zwei Registern |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Der Befehl als 32 Bits
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
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
qemu-riscv64 -one-insn-per-tb -d exec,nochain ./taktHier 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
gcc -O2 -o loop loop.cHier 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
gdb -batch -iex 'set debuginfod enabled off' -ex 'break main' -ex run -ex 'info registers pc' -ex stepi -ex 'info registers pc' ./loopHier 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?