Home | Notifications | New Note | Local | Federated | Search | Logout
Note Detail
David Chisnall (*Now with 50% more sarcasm!*)@david_chisnall@infosec.exchange (2026-04-24 19:05:41)
Fun thing I've learned about RISC-V recently:
There is no easy way of writing a 32-bit nop in RISC-V assembly.
RISC-V tries to make the C extension transparent. You don't need to write compressed variants of instructions, you just write as if you're targeting the 32-bit encoding and the assembler transparently shrinks some things for you. The C extension is entirely duplicated instructions: every 16-bit instruction in the C extension can also be written as a 32-bit instruction and this leaves it to the assembler to figure out which.
The exact same logic is applied to NOPs (which aren't really nops, they're add 0 to 0 and store the result in the zero register). There is a NOP and a C.NOP variant, but because NOP is an alias for ADDI x0, x0, 0 and C.NOP is an alias for C.ADDI x0, 0 (which is equivalent), the assembler will always emit C.NOP (a.k.a. C.ADDI x0, 0) if you write NOP. You can generate a non-canonical nop by doing something like ADDI x0, x15, 0x200, which can't be compressed (currently), but that's fragile.
This is an issue if you want to guarantee padding space in the instruction stream for later patching or linker relaxations.
As far as I am aware, RISC-V is the only variable-length architecture whose assembler makes this mistake. x86 and Thumb-2, for example, both have explicit mnemonics for longer nops. Thumb-2 has NOP and NOP.W. x86 has a baroque list of arguments you add to NOP to make it 2-15 bytes (it's one byte with no operands).
Reply
---Replies---
Sun Microdevil Pte Ltd@koakuma@uwu.social (2026-08-17 01:36:27)
@david_chisnall For reasons that I myself can't articulate, seeing how RVC is basically just copies of G instructions But Smallerâ„¢ disturbs me greatly
Though apparently they managed to shrink byte counts by a lot so I suppose it does work well?
Though on the other hand I'd also love to see ISA designs that tries to shrink instruction counts instead (while stillbwing amenable to the usual set of optimizing implementation techniques ofc)...