Miden VM Instruction Reference
This page provides a comprehensive reference for Miden Assembly instructions.
Field Operations
Comparison Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
lte lte.b | [b, a, ...] | [c, ...] | 15 16 | |
lt lt.b | [b, a, ...] | [c, ...] | 14 15 | |
gte gte.b | [b, a, ...] | [c, ...] | 16 17 | |
gt gt.b | [b, a, ...] | [c, ...] | 15 16 | |
eq eq.b | [b, a, ...] | [c, ...] | 1 1-2 | |
neq neq.b | [b, a, ...] | [c, ...] | 2 2-3 | |
eqw | [A, B, ...] | [c, A, B, ...] | 15 | |
is_odd | [a, ...] | [b, ...] | 5 |
Assertions and Tests
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
assert | [a, ...] | [...] | 1 | Removes if . Fails if . |
assertz | [a, ...] | [...] | 2 | Removes if . Fails if . |
assert_eq | [b, a, ...] | [...] | 2 | Removes if . Fails if . |
assert_eqw | [B, A, ...] | [...] | 11 | Removes if . Fails if . |
Note: Assertions can be parameterized with an error message (e.g., assert.err="Division by 0").
Arithmetic and Boolean Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
add add.b | [b, a, ...] | [c, ...] | 1 1-2 | |
sub sub.b | [b, a, ...] | [c, ...] | 2 2 | |
mul mul.b | [b, a, ...] | [c, ...] | 1 2 | |
div div.b | [b, a, ...] | [c, ...] | 2 2 | . Fails if . |
neg | [a, ...] | [b, ...] | 1 | |
inv | [a, ...] | [b, ...] | 1 | . Fails if . |
pow2 | [a, ...] | [b, ...] | 16 | . Fails if . |
exp.uxx exp.b | [b, a, ...] | [c, ...] | 9+xx 9+log2(b) | . Fails if is outside . exp is exp.u64 (73 cycles). |
ilog2 | [a, ...] | [b, ...] | 44 | . Fails if . |
not | [a, ...] | [b, ...] | 1 | . Fails if . |
and | [b, a, ...] | [c, ...] | 1 | . Fails if . |
or | [b, a, ...] | [c, ...] | 1 | . Fails if . |
xor | [b, a, ...] | [c, ...] | 7 | . Fails if . |
Extension Field Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
ext2add | [b1, b0, a1, a0, ...] | [c1, c0, ...] | 5 | |
ext2sub | [b1, b0, a1, a0, ...] | [c1, c0, ...] | 7 | |
ext2mul | [b1, b0, a1, a0, ...] | [c1, c0, ...] | 3 | |
ext2neg | [a1, a0, ...] | [a1', a0', ...] | 4 | |
ext2inv | [a1, a0, ...] | [a1', a0', ...] | 8 | . Fails if . |
ext2div | [b1, b0, a1, a0, ...] | [c1, c0, ...] | 11 | . Fails if . Multiplication and inversion are as defined previously. |
U32 Operations
Operations on 32-bit integers. Most instructions will fail or have undefined behavior if inputs are not valid u32 values.
Conversions and Tests
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
u32test | [a, ...] | [b, a, ...] | 5 | |
u32testw | [A, ...] | [b, A, ...] | 23 | |
u32assert | [a, ...] | [a, ...] | 3 | Fails if . |
u32assert2 | [b, a,...] | [b, a,...] | 1 | Fails if or . |
u32assertw | [A, ...] | [A, ...] | 6 | Fails if any element of is . |
u32cast | [a, ...] | [b, ...] | 2 | |
u32split | [a, ...] | [c, b, ...] | 1 | , |
Note: Assertions can be parameterized with an error message (e.g., assert.err="Division by 0").
Arithmetic Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
u32overflowing_add u32overflowing_add.b | [b, a, ...] | [d, c, ...] | 1 2-3 | , . Undefined if . |
u32wrapping_add u32wrapping_add.b | [b, a, ...] | [c, ...] | 2 3-4 | . Undefined if . |
u32overflowing_add3 | [c, b, a, ...] | [e, d, ...] | 1 | , . Undefined if . |
u32wrapping_add3 | [c, b, a, ...] | [d, ...] | 2 | . Undefined if . |
u32overflowing_sub u32overflowing_sub.b | [b, a, ...] | [d, c, ...] | 1 2-3 | , . Undefined if . |
u32wrapping_sub u32wrapping_sub.b | [b, a, ...] | [c, ...] | 2 3-4 | . Undefined if . |
u32overflowing_mul u32overflowing_mul.b | [b, a, ...] | [d, c, ...] | 1 2-3 | , . Undefined if . |
u32wrapping_mul u32wrapping_mul.b | [b, a, ...] | [c, ...] | 2 3-4 | . Undefined if . |
u32overflowing_madd | [b, a, c, ...] | [e, d, ...] | 1 | , . Undefined if . |
u32wrapping_madd | [b, a, c, ...] | [d, ...] | 2 | . Undefined if . |
u32div u32div.b | [b, a, ...] | [c, ...] | 2 3-4 | . Fails if . Undefined if . |
u32mod u32mod.b | [b, a, ...] | [c, ...] | 3 4-5 | . Fails if . Undefined if . |
u32divmod u32divmod.b | [b, a, ...] | [d, c, ...] | 1 2-3 | , . Fails if . Undefined if . |
Bitwise Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
u32and u32and.b | [b, a, ...] | [c, ...] | 1 2 | Bitwise AND. Fails if . |
u32or u32or.b | [b, a, ...] | [c, ...] | 6 7 | Bitwise OR. Fails if . |
u32xor u32xor.b | [b, a, ...] | [c, ...] | 1 2 | Bitwise XOR. Fails if . |
u32not u32not.a | [a, ...] | [b, ...] | 5 6 | Bitwise NOT. Fails if . |
u32shl u32shl.b | [b, a, ...] | [c, ...] | 18 3 | . Undefined if or . |
u32shr u32shr.b | [b, a, ...] | [c, ...] | 18 3 | . Undefined if or . |
u32rotl u32rotl.b | [b, a, ...] | [c, ...] | 18 3 | Rotate left. Undefined if or . |
u32rotr u32rotr.b | [b, a, ...] | [c, ...] | 23 3 | Rotate right. Undefined if or . |
u32popcnt | [a, ...] | [b, ...] | 33 | Population count (Hamming weight). Undefined if . |
u32clz | [a, ...] | [b, ...] | 42 | Count leading zeros. Undefined if . |
u32ctz | [a, ...] | [b, ...] | 34 | Count trailing zeros. Undefined if . |
u32clo | [a, ...] | [b, ...] | 41 | Count leading ones. Undefined if . |
u32cto | [a, ...] | [b, ...] | 33 | Count trailing ones. Undefined if . |
Comparison Operations
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
u32lt u32lt.b | [b, a, ...] | [c, ...] | 3 4 | . Undefined if . |
u32lte u32lte.b | [b, a, ...] | [c, ...] | 5 6 | . Undefined if . |
u32gt u32gt.b | [b, a, ...] | [c, ...] | 4 5 | . Undefined if . |
u32gte u32gte.b | [b, a, ...] | [c, ...] | 4 5 | . Undefined if . |
u32min u32min.b | [b, a, ...] | [c, ...] | 8 9 | . Undefined if . |
u32max u32max.b | [b, a, ...] | [c, ...] | 9 10 | . Undefined if . |
Stack Manipulation
Instructions for directly manipulating the operand stack. Only the top 16 elements are directly accessible.
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
drop | [a, ... ] | [ ... ] | 1 | Deletes the top stack item. |
dropw | [A, ... ] | [ ... ] | 4 | Deletes a word (4 elements) from the top of the stack. |
padw | [ ... ] | [0,0,0,0, ... ] | 4 | Pushes four 0 values onto the stack. |
dup.n | [ ..., a, ... ] | [a, ..., a, ... ] | 1-3 | Pushes a copy of the n th stack item (0-indexed) onto the stack. dup is dup.0 . Valid for n in 0..=15 . |
dupw.n | [ ..., A, ... ] | [A, ..., A, ... ] | 4 | Pushes a copy of the n th stack word (0-indexed) onto the stack. dupw is dupw.0 . Valid for n in 0..=3 . |
swap.n | [a, ..., b, ... ] | [b, ..., a, ... ] | 1-6 | Swaps the top stack item with the n th stack item (1-indexed). swap is swap.1 . Valid for n in 1..=15 . |
swapw.n | [A, ..., B, ... ] | [B, ..., A, ... ] | 1 | Swaps the top stack word with the n th stack word (1-indexed). swapw is swapw.1 . Valid for n in 1..=3 . |
swapdw | [D,C,B,A, ... ] | [B,A,D,C ... ] | 1 | Swaps words: 1st with 3rd, 2nd with 4th. |
movup.n | [ ..., a, ... ] | [a, ... ] | 1-4 | Moves the n th stack item (2-indexed) to the top. Valid for n in 2..=15 . |
movupw.n | [ ..., A, ... ] | [A, ... ] | 2-3 | Moves the n th stack word (2-indexed) to the top. Valid for n in 2..=3 . |
movdn.n | [a, ... ] | [ ..., a, ... ] | 1-4 | Moves the top stack item to the n th position (2-indexed). Valid for n in 2..=15 . |
movdnw.n | [A, ... ] | [ ..., A, ... ] | 2-3 | Moves the top stack word to the n th word position (2-indexed). Valid for n in 2..=3 . |
Conditional Manipulation
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
cswap | [c, b, a, ... ] | [e, d, ... ] | 1 | If c = 1 , d=b, e=a . If c = 0 , d=a, e=b . Fails if c > 1 . |
cswapw | [c, B, A, ... ] | [E, D, ... ] | 1 | If c = 1 , D=B, E=A . If c = 0 , D=A, E=B . Fails if c > 1 . |
cdrop | [c, b, a, ... ] | [d, ... ] | 2 | If c = 1 , d=b . If c = 0 , d=a . Fails if c > 1 . |
cdropw | [c, B, A, ... ] | [D, ... ] | 5 | If c = 1 , D=B . If c = 0 , D=A . Fails if c > 1 . |
Input/Output Operations
Instructions for moving data between the stack and other sources like program code, environment, advice provider, and memory.
Constant Inputs
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
push.a... | [ ... ] | [c, b, a, ...] | 1-2 | Pushes up to 16 field elements (decimal or hex) onto the stack. Hex words (32 bytes) are little-endian; short hex values are big-endian. Example: push.0x1234.0x5678 or push.0x34120000...78560000... |
Environment Inputs
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
clk | [ ... ] | [t, ... ] | 1 | Pushes current clock cycle t . |
sdepth | [ ... ] | [d, ... ] | 1 | Pushes current stack depth d . |
caller | [A, b,...] | [H, b,...] | 1 | Overwrites top 4 stack items with hash H of the function that initiated the current SYSCALL . Fails if not in SYSCALL . |
locaddr.i | [ ... ] | [a, ... ] | 2 | Pushes absolute memory address a of local memory at index i . |
procref.name | [ ... ] | [A, ... ] | 4 | Pushes MAST root A of procedure name . |
Nondeterministic Inputs (Advice Provider)
Reading from Advice Stack
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
adv_push.n | [ ... ] | [a, ...] | n | Pops n values from advice stack to operand stack (1st popped is deepest). Valid n in 1..=16 . Fails if advice stack has < n values. |
adv_loadw | [0,0,0,0, ...] | [A, ...] | 1 | Pops word A (4 elements) from advice stack, overwrites top word of operand stack. Fails if advice stack has < 4 values. |
adv_pipe | [C,B,A,a,...] | [E,D,A,a',...] | 1 | Pops 2 words [D,E] from advice stack. Overwrites top 2 words of operand stack. Writes [D,E] to memory at a and a+1 . a' <- a+2 . Fails if advice stack has < 8 values. |
Injecting into Advice Provider (System Events - 0 cycles)
Push to Advice Stack:
Instruction | Stack Input | Stack Output | Notes |
---|---|---|---|
adv.push_mapval | [K, ... ] | [K, ... ] | Pushes values from advice_map[K] to advice stack. |
adv.push_mapvaln | [K, ... ] | [K, ... ] | Pushes [n, ele1, ele2, ...] from advice_map[K] to advice stack, where n is element count. |
adv.push_mtnode | [d, i, R, ... ] | [d, i, R, ... ] | Pushes Merkle tree node (root R , depth d , index i ) from Merkle store to advice stack. |
adv.push_u64div | [b1, b0, a1, a0, ...] | [b1, b0, a1, a0, ...] | Pushes quotient and remainder of u64 division a/b (represented by 32-bit limbs) to advice stack. |
adv.push_smtpeek | [K, R, ...] | [K, R, ...] | Pushes value for key K in Sparse Merkle Tree with root R to advice stack. |
Insert into Advice Map:
Instruction | Stack Input | Stack Output | Notes |
---|---|---|---|
adv.insert_mem | [K, a, b, ... ] | [K, a, b, ... ] | advice_map[K] <- mem[a..b] . |
adv.insert_hdword | [B, A, ... ] | [B, A, ... ] | K <- hash(A || B, domain=0) . advice_map[K] <- [A,B] . |
adv.insert_hdword_d | [B, A, d, ... ] | [B, A, d, ... ] | K <- hash(A || B, domain=d) . advice_map[K] <- [A,B] . |
adv.insert_hperm | [B, A, C, ...] | [B, A, C, ...] | K <- permute(C,A,B).digest . advice_map[K] <- [A,B] . |
Random Access Memory
Memory is 0-initialized. Addresses are absolute [0, 2^32)
. Locals are stored at offset 2^30
.
Absolute Addressing
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
mem_load mem_load.a | [a, ... ] | [v, ... ] | 1 2 | v <- mem[a] . Pushes element from mem[a] . If a on stack, it's popped. Fails if a >= 2^32 . |
mem_loadw mem_loadw.a | [a, 0,0,0,0,...] | [A, ... ] | 1 2 | A <- mem[a..a+3] (word). Overwrites top 4 stack elements (mem[a+3] is top). If a on stack, it's popped. Fails if a >= 2^32 or a not multiple of 4. |
mem_store mem_store.a | [a, v, ... ] | [ ... ] | 2 3-4 | mem[a] <- v . Pops v to mem[a] . If a on stack, it's popped. Fails if a >= 2^32 . |
mem_storew mem_storew.a | [a, A, ... ] | [A, ... ] | 1 2-3 | mem[a..a+3] <- A . Stores word A (top stack element at mem[a+3] ). If a on stack, it's popped. Fails if a >= 2^32 or a not multiple of 4. |
mem_stream | [C, B, A, a, ... ] | [E,D,A,a',...] | 1 | [E,D] <- [mem[a..a+3], mem[a+4..a+7]] . a' <- a+8 . Reads 2 sequential words from memory to top of stack. |
Procedure Locals (Context-Specific)
Locals are not 0-initialized. Max locals per procedure, total. Rounded up to multiple of 4.
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
loc_load.i | [ ... ] | [v, ... ] | 3-4 | v <- local[i] . Pushes element from local memory at index i . |
loc_loadw.i | [0,0,0,0, ...] | [A, ... ] | 3-4 | A <- local[i..i+3] . Reads word, local[i+3] is top of stack. Fails if i not multiple of 4. |
loc_store.i | [v, ... ] | [ ... ] | 4-5 | local[i] <- v . Pops v to local memory at index i . |
loc_storew.i | [A, ... ] | [A, ... ] | 3-4 | local[i..i+3] <- A . Stores word, top stack element at local[i+3] . |
Cryptographic Operations
Common cryptographic operations, including hashing and Merkle tree manipulations using Rescue Prime Optimized.
Hashing and Merkle Trees
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
hash | [A, ...] | [B, ...] | 20 | B <- hash(A) . 1-to-1 Rescue Prime Optimized hash. |
hperm | [B, A, C, ...] | [F, E, D, ...] | 1 | D,E,F <- permute(C,A,B) . Rescue Prime Optimized permutation. C =capacity, A,B =rate, E =digest. |
hmerge | [B, A, ...] | [C, ...] | 16 | C <- hash(A,B) . 2-to-1 Rescue Prime Optimized hash. |
mtree_get | [d, i, R, ...] | [V, R, ...] | 9 | Verifies Merkle path for node V at depth d , index i for tree R (from advice provider), returns V . |
mtree_set | [d, i, R, V', ...] | [V, R', ...] | 29 | Updates node in tree R at d,i to V' . Returns old value V and new root R' . Both trees in advice provider. |
mtree_merge | [R, L, ...] | [M, ...] | 16 | Merges Merkle trees with roots L (left) and R (right) into new tree M . Input trees retained. |
mtree_verify | [V, d, i, R, ...] | [V,d,i,R,...] | 1 | Verifies Merkle path for node V at depth d , index i for tree R (from advice provider). Can be parameterized with err code (e.g., mtree_verify.err=123 ). Default error code is 0. |
Flow Control Operations
High-level constructs for controlling the execution flow.
Conditional Execution: if.true ... else ... end
/ if.false ... else ... end
- Syntax:
Or withif.true # instructions for true branch else # instructions for false branch end
if.false
(condition inverted). Theelse
block is optional. - Stack Input:
[cond, ...]
(wherecond
is 0 or 1) - Cycles: Incurs a small overhead. For simple conditionals,
cdrop
might be more efficient if side-effects can be managed. - Notes:
- Pops
cond
from the stack. Fails if not boolean. if.true
: Executes first block ifcond = 1
, second (else) block ifcond = 0
.if.false
: Executes first block ifcond = 0
, second (else) block ifcond = 1
.- Empty or elided branches are treated as a
nop
. - Ensure stack consistency at join points if modifications persist beyond a branch.
- Pops
Counter-Controlled Loops: repeat.count ... end
- Syntax:
repeat.COUNT # instructions to repeat end
- Cycles: No additional cost for counting; the block is unrolled
COUNT
times during compilation. - Notes:
COUNT
must be an integer or a named constant greater than 0.- Instructions inside can include nested control structures.
Condition-Controlled Loops: while.true ... end
- Syntax:
while.true # instructions for loop body end
- Stack Input (for each iteration check):
[cond, ...]
(wherecond
is 0 or 1) - Cycles: Overhead per iteration for condition check.
- Notes:
- Pops
cond
from the stack. If0
, skips loop. Fails if not boolean. - If
cond = 1
, executes loop body. - After body execution, pops a new
cond
. If1
, repeats body. If0
, exits loop. Fails if not boolean.
- Pops
No-Operation: nop
- Syntax:
nop
- Cycles: 1
- Notes:
- Increments the cycle counter with no other effects.
- Useful for empty blocks or explicitly advancing cycles.
- Assembler automatically inserts
nop
for empty/elided branches inif
statements.
Events
Instructions for communicating with the host through events and tracing.
Instruction | Stack Input | Stack Output | Cycles | Notes |
---|---|---|---|---|
emit.<event_id> | [...] | [...] | 5 | Emits an event with the specified event_id to the host. Does not change the state of the operand stack. The event_id can be any 32-bit value specified either directly or via a named constant. Events allow programs to communicate contextual information to the host for triggering appropriate actions. Example: emit.123 or emit.EVENT_ID_1 |
trace.<trace_id> | [...] | [...] | 0 | Emits a trace with the specified trace_id to the host. Does not change the state of the operand stack. The trace_id can be any 32-bit value specified either directly or via a named constant. Only active when programs are run with tracing flag (-t or --trace ), otherwise ignored. Example: trace.123 or trace.TRACE_ID_1 |
Debugging Operations
Instructions for inspecting VM state during execution. These do not affect VM state or program hash and are only active when the assembler is in debug mode.
debug
- Syntax & Parameters:
debug.stack
: Prints entire stack.debug.stack.N
: Prints topN
stack items (0 < N < 256
).debug.mem
: Prints entire RAM.debug.mem.A
: Prints memory at addressA
.debug.mem.A.M
: Prints memory from addressA
toM
(inclusive,M >= A
).debug.local
: Prints entire local memory of the current procedure.debug.local.I
: Prints local memory at indexI
(0 <= I < 65536
).debug.local.I.M
: Prints local memory from indexI
toM
(inclusive,M >= I
,0 <= I, M < 65536
).
- Cycles: 0 (does not consume VM cycles).
- Notes:
- Prints the specified part of the VM state.
- Ignored if assembler is not in debug mode.