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 nth 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 nth 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 nth 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 nth 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 nth stack item (2-indexed) to the top. Valid for n in 2..=15. |
movupw.n | [ ..., A, ... ] | [A, ... ] | 2-3 | Moves the nth 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 nth position (2-indexed). Valid for n in 2..=15. |
movdnw.n | [A, ... ] | [ ..., A, ... ] | 2-3 | Moves the top stack word to the nth 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 - 3 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. |
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_hqword | [D, C, B, A, ... ] | [D, C, B, A, ... ] | K ← hash(hash(hash(A || B) || C) || D), domain=0. advice_map[K] ← [A,B,C,D]. |
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 with
if.true
# instructions for true branch
else
# instructions for false branch
endif.false(condition inverted). Theelseblock is optional. - Stack Input:
[cond, ...](wherecondis 0 or 1) - Cycles: Incurs a small overhead. For simple conditionals,
cdropmight be more efficient if side-effects can be managed. - Notes:
- Pops
condfrom 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
COUNTtimes during compilation. - Notes:
COUNTmust 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, ...](wherecondis 0 or 1) - Cycles: Overhead per iteration for condition check.
- Notes:
- Pops
condfrom 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
nopfor empty/elided branches inifstatements.
Events
Instructions for communicating with the host through events and tracing.
| Instruction | Stack Input | Stack Output | Cycles | Notes |
|---|---|---|---|---|
emit.<event_id> | [...] | [...] | 3 | Emits an event with the specified event_id to the host. The net effect on the operand stack is no change (internally expands to push.<event_id> emit drop). Immediate event_id must be defined via const.ID=event("...") or inlined as emit.event("..."). Events allow programs to communicate contextual information to the host for triggering appropriate actions. Example: emit.event("foo") or emit.MY_EVENT |
emit | [event_id, ...] | [event_id, ...] | 1 | Emits an event using the event_id from the top of the stack. The stack remains unchanged as the event_id is read without consuming it. This instruction reads the event ID from the stack but does not modify the stack depth. Example: with push.1230 on stack, emit reads the event ID 1230 and executes the corresponding event handler. Note that event IDs in the range 0..256 are reserved for system events. |
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 topNstack items (0 < N < 256).debug.mem: Prints entire RAM.debug.mem.A: Prints memory at addressA.debug.mem.A.M: Prints memory from addressAtoM(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 indexItoM(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.