disc-v 0.1.0

A RISC-V disassembler
Documentation
  • Coverage
  • 100%
    15 out of 15 items documented4 out of 10 items with examples
  • Size
  • Source code size: 186.4 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 839.2 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 1s Average build duration of successful builds.
  • all releases: 1s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • swenson/disc-v
    0 1 5
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • swenson

disc-v

CI

A RISC-V disassembler in Rust. It is no_std, does not allocate, and its output follows GNU objdump's (see Output format).

It is meant to be embedded in various Rust tools: debuggers, emulators, etc.

use disc_v::{disassemble, Isa};

let code = [0x13, 0x05, 0x10, 0x00, 0x82, 0x80];
for ins in disassemble(Isa::Rv64, 0x1000, &code) {
    println!("{:x}: {ins}", ins.pc());
}
// 1000: li a0,1
// 1004: ret

Single instructions can be decoded from bytes with decode_bytes, or from an integer with decode. An Instruction has the mnemonic, operands, address, length and raw encoding, and without_aliases() shows it as encoded (c.li a0,1 rather than li a0,1), like objdump -M no-aliases.

The minimum supported Rust version is 1.85.1.

Output format

The text is what objdump -D -b binary prints for the same bytes: the same mnemonics, aliases (li, ret, csrr, ...) and operand syntax. Immediates are decimal (li a0,-1107), while shift amounts and upper immediates are hex (slli a0,a0,0x3, lui a0,0xbad).

Branch and jump targets are absolute addresses, always written with 0x: beq a0,a1,0x1008. When objdump disassembles an ELF file it instead writes the target as bare hex followed by a symbol, as in beq a0,a1,1008 <foo+0x8>. disc-v has no symbol information, so it uses objdump's raw-binary form, which is unambiguous.

A few encodings are decoded differently from objdump where binutils and the ISA specification disagree; see Testing.

Supported instructions

  • RV32I, RV64I and RV128I
  • M, A, F, D, Q and C
  • Zicsr and Zifencei
  • Zba, Zbb, Zbc and Zbs
  • ecall, ebreak, sret, mret, dret, wfi and sfence.vma

48- and 64-bit encodings are recognized (so disassembly stays in sync) but shown as .insn, as objdump does.

Testing

Besides unit tests, the decoder is checked against two references:

  • tests/riscv_opcodes.rs checks it against the encodings in riscv-opcodes, in both directions: every listed instruction decodes to its name, and every encoding disc-v accepts is listed. The data is in tests/data/riscv-opcodes.txt, generated by scripts/gen-riscv-opcodes.py.
  • tests/objdump.rs compares the output with GNU objdump (after rewriting objdump's 1008 <foo+0x8> targets as 0x1008) for every compressed encoding, random 32-bit encodings, and random encodings of every instruction in riscv-opcodes. It needs a RISC-V binutils (riscv64-elf-objdump, riscv64-unknown-elf-objdump or riscv64-linux-gnu-objdump) and is skipped if none is found; set DISC_V_REQUIRE_BINUTILS=1 to make that an error, as CI does.

Where binutils and the ISA specification disagree on whether an encoding is valid, disc-v follows the specification. The differences, such as RV32 shift amounts of 32 or more (reserved, but decoded by objdump), are listed in known_difference in tests/objdump.rs.

CSR names come from riscv-opcodes, via scripts/gen-csr-names.py.

Origins

disc-v is built on the disassembler from the Caliptra MCU emulator (emulator/app/src/dis.rs, imported at commit 20f7fcff1b51d69b03d0b352685fc7360536ad9a). The Caliptra authors ported it to Rust and added the bit-manipulation extensions (Zba, Zbb, Zbc, Zbs).

That code is itself a port of Michael Clark and SiFive's C riscv-disassembler.

The name is a nod to Oxide Computer's disc-v, an earlier Rust port of the same C disassembler by Wladimir J. van der Laan and Adam H. Leventhal. That repository has no license, so this crate does not use any of its code.

License

Copyright (c) 2026 Christopher Swenson.

disc-v is licensed under the Apache License, Version 2.0 (LICENSE).

It is derived from Michael Clark and SiFive's riscv-disassembler, which is MIT licensed (Copyright (c) 2016-2017 Michael Clark, (c) 2017-2018 SiFive, Inc.), by way of the Caliptra port, which is Apache-2.0 licensed. The original MIT copyright and permission notice is kept in NOTICE, and source files derived from that code say so in their headers.

The test data and CSR names derived from riscv-opcodes are Copyright (c) 2022 RISC-V International, under the BSD-3-Clause license (tests/data/LICENSE-riscv-opcodes).