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_ext2intt | [osize,isize,iptr,...] | [osize,isize,iptr,...] | Interpolates polynomial evaluations (from memory at iptr , isize evals) and pushes coefficients (osize ) 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.
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.