IntelliSense for RISC-V RV32IM assembly language in VS Code.
Provides MARS-like autocomplete, diagnostics, and documentation to help students learn RISC-V assembly.
Type instruction mnemonics to see suggestions with descriptions:
- Instructions: All RV32I base + M extension (multiply/divide)
- Pseudo-instructions:
li,la,mv,j,ret,beqz,bnez, etc. - Directives:
.text,.data,.global,.word,.align, etc. - Registers: Both ABI names (
t0,a0,sp) and numeric (x5,x10,x2) - Labels: Suggests labels defined in the current file
- Header symbols:
#defineconstants from C headers (e.g., ESP-IDF register definitions) - #include completion: Suggests header files when typing
#include
After typing an instruction, see operand hints:
add |
add rd, rs1, rs2
rd: Destination register
Hover over any element for documentation:
- Instructions: Description, syntax variants, operand details, examples
- Registers: ABI name, purpose, caller/callee-saved status
- Directives: Syntax and usage examples
- Labels: Shows definition line number
- .equ/.set constants: Shows the defined value
- Header symbols: Shows value and source file
Ctrl+Click (or F12) on any symbol to jump to its definition:
- Labels defined with
label: - Constants defined with
.equor.set - Header symbols (jumps to the header file)
Right-click > Find All References (or Shift+F12) to see all uses of a symbol:
- Shows the definition and all places where the symbol is referenced
- Works for labels,
.equ/.setconstants
Real-time error and warning highlighting as you type:
| Error | Example | Message |
|---|---|---|
| Unknown instruction | addd a0, a1, a2 |
Unknown instruction: 'addd' |
| Wrong operand count | add a0, a1 |
'add' expects 3 operand(s), got 2 |
| Invalid register | add a0, a1, a99 |
Invalid register: 'a99'. Valid range is a0-a7 |
| Immediate out of range | addi a0, a1, 50000 |
Immediate value 50000 is out of range for imm (-2048 to 2047) |
| Malformed memory operand | lw a0, sp |
Memory operand requires parentheses: 'offset(sp)' or '(sp)' |
| Invalid label name | 123: add a0, a1, a2 |
Invalid label name: '123'. Labels must start with a letter or underscore |
| Duplicate label | loop: (defined twice) |
Duplicate label: 'loop' |
| Undefined symbol | j unknown_label |
Undefined symbol: 'unknown_label' |
| li with symbol | li t0, my_label |
Use 'la' instead of 'li' to load address of symbol 'my_label' |
| la with numeric | la t0, 0x1000 |
Consider using a symbol instead of numeric address (warning) |
| Register as immediate | addi t1, t2, t4 |
Expected immediate value, got register 't4' |
Format Document (Shift+Alt+F) to align your code:
- Labels stay at column 0
- Section directives (
.text,.data,.global) stay at column 0 - Instructions align to configurable column (default: 8)
- Operands align to configurable column (default: 16)
- Inline comments align to configurable column (default: 40)
Before:
loop: add a0,a1,a2 # add values
lw t0, 0(sp)
addi sp, sp, -16After:
loop: add a0, a1, a2 # add values
lw t0, 0(sp)
addi sp, sp, -16Labels and .equ/.set constants appear in the Outline view (Ctrl+Shift+O) for easy navigation.
Autocomplete for #define constants from C header files (e.g., ESP-IDF SOC registers):
la a0, GPIO|
↓
┌─────────────────────────────────┐
│ GPIO_NUM_0 = 0 (gpio_num.h) │
│ GPIO_NUM_1 = 1 │
│ GPIO_NUM_2 = 2 │
└─────────────────────────────────┘
When you accept a symbol, the corresponding #include is automatically added:
#include "soc/gpio_num.h" ← auto-inserted
.text
la a0, GPIO_NUM_0Also provides #include completion:
#include "|
↓
┌─────────────────────────┐
│ soc/gpio_num.h │
│ soc/usb_serial_jtag_reg.h│
│ soc/interrupts.h │
└─────────────────────────┘
- Arithmetic:
add,sub,addi - Logical:
and,or,xor,andi,ori,xori - Shift:
sll,srl,sra,slli,srli,srai - Compare:
slt,sltu,slti,sltiu - Load:
lw,lh,lb,lhu,lbu - Store:
sw,sh,sb - Branch:
beq,bne,blt,bge,bltu,bgeu - Jump:
jal,jalr - Upper Immediate:
lui,auipc - System:
ecall,ebreak,fence
mul, mulh, mulhsu, mulhu, div, divu, rem, remu
nop, li, la, mv, not, neg, j, jr, ret, call, tail,
seqz, snez, sltz, sgtz, beqz, bnez, blez, bgez, bltz, bgtz,
bgt, ble, bgtu, bleu
| Setting | Default | Description |
|---|---|---|
riscvSense.enableMExtension |
true |
Include M extension instructions |
riscvSense.showPseudoInstructions |
true |
Include pseudo-instructions |
riscvSense.preferAbiNames |
true |
Show ABI names (t0) before numeric (x5) |
riscvSense.includePaths |
["~/.platformio/..."] |
Paths to search for header files |
| Setting | Default | Description |
|---|---|---|
riscvSense.diagnostics.enabled |
true |
Enable real-time diagnostics |
riscvSense.diagnostics.unknownInstruction |
true |
Report unknown instructions |
riscvSense.diagnostics.operandCount |
true |
Report wrong operand count |
riscvSense.diagnostics.invalidRegister |
true |
Report invalid register names |
riscvSense.diagnostics.immediateRange |
true |
Report immediate values out of range |
riscvSense.diagnostics.undefinedSymbol |
true |
Report undefined symbol references |
riscvSense.diagnostics.duplicateLabel |
true |
Report duplicate label definitions |
| Setting | Default | Description |
|---|---|---|
riscvSense.formatting.instructionColumn |
8 |
Column to align instructions |
riscvSense.formatting.operandColumn |
16 |
Column to align operands |
riscvSense.formatting.commentColumn |
40 |
Column to align inline comments |
By default, the extension looks for ESP-IDF headers in the PlatformIO installation:
~/.platformio/packages/framework-espidf/components/soc/esp32c3
This path works on Linux, macOS, and Windows. The extension scans include/ and register/ subdirectories for .h files.
To add custom paths:
{
"riscvSense.includePaths": [
"~/.platformio/packages/framework-espidf/components/soc/esp32c3",
"/path/to/other/headers"
]
}Activates for files with extensions: .s, .S, .asm
# Install dependencies
npm install
# Compile
npm run compile
# Watch mode
npm run watchPress F5 in VS Code to launch the extension in a development host.
MIT