zasm
A Deterministic Virtual CPU + IR Toolchain (WASM, native, and more)
zasm is a compiler-and-runtime stack for deterministic, auditable, and sandboxed execution.
At the bottom, it defines a stable virtual CPU (the “ZASM64 / ZX64” model) with a concrete opcode encoding that can be:
- Interpreted (reference execution)
- JIT-compiled to native machine code (arm64 / x86_64; more planned)
- AOT-lowered to WebAssembly (WAT/WASM)
- Packaged as a portable opcode container for shipping and replay
But zasm is no longer “just a cute ISA”: it has grown into a multi-IR toolchain where:
- Higher-level languages can compile into a stable, streaming IR (SIR) and then lower through zasm layers.
- The host boundary is defined by a normative, capability-gated ABI (zABI 2.x,
env.zi_*). - Complex data lives in a controlled arena/record system (Hopper), enabling “memory-safe by default” frontends.
zasm supports three closely-related runtime profiles:
- ZX64 — classic register-machine virtual CPU (the stable baseline).
- Z64+S — ZX64 plus the optional stacker coprocessor (explicit stack substrate for mixed-work loads).
- ZX64S — a stack-machine runtime (stacker as the whole CPU; stacker-only control flow).
These are compile-time/lowering-time choices (no runtime auto-switch). If a target/runtime doesn’t support a requested profile, lowering fails.
Status: v1.0.5 — core contracts are stable (ISA/IR/ABI/opcode encoding). Breaking changes trigger major version bumps.
┌─────────────────────────────────────────────────────────────────────────────┐
│ FRONTENDS (many languages) │
│ Oberon / C89 / DSLs / etc. → SIR (streaming typed IR) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ zasm layer (ZIR / zasm IR) │
│ Lowering, tooling, analysis, minimization, replay │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SOURCE (.asm) / zas (Assembler) │
│ Human-readable mnemonics → Emits versioned JSONL IR / opcode stream │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ zlnt (Analyzer) │
│ Static analysis on JSONL IR (recommended safety gate) │
└─────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────────┐
│ zld (Linker) │ │ zop (Packer) │ │ Third-Party Compilers │
│ JSONL → WAT/WASM │ │ JSONL → .zasm.bin │ │ (Your DSL → JSONL IR) │
└─────────────────────┘ └─────────────────────┘ └─────────────────────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────────────────────────────────┐
│ WebAssembly │ │ libzxc (Cross-Compiler) │
│ (Any WASM host) │ │ Opcode bytes → Native machine code │
└─────────────────────┘ │ ┌─────────────┬─────────────┬───────────────┐ │
│ │ arm64 │ x86_64 │ RV64I (soon) │ │
│ └─────────────┴─────────────┴───────────────┘ │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Cloak Runtime (Sandbox) │
│ Capability-gated execution with zABI 2.x │
│ • zrun (WASM via wasmtime) │
│ • zcloak (Pure C interpreter) │
│ • zcloak-jit (JIT via libzxc) │
└─────────────────────────────────────────────────┘
zasm defines a 64-bit virtual CPU (ZX64) with:
- Fixed 32-bit base instruction word with extension words for large immediates
- 16-register file (5 currently mapped: HL, DE, A, BC, IX)
- Explicit opcode encoding (documented in
docs/spec/opcode_encoding.md) - Both 32-bit and 64-bit arithmetic with zero-extension semantics
- Memory operations with bounds checking built into the ABI
This is not a Z80 emulator—the mnemonics are merely a UX choice for readability. The underlying architecture is closer to RISC-V in philosophy.
Every aspect of zasm is built for byte-for-byte reproducibility:
- No timestamps, random IDs, or host-dependent formatting
- Deterministic memory layout with fixed base offsets and 4-byte alignment
- Deterministic allocator behavior (
_allocresults are reproducible for identical call sequences) - Identical inputs → identical outputs across runs, machines, and platforms
This makes zasm ideal for content-addressable systems, blockchain execution, and reproducible builds.
zasm is built around line-oriented, versioned IR streams (JSONL) so tools can operate on real programs:
- interpret and debug (reference semantics)
- trace execution and memory events
- compute and merge coverage
- delta-minimize and triage failures
- strip unreachable code and dead regions
- analyze repetition (n-grams) and bloat
This is the “compiler stack” part: a stable representation you can pipe through real toolchains.
The runtime boundary is defined by a normative host ABI (zABI 2.x):
- All host interactions go through explicit
env.zi_*syscalls (e.g.zi_read,zi_write,zi_alloc,zi_ctl). - No ambient authority — if it’s not in the ABI surface, it doesn’t exist.
- Fail-closed security — missing capabilities are rejected via discovery/negotiation (
zi_ctl). - Auditability — host effects are explicit and can be traced, replayed, minimized, and certified.
This keeps zasm modules portable across hosts while preserving a strict sandbox contract.
A single source compiles to multiple backends:
| Target | Output | Use Case |
|---|---|---|
--target wasm |
WebAssembly (WAT/WASM) | Browser, edge, serverless |
--target zasm |
Native opcode bytes | JIT/AOT via libzxc |
--target rv64i |
RISC-V RV64I | Embedded, FPGA, future hardware |
The libzxc library provides embeddable C APIs for translating opcode streams to native machine code:
zxc_result_t zxc_arm64_translate(const uint8_t* in, size_t in_len,
uint8_t* out, size_t out_cap,
uint64_t mem_base, uint64_t mem_size,
const struct zi_host_v1* host);
zxc_result_t zxc_x86_64_translate(const uint8_t* in, size_t in_len,
uint8_t* out, size_t out_cap,
uint64_t mem_base, uint64_t mem_size);zasm ships with normative specifications that third-party tools can rely on:
- ISA Spec (
docs/spec/isa.md) — Registers, instructions, directives - | docs/spec/stacker.md | Stacker profile (coprocessor) and ZX64S addendum (stack CPU) |
- ABI Spec (
docs/spec/abi.md) — Host primitives, memory model, handle semantics - IR Spec (
docs/spec/ir.md) — JSONL intermediate representation - Opcode Spec (
docs/spec/opcode_encoding.md) — Binary encoding for native backends
The historical Integrator Pack was ABI1-based and is now largely defunct; we will produce a new zABI 2.5 integrator pack later.
Building a domain-specific language? Emit JSONL IR and let zasm handle the hard parts:
{"ir":"zasm-v1.1","kind":"instr","op":"LD","ops":[{"t":"reg","v":"DE"},{"t":"sym","v":"msg"}],"loc":{"line":5}}
{"ir":"zasm-v1.1","kind":"instr","op":"LD","ops":[{"t":"reg","v":"BC"},{"t":"sym","v":"msg_len"}],"loc":{"line":6}}
{"ir":"zasm-v1.1","kind":"instr","op":"LD","ops":[{"t":"reg","v":"HL"},{"t":"num","v":1}],"loc":{"line":7}}
{"ir":"zasm-v1.1","kind":"instr","op":"CALL","ops":[{"t":"sym","v":"zi_write"}],"loc":{"line":8}}No need to handle WASM's structured control flow—zld converts labels and jumps automatically.
Run untrusted code with full auditability:
- Every host call is explicit (
CALL zi_write,CALL zi_alloc) - No hidden syscalls or ambient capabilities
- Memory bounds checked at the ABI level
- Deterministic execution for replay/audit
Perfect for systems where the hash is the identity:
- IPFS / Filecoin compute
- Blockchain smart contracts
- Build caches and artifact stores
- Reproducible research
The (DE, BC) = (ptr, len) slice convention (with HL as a handle for zi_read/zi_write) enables:
- O(1) length lookups (no NUL scanning)
- Zero-copy buffer passing
- UNIX-style filter composition
For end users, zasm is delivered as self-contained compiled binaries (e.g. bin/<platform>/*, with convenience symlinks under bin/).
The repository may contain scripts used for development, testing, or internal workflows; they are not part of the user-facing product surface.
make # Build core tools (zas, zld, zlnt, zop)
make zrun # Build WASM runner (requires wasmtime-c-api)
make zcloak # Build pure-C cloak runtime
make zcloak-jit # Build JIT runner (via libzxc); hello.asm
CALL print_hello
RET
print_hello:
LD HL, msg
LD DE, msg_len
LD BC, DE
LD DE, HL
LD HL, #1
CALL zi_write
RET
msg: STR "Hello from zasm!"cat hello.asm | bin/zas | bin/zlnt | bin/zld > hello.wat
wat2wasm hello.wat -o hello.wasm
bin/zrun hello.watcat hello.asm | bin/zas --target opcodes | bin/zop --container > hello.zasm.bin
bin/zcloak-jit --mem 2mb hello.zasm.binJIT error semantics:
- Bounds violations and div0 traps raise a signal and
zcloak-jitexits non-zero with a diagnostic. - Host ABI faults (invalid pointers/handles) are reported as
zcloakfaults after execution.
| Tool | Description |
|---|---|
zas |
Assembler: zASM source → JSONL IR |
zld |
Linker: JSONL IR → WAT/WASM |
zop |
Packer: JSONL opcode stream → .zasm.bin |
zlnt |
Linter: Static analysis for JSONL IR |
zrun |
Runner: Execute WAT/WASM via wasmtime |
zem |
Emulator + debugger: Execute JSONL IR directly (trace/debug/events) |
zcloak |
Pure-C cloak runtime (interpreter) |
zcloak-jit |
JIT runner via libzxc |
libzxc |
Embeddable cross-compiler library (C API) |
| Document | Description |
|---|---|
| docs/architecture.md | System design and pipeline overview |
| docs/spec/stacker.md | Stacker profile (coprocessor) and ZX64S addendum (stack CPU) |
| docs/developers.md | Getting started guide |
| docs/spec/isa.md | Normative instruction set specification |
| docs/spec/abi.md | Normative host ABI and capability model |
| docs/spec/ir.md | Normative JSONL IR format |
| docs/spec/opcode_encoding.md | Normative binary opcode encoding |
| docs/spec/zasm_bin.md | Normative .zasm.bin container format |
| docs/tools/zem.md | zem usage (debugger + JSONL stop events) |
| docs/spec/accelerator.md | Accelerator profile (CUDA/Vulkan/Metal; draft) |
| docs/spec/fpga.md | FPGA profile (HLS/RTL; draft) |
| docs/integrator_pack/jit/README.md | JIT codepack snapshot (integrator pack) |
| docs/integrator_pack/integrator_pack.md | Third-party compiler integration guide |
| docs/integrator_pack/integrator_pack/CLOAK_INTEGRATOR_GUIDE.md | Legacy cloak integration guide (retired) |
- JSONL IR schema and versioning
- Host ABI (zABI 2.0:
env.zi_*syscalls) - Core ISA (arithmetic, logic, shifts, loads, stores, branches, calls)
- WASM backend via
zld - Pure-C cloak runtime
- Opcode binary encoding
- libzxc arm64 backend (partial coverage)
- libzxc x86_64 backend (Group A only)
zcloak-jitnative execution
- RV64I backend
- Additional target architectures
- VS Code extension (syntax highlighting, diagnostics)
- Expanded conformance test suite
Contributions are welcome. Areas of interest:
- Backend coverage: Expanding opcode support in libzxc (arm64, x86_64)
- New targets: RV64I, additional architectures
- Tooling: Editor integrations, debugging support
- Conformance tests: Golden tests for all mnemonic/operand combinations
- Documentation: Examples, tutorials, integration guides
See CONTRIBUTING.md for guidelines.
- Toolchain code: GPL-3.0-or-later
- Assembly examples and libraries (
examples/*.asm,lib/*.asm): MIT - See LICENSE, LICENSE-ASM, and TRADEMARK.md
zasm: Write once, run deterministically everywhere.
zas: assembler → JSONL/opcodes (docs/tools/zas.md)lower: JSON IR (zasm-v1.0/v1.1) → macOS arm64 Mach-O with rich dump/LLDB helper modes (docs/tools/lower.md)zxc: experimental cross-compilers (docs/tools/zxc.md)zir: IR utilities