Easy RISC-V: Interaktives Einstiegstutorial für RISC-V-Assembly-Programmierung
(dramforever.github.io)- Ein interaktives Tutorial, mit dem man RISC-V-Assembly Schritt für Schritt über einen im Webbrowser lauffähigen Emulator lernen kann; inspiriert von Nick Morgans Easy 6502
- Behandelt die 45 Basisbefehle des RV32I_Zicsr-Befehlssatzes sowie die Kernkonzepte der privilegierten Architektur und vermittelt einen für Compiler-Ziele hinreichend vollständigen Befehlssatz
- Bietet Grundlagen der Assembly-Programmierung wie Arithmetik-/Logikoperationen, Verzweigungen/Sprünge, Speicherzugriffe, Funktionsaufrufkonventionen und Stack-Verwaltung zusammen mit Praxisbeispielen
- Erklärt mit realem Code den Wechsel zwischen Privilegstufen zwischen Machine Mode und User Mode, die Ausnahmebehandlung sowie die Manipulation von CSRs (Control and Status Registers)
- Das Endziel des Tutorials ist das eigenständige Schreiben eines winzigen Betriebssystems mit Unterstützung für System Calls und Ausnahmebehandlung, sodass sich der gesamte Ablauf der Low-Level-Entwicklung mit RISC-V nachvollziehen lässt
Aufbau des Tutorials und wichtigste Lerninhalte
Grundlegende Befehle und Prozessorkonzepte
- Prozessorzustand: Verständnis von Program Counter (
pc), 31 allgemeinen Registern (x1~x31) und dem speziellen Zero-Register (x0) - Arithmetische Befehle: Lernen von Addition/Subtraktion und dem Verhalten bei Overflow mit
add,addi,subusw. - Bitoperationen: Übungen zu logischen Bitoperationen und Shift-Befehlen wie
and,or,xor,sll,srl,sra - Vergleichsbefehle: Umsetzung von Logik für vorzeichenbehaftete/vorzeichenlose Ganzzahlvergleiche und Bedingungen mit
slt,sltuusw.
Kontrollfluss und Speicher
- Verzweigungen und Sprünge: Mechanismen für bedingte/unbedingte Verzweigungen und Funktionsaufrufe mit
beq,bne,blt,jal,jalrusw. - Speicherzugriff: Load-/Store-Operationen für Word, Halfword und Byte mit
lw,sw,lb,lh,sb,sh - Memory-Mapped I/O: Verständnis dafür, wie über Lese-/Schreibzugriffe auf bestimmte Adressen mit externen Geräten kommuniziert wird
- Positionsunabhängiger Code: Techniken zum Schreiben von relocatablem Code mit dem
auipc-Befehl und PC-relativer Adressierung
Funktionen und Aufrufkonventionen
- Register-Aliasse: Rollen von
a0~a7(Argumente),s0~s11(gesichert),t0~t6(temporär),ra(Rücksprungadresse),sp(Stack Pointer) usw. - Stack-Verwaltung: Muster zum Sichern von Registern beim Funktionseintritt, Reservieren/Freigeben von Stack-Speicher sowie zum Bewahren und Wiederherstellen der Rücksprungadresse
- Rekursive Funktionen: Praxis mit rekursiven Aufrufen und Stack-Frame-Verwaltung anhand einer Fibonacci-Implementierung
Privilegierte Architektur und Betriebssystem
- Privilegstufen: Unterschiede zwischen Machine Mode (Level 3) und User Mode (Level 0) sowie deren Isolationsmechanismen
- CSR-Befehle: Lesen/Schreiben von Kontrollregistern und Manipulation von Bitfeldern mit
csrrw,csrrs,csrrcusw. - Ausnahmebehandlung: Prüfen von Ausnahmeinformationen und Schreiben von Handlern mit den CSRs
mcause,mepc,mtval,mstatus - Moduswechsel: Eintritt in den User Mode und Rückkehr mit dem
mret-Befehl sowie Context Switching mitmscratch
Abschlussprojekt: winziges OS
- Implementierung von System Calls: Trap von User Mode in Machine Mode mit dem
ecall-Befehl, umputchar-/exit-Funktionen bereitzustellen - Sichern/Wiederherstellen von Registern: Vollständige Struktur eines Trap-Handlers, der alle allgemeinen Register auf dem Stack sichert und restauriert
- Logik der Ausnahmebehandlung: Bestimmung der Ausnahmeursache mit
mcause, Dispatch nach System-Call-Nummer (a7) und Ausgabe von Fehlermeldungen - Ausführbarer Code: Vollständiger Code für Einstieg und Rückkehr des OS-Kernels, direkt im Web-Emulator ausführbar
Referenzmaterialien und Lizenz
- Tutorial und Code stehen vollständig unter CC0 Public Domain oder der 0-clause BSD-Lizenz
- Original und Code-Repository: https://github.com/dramforever/easyriscv
- Für das Lernen von RISC-V geeignet für Bildung, Forschung und den Aufbau von Simulationsumgebungen
2 Kommentare
Wow
Ich habe mich für RISC-V-Assembly interessiert, das man im Fachunterricht lernt ... Selbst wenn ich mir extra ein Buch kaufen und lesen wollte, habe ich nur ARM-Architektur gesehen und nichts zu RISC-V, also habe ich gerade überlegt, was ich mir ansehen sollte. Da scheint es, als hätte ich eine richtig gute Ressource zum Lernen gefunden.
Vielen Dank!!!
Hacker-News-Kommentare
Wirklich ein sehr guter Leitfaden.
Ich wünschte, der Emulator-Bildschirm aus dem ersten „My first RISC-V assembly program“ stünde ganz am Anfang des Leitfadens. Sonst könnten Leser trotz des Titels „interactive“ denken, es handle sich nur um eine textbasierte Einführung.
Ich werde mir in den nächsten Tagen noch mehr Zeit dafür nehmen. Ich interessiere mich ziemlich für RISC-V und denke, dass es eine vielversprechende Zukunft hat.
Falls ein KI-Experte das hier liest: Es wäre wirklich großartig, wenn jemand Core War mit einer Plattform wie Replit oder Lovable noch einmal in RISC-V-Assembly umsetzen würde.
Ich habe Assembly mit Patterson und Hennessys Computer Organization And Design gelernt, und man merkt deutlich, wie viel RISC-V von MIPS übernommen hat.
An beiden ISAs waren dieselben Leute beteiligt, und man hat Fehler wie den delay slot von MIPS vermieden. Wenn man Erfahrung mit MIPS hat, fühlt sich RISC-V-Assembly fast genauso an.
Ich schaue mir derzeit auch AArch64 an; es ist weniger elegant als RISC-V, aber das praktische Design ist beeindruckend. Manchmal frage ich mich sogar, ob RISC-V nicht zu konservativ entworfen wurde.
Ich habe selbst TCP Socket in RISC-V Assembly geschrieben.
Dabei habe ich die RV64I-ISA verwendet, und man muss das Konzept der linker relaxation verstehen. Referenzmaterial habe ich ebenfalls beigefügt.
Im Abschnitt über Position Independence scheint es einen Fehler zu geben.
Ich frage mich, ob im Beispielcode nicht
luistattauipcverwendet werden müsste, damit 0x3004 herauskommt.luierzeugt eine absolute Adresse, während die Kombinationauipc/addieine positionsunabhängige Adresse erzeugt. Wennauipcan Adresse 0 steht, ist das Ergebnis identisch, tatsächlich wird aber ein Wert addiert, der von der Adresse der aktuellen Instruktion ausgeht.Die interaktive Gestaltung dieses Inhalts ist wirklich hervorragend.
Als C/C++-Entwickler fand ich Assembly immer schwierig, aber durch diese Herangehensweise ist es viel klarer geworden.
lwkönnte manload4schreiben, stattjeinfachjump— wir leben schließlich nicht mehr im Zeitalter der Lochkarten, also verstehe ich nicht, warum alles so kurz sein muss.Dieser Artikel hat mir wieder Lust auf Low-Level-Programmierung gemacht.
Ich habe im Studium der Mechatronik mit C und Assembly auf Mikrocontrollern gearbeitet, bin inzwischen aber in die Webentwicklung gewechselt.
Mich würde interessieren, ob es vertrauenswürdige Ressourcen gibt, um RISC-V-Hardware zu lernen. Wenn möglich, würde ich das gern mit Rust machen.
Außerdem gab es noch ein Rust-basiertes OS-Tutorial, aber den Link finde ich gerade nicht.
Wenn du echte Hardware willst, empfehle ich neorv32 — die Dokumentation ist gut: offizielle Dokumentation, GitHub-Repository. Das ist ein in VHDL geschriebener RISC-V-Kern.
RISC-V-Hardware ist leicht zu bekommen.
Siehe RISC-V on Raspberry Pi Pico 2.
Siehe Kickstarter-Seite.
Und wenn man RISC-V zusammen mit FPGA behandeln möchte, gibt es auch PolarFireSoC. Das ist deutlich günstiger als AMD/Xilinx und durchaus brauchbar. Die Entwicklungsumgebung ist etwas altmodisch, aber schnell, und die Dokumentation ist verstreut, aber das meiste findet sich irgendwo.
Link zum Entwicklungskit
Lustig ist, dass das Entwicklungsboard billiger ist als der Chip selbst.
Zufällig haben wir diese Woche in einer C-Vorlesung gerade mit dem Kapitel Einführung in Assembly begonnen, und ich dachte, mit RISC-V könnte man die Unterschiede zwischen CPUs elegant umgehen.
Aber offenbar hat schon jemand genau dafür perfekt aufbereitetes Material erstellt. Vielen Dank dafür.
Im Beispiel „Wenn man von 0 subtrahiert, wird das Ergebnis negativ“ ist das Negative von 0x123 gleich 0xfffffedd.
Es hieß, der Emulator zeige 0xfffffccd an, aber tatsächlich ist 0xfffffedd korrekt. Ich habe es selbst nachgerechnet, und der Emulator liegt richtig.
Wer einen guten RISC-V-Emulator sucht, dem empfehle ich RARS.