Great guide!
I think the first "My first RISC-V assembly program" emulator plane should be right at the beginning of the guide. Otherwise, casual readers might think that this is a text-only introduction (despite the word "interactive" in the title).
Will spend more time on it in the coming days. I am quite interested in RISC-V and I think that it might have a bright future ahead.
If any AI expert is reading this now, please use Replit or Lovable or something like that to re-create "Core War" [0] with RISC-V assembly. It would be GREAT.
I was going to add to your comment with some snarky rejoinder like "brain, is that a new agent from OpenAI?" or "we are all vibecoders now" or simply "ain't nobody got time for that".
But then I got to wondering about the OP's statement that they would specifically like someone to create this with AI. It strikes me both as silly as saying "if you're good at using Visual Studio, could you do this?", because AI tools are just tools now, and those who want to use them don't need to be prompted... but also somehow fundamentally different.
OP, what was on your heart that caused you to phrase it that way?
I'm still busy building my ox-bike wagon. Soon I'll start pedaling around the country offering tea, and hand written (my brain to my keyboard ™) software.
Having learned assembly with the book "Computer Organization And Design" from Patterson and Hennessy, it really shows how much RISC-V takes from MIPS. After all they share some of the people involved in both ISAs and they have learned from the MIPS mistakes (no delay slots!). Basically if you come from a MIPS the assembly is very very similar, as it was my case.
Now that book is also available with a RISC-V edition, which has a very interesting chapter comparing all different RISC ISAs and what they do differently (SH, Alpha, SPARC, PA-RISC, POWER, ARM, ...),...
However I've been exploring AArch64 for some time and I think it has some very interesting ideas too. Maybe not as clean as RISC-V but with very pragmatic design and some choices that make me question if RISC-V was too conservative in its design.
> However I've been exploring AArch64 for some time and I think it has some very interesting ideas too. Maybe not as clean as RISC-V but with very pragmatic design and some choices that make me question if RISC-V was too conservative in its design.
Not enough people reflect on this, or the fact that it's remarkably hazy where exactly AArch64 came from and what guided the design of it.
AArch64 came from AArch32. That's why it keeps things like condition codes, which are a big mistake for large out-of-order implementations. RISC-V sensibly avoid this by having condition-and-branch instructions instead. Otherwise, RISC-V is conservative because it tries to avoid possibly encumbered techniques. But other than that it's remarkably simple and elegant.
I get the same impression w.r.t. RISC-V v. MIPS similarities, just from my (limited) exposure to Nintendo 64 homebrew development. Pretty striking how often I was thinking to myself “huh, that looks exactly like what I was fiddling with in Ares+Godbolt, just without the delay slots”.
Instructions are more easily added than taken away. RISC-V started with a minimum viable set of instructions to efficiently run standard C/C++ code. More instructions are being added over time, but the burden of proof is on someone proposing a new instruction to demonstrate what adding the instruction costs and how much benefit it brings and in what real-world applications.
> Instructions are more easily added than taken away.
That's not saying much, it's basically impossible to remove an instruction. Just because something is easier than impossible doesn't mean that it's easy.
And sure, from a technical perspective, it's quite easy to add new instructions to RISC-V. Anyone can draft up a spec and implement it in their core.
But if you actually want wide-spread adoption of a new instruction, to the point where compilers can actually emit it by default and expect it to run everywhere, that's really, really hard. First you have to prove that this instruction is worthwhile standardizing, then debate the details and actually agree on a spec. Then you have to repeat the process and argue the extension is worth including in the next RVA profile, which is highly contentious.
Then you have to wait. Not just for the first CPUs to support that profile. You have to wait for every single processor that doesn't support that profile to become irrelevant. It might be over a decade before a compiler can safely switch on that instruction by default.
For the uninitiated in AArch64, are there specific parts of it you're referring to here? Mostly what I find is that it lets you stitch common instruction combinations together, like shift + add and fancier adressing. Since the whole point of RISC-V was a RISC instruction set, these things are superfluous.
My memory is a bit fuzzy but I think Patterson and Hennessy‘s “Computer Architecture: A Quantitative Approach” had some bits that were explicitly about RISC-V, and similarities to MIPS. Unfortunately my copy is buried in a box somewhere so I can’t get you any page numbers, but maybe someone else remembers…
Henessey and Patterson "Computer Architecture: A Quantitative Approach" has 6 published editions (1990, 1996?, 2003, 2006, 2011, 2019) with the 7th due November 2025. Each edition would have a varying set of CPUs as examples for each chapter. For example, the various chapters in the 2nd edition has sections on the MIPS R4000 and the PowerPC 620, while the 3rd edition has sections on the Trimedia TM32, Intel P6, Intel IA-64, Alpha 21264, Sony PS2 Emotion Engine, Sun Wildfire, MIPS R4000, and MIPS R4300. From what I could figure out via web searches, the 6th edition has RISC-V in the appendix, but the 3rd through 5th editions has the MIPS R4000.
Patterson and Hennessy "Computer Organization and Design: The Hardware/Software Interface" has had 6 editions (1998, 2003, 2005, 2012, 2014, 2020) but various editions have had ARM, MIPS, and RISC-V specific editions.
No, because `lui` results in an absolute address, not a position independent one.
The `auipc/addi` sequence results in 0x3004 + whatever the address of the `auipc` instruction itself is. If the `auipc` is at address 0 then the result will be the same.
Exactly, but the text has the same instruction sequence twice and the parent correctly indicated that the first copy should have used "lui" to illustrate the problem you mentioned and the second copy does use "auipc" to illustrate the fix you mentioned.
I have reached “intro to assembly” in my C course this week and had decided on RISC-V to bridge the gap that everyone has different CPUs and that x86-64 is a little harder to learn than MIPS32, but MIPS32 isn’t as relevant.
And here’s someone who made my course material for the subject entirely.
RISC-V assembly is mostly very easy (but still super tedious). The main difficulty is their insistence on unnecessarily abbreviated instruction mnemonics. `lw` instead of `load4`, `j` instead of `jump`, and so on. I don't really understand why. We aren't writing these on punch cards.
Even if there are not that expensive to implement, I do not use official ABI register names, neither pseudo-instructions (I use a command to generate the code on the side).
Once RISC-V has performant silicon implementations (server/desktop/mobile/embedded), the really hard part will be to move the software stack, mostly closed source applications like video games.
And a very big warning: do NOT abuse an assembler macro-preprocessor or you will lock your code on that very assembler. On my side I have been using a simple C pre-processor to keep the door open for any other assembler, at minimal technical cost.
The games are barely moving to ARM, they won’t move to yet another architecture. Desktop games will remain x86 windows for the foreseeable future merely due to the existing catalogue.
The only exception is console games, where the architecture doesn’t matter anyway.
Yep, the super hard part: this rv64 "catalog" is empty.
If you put emulation (hardware accelerated or not), game devs won't compile for rv64. Look at how valve proton is hurting native elf/linux gaming: game devs hardly build anymore for native elf/linux (but this may be related to the toxic behavior of some glibc and gcc devs though), even though their game engine has everything linux support.
Will spend more time on it in the coming days. I am quite interested in RISC-V and I think that it might have a bright future ahead.
If any AI expert is reading this now, please use Replit or Lovable or something like that to re-create "Core War" [0] with RISC-V assembly. It would be GREAT.
[0]: https://en.wikipedia.org/wiki/Core_War
But then I got to wondering about the OP's statement that they would specifically like someone to create this with AI. It strikes me both as silly as saying "if you're good at using Visual Studio, could you do this?", because AI tools are just tools now, and those who want to use them don't need to be prompted... but also somehow fundamentally different.
OP, what was on your heart that caused you to phrase it that way?
Now that book is also available with a RISC-V edition, which has a very interesting chapter comparing all different RISC ISAs and what they do differently (SH, Alpha, SPARC, PA-RISC, POWER, ARM, ...),...
However I've been exploring AArch64 for some time and I think it has some very interesting ideas too. Maybe not as clean as RISC-V but with very pragmatic design and some choices that make me question if RISC-V was too conservative in its design.
https://aspire.eecs.berkeley.edu/2017/06/how-close-is-risc-v...
https://thechipletter.substack.com/p/risc-on-a-chip-david-pa...
Not enough people reflect on this, or the fact that it's remarkably hazy where exactly AArch64 came from and what guided the design of it.
That's not saying much, it's basically impossible to remove an instruction. Just because something is easier than impossible doesn't mean that it's easy.
And sure, from a technical perspective, it's quite easy to add new instructions to RISC-V. Anyone can draft up a spec and implement it in their core.
But if you actually want wide-spread adoption of a new instruction, to the point where compilers can actually emit it by default and expect it to run everywhere, that's really, really hard. First you have to prove that this instruction is worthwhile standardizing, then debate the details and actually agree on a spec. Then you have to repeat the process and argue the extension is worth including in the next RVA profile, which is highly contentious.
Then you have to wait. Not just for the first CPUs to support that profile. You have to wait for every single processor that doesn't support that profile to become irrelevant. It might be over a decade before a compiler can safely switch on that instruction by default.
Patterson and Hennessy "Computer Organization and Design: The Hardware/Software Interface" has had 6 editions (1998, 2003, 2005, 2012, 2014, 2020) but various editions have had ARM, MIPS, and RISC-V specific editions.
I wrote TCP Socket for RISCV by using ISA RV64I. You have to know about linker relaxation and how to using it. Some of reference I have attached there
The `auipc/addi` sequence results in 0x3004 + whatever the address of the `auipc` instruction itself is. If the `auipc` is at address 0 then the result will be the same.
I have reached “intro to assembly” in my C course this week and had decided on RISC-V to bridge the gap that everyone has different CPUs and that x86-64 is a little harder to learn than MIPS32, but MIPS32 isn’t as relevant.
And here’s someone who made my course material for the subject entirely.
Thank you so much.
As a C/C++ dev, I've always thought assembly was much harder. But this interactive content makes assembly clearer.
Once RISC-V has performant silicon implementations (server/desktop/mobile/embedded), the really hard part will be to move the software stack, mostly closed source applications like video games.
And a very big warning: do NOT abuse an assembler macro-preprocessor or you will lock your code on that very assembler. On my side I have been using a simple C pre-processor to keep the door open for any other assembler, at minimal technical cost.
The only exception is console games, where the architecture doesn’t matter anyway.
If you put emulation (hardware accelerated or not), game devs won't compile for rv64. Look at how valve proton is hurting native elf/linux gaming: game devs hardly build anymore for native elf/linux (but this may be related to the toxic behavior of some glibc and gcc devs though), even though their game engine has everything linux support.
It is 0xfffffedd.
> Hmm, we get 0xfffffccd.
No, we didn't. The emulator shows 0xfffffedd, and I've checked it manually. The emulator is right.