# r/moul/x/vm/riscvdemo Demo of [`p/moul/x/vm/riscv`](/p/moul/x/vm/riscv/v0), the RV32IM hart, and [`p/moul/x/vm/vmkit`](/p/moul/x/vm/vmkit/v0), the host ABI. This realm holds no logic of its own: it stores images, builds a `vmkit.Host`, and renders. What it exists to show is two things realm code cannot do for itself. **The guest was not written for gno.** The programs on the front page are flat `.text` images, the bytes a cross compiler emits for `riscv32im-unknown-none-elf`. `Upload` takes hex, so anything you can build with `clang`, `rustc`, TinyGo or Zig and strip to its text segment goes in unchanged. Two samples are exactly that and neither is a mock up. **Compiled by clang** is a freestanding C program; **A token, in Rust** is `#![no_std]` Rust that mints, sends and burns, linking Rust's real `core` and `compiler_builtins`, so a 64-bit divide in it runs `__udivdi3` on a machine with no 64-bit divide instruction. Both are shipped as the bytes the compiler emitted, and the page shows their source rather than a disassembly, because a disassembly would bury the only interesting fact: nobody wrote the machine code. Sources and build commands: `tools/riscv-guests`. **A program pauses instead of failing.** It runs until its fuel slice is spent, then stops with a snapshot the realm keeps, and the next caller pays for the next slice. The "Heavy loop" sample is 200,006 instructions and takes three transactions at the default slice, which is the whole point. ``` UploadSample("heavy", "", 0) -> id Step(id, 80000) -> "running" Step(id, 80000) -> "running" Step(id, 80000) -> "halted" ``` ## Reading the instance page A guest that writes nothing has still computed something, so the instance page restores the snapshot and shows the register file under its ABI names. That is the only place the state is legible: the hart itself does not survive the transaction, only its snapshot does. ## What a slice costs An RV32IM instruction costs about **8,500 gas**, measured rather than estimated, so a block buys roughly **350,000 guest instructions**. Loading the image costs about **19,600 gas per instruction word** and is paid again on every resume, which is why `MaxImage` is 8 KiB and not a megabyte. The measurements and how they were taken are in the [library README](/p/moul/x/vm/riscv/v0). ## What this realm does not grant `Send` always returns `vmkit.ErrNotGranted`. No instance here is funded, so a guest that tries to move coins is refused, and that is the capability rule working rather than a missing feature. Guest key-value storage is scoped to the instance being stepped by construction: the tree belongs to the instance, so one program cannot reach another's even though both live in this realm. --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** โ€” moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:** ![gno.land/r/moul/x/vm/riscvdemo/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/r/moul/x/vm/riscvdemo/v0/deps.png) > ๐Ÿงช **Highly experimental โ€” potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).