Skip to main content
Version: 0.12 (unstable)

Miden VM Instruction Reference

This page provides a comprehensive reference for Miden Assembly instructions.

Field Operations

Comparison Operations

InstructionStack InputStack OutputCyclesNotes
lte
lte.b
[b, a, ...][c, ...]15
16
c={1,if ab0,otherwisec = \begin{cases} 1, & \text{if } a \leq b 0, & \text{otherwise} \end{cases}
lt
lt.b
[b, a, ...][c, ...]14
15
c={1,if a<b0,otherwisec = \begin{cases} 1, & \text{if } a < b 0, & \text{otherwise} \end{cases}
gte
gte.b
[b, a, ...][c, ...]16
17
c={1,if ab0,otherwisec = \begin{cases} 1, & \text{if } a \geq b 0, & \text{otherwise} \end{cases}
gt
gt.b
[b, a, ...][c, ...]15
16
c={1,if a>b0,otherwisec = \begin{cases} 1, & \text{if } a > b 0, & \text{otherwise} \end{cases}
eq
eq.b
[b, a, ...][c, ...]1
1-2
c={1,if a=b0,otherwisec = \begin{cases} 1, & \text{if } a = b 0, & \text{otherwise} \end{cases}
neq
neq.b
[b, a, ...][c, ...]2
2-3
c={1,if ab0,otherwisec = \begin{cases} 1, & \text{if } a \neq b 0, & \text{otherwise} \end{cases}
eqw[A, B, ...][c, A, B, ...]15c={1,if ai=bi i{0,1,2,3}0,otherwisec = \begin{cases} 1, & \text{if } a_i = b_i\ \forall i \in \{0,1,2,3\} 0, & \text{otherwise} \end{cases}
is_odd[a, ...][b, ...]5b={1,if a is odd0,otherwiseb = \begin{cases} 1, & \text{if $a$ is odd} 0, & \text{otherwise} \end{cases}

Assertions and Tests

InstructionStack InputStack OutputCyclesNotes
assert[a, ...][...]1Removes aa if a=1a = 1. Fails if a1a \neq 1.
assertz[a, ...][...]2Removes aa if a=0a = 0. Fails if a0a \neq 0.
assert_eq[b, a, ...][...]2Removes a,ba, b if a=ba = b. Fails if aba \neq b.
assert_eqw[B, A, ...][...]11Removes A,BA, B if A=BA = B. Fails if ABA \neq B.

Note: Assertions can be parameterized with an error message (e.g., assert.err="Division by 0").

Arithmetic and Boolean Operations

InstructionStack InputStack OutputCyclesNotes
add
add.b
[b, a, ...][c, ...]1
1-2
c=(a+b)modpc = (a + b) \bmod p
sub
sub.b
[b, a, ...][c, ...]2
2
c=(ab)modpc = (a - b) \bmod p
mul
mul.b
[b, a, ...][c, ...]1
2
c=(ab)modpc = (a \cdot b) \bmod p
div
div.b
[b, a, ...][c, ...]2
2
c=(ab1)modpc = (a \cdot b^{-1}) \bmod p. Fails if b=0b = 0.
neg[a, ...][b, ...]1b=amodpb = -a \bmod p
inv[a, ...][b, ...]1b=a1modpb = a^{-1} \bmod p. Fails if a=0a = 0.
pow2[a, ...][b, ...]16b=2ab = 2^a. Fails if a>63a > 63.
exp.uxx
exp.b
[b, a, ...][c, ...]9+xx
9+log2(b)
c=abc = a^b. Fails if xxxx is outside [0,63)[0, 63). exp is exp.u64 (73 cycles).
ilog2[a, ...][b, ...]44b=log2(a)b = \lfloor \log_2(a) \rfloor. Fails if a=0a = 0.
not[a, ...][b, ...]1b=1ab = 1 - a. Fails if a>1a > 1.
and[b, a, ...][c, ...]1c=abc = a \cdot b. Fails if max(a,b)>1\max(a, b) > 1.
or[b, a, ...][c, ...]1c=a+babc = a + b - a \cdot b. Fails if max(a,b)>1\max(a, b) > 1.
xor[b, a, ...][c, ...]7c=a+b2abc = a + b - 2 \cdot a \cdot b. Fails if max(a,b)>1\max(a, b) > 1.

Extension Field Operations

All operations in this section are defined over the quadratic extension field Fp[x]/(x2x+2)\mathbb{F}_p[x] / (x^2 - x + 2), with modulus p=264232+1p = 2^{64} - 2^{32} + 1.

InstructionStack InputStack OutputCyclesNotes
ext2add[b1, b0, a1, a0, ...][c1, c0, ...]5c1=(a1+b1)modpc1 = (a1 + b1) \bmod p
c0=(a0+b0)modpc0 = (a0 + b0) \bmod p
ext2sub[b1, b0, a1, a0, ...][c1, c0, ...]7c1=(a1b1)modpc1 = (a1 - b1) \bmod p
c0=(a0b0)modpc0 = (a0 - b0) \bmod p
ext2mul[b1, b0, a1, a0, ...][c1, c0, ...]3c1=(a0+a1)(b0+b1)a0b0modpc1 = (a0 + a1)(b0 + b1) - a0b0 \bmod p
c0=a0b02a1b1modpc0 = a0b0 - 2a1b1 \bmod p
ext2neg[a1, a0, ...][a1', a0', ...]4a1=a1a1' = -a1
a0=a0a0' = -a0
ext2inv[a1, a0, ...][a1', a0', ...]8a=a1a' = a^{-1} in Fp[x]/(x2x+2)\mathbb{F}_p[x]/(x^2 - x + 2). Fails if a=0a = 0.
ext2div[b1, b0, a1, a0, ...][c1, c0, ...]11c=ab1c = a \cdot b^{-1} in Fp[x]/(x2x+2)\mathbb{F}_p[x]/(x^2 - x + 2). Fails if b=0b = 0.

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

InstructionStack InputStack OutputCyclesNotes
u32test[a, ...][b, a, ...]5b={1,if a<2320,otherwiseb = \begin{cases} 1, & \text{if } a < 2^{32} 0, & \text{otherwise} \end{cases}
u32testw[A, ...][b, A, ...]23b={1,if i{0,1,2,3},ai<2320,otherwiseb = \begin{cases} 1, & \text{if } \forall i \in \{0,1,2,3\}, a_i < 2^{32} 0, & \text{otherwise} \end{cases}
u32assert[a, ...][a, ...]3Fails if a232a \geq 2^{32}.
u32assert2[b, a,...][b, a,...]1Fails if a232a \geq 2^{32} or b232b \geq 2^{32}.
u32assertw[A, ...][A, ...]6Fails if any element of AA is 232\geq 2^{32}.
u32cast[a, ...][b, ...]2b=amod232b = a \bmod 2^{32}
u32split[a, ...][c, b, ...]1b=amod232b = a \bmod 2^{32}, c=a/232c = \lfloor a / 2^{32} \rfloor

Note: Assertions can be parameterized with an error message (e.g., assert.err="Division by 0").

Arithmetic Operations

InstructionStack InputStack OutputCyclesNotes
u32overflowing_add
u32overflowing_add.b
[b, a, ...][d, c, ...]1
2-3
c=(a+b)mod232c = (a + b) \bmod 2^{32}, d={1,if (a+b)2320,otherwised = \begin{cases} 1, & \text{if } (a + b) \geq 2^{32} 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32wrapping_add
u32wrapping_add.b
[b, a, ...][c, ...]2
3-4
c=(a+b)mod232c = (a + b) \bmod 2^{32}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32overflowing_add3[c, b, a, ...][e, d, ...]1d=(a+b+c)mod232d = (a+b+c) \bmod 2^{32}, e=(a+b+c)/232e = \lfloor (a+b+c)/2^{32} \rfloor. Undefined if max(a,b,c)232\max(a,b,c) \geq 2^{32}.
u32wrapping_add3[c, b, a, ...][d, ...]2d=(a+b+c)mod232d = (a+b+c) \bmod 2^{32}. Undefined if max(a,b,c)232\max(a,b,c) \geq 2^{32}.
u32overflowing_sub
u32overflowing_sub.b
[b, a, ...][d, c, ...]1
2-3
c=(ab)mod232c = (a - b) \bmod 2^{32}, d={1,if a<b0,otherwised = \begin{cases} 1, & \text{if } a < b 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32wrapping_sub
u32wrapping_sub.b
[b, a, ...][c, ...]2
3-4
c=(ab)mod232c = (a - b) \bmod 2^{32}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32overflowing_mul
u32overflowing_mul.b
[b, a, ...][d, c, ...]1
2-3
c=(ab)mod232c = (a \cdot b) \bmod 2^{32}, d=(ab)/232d = \lfloor(a \cdot b) / 2^{32}\rfloor. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32wrapping_mul
u32wrapping_mul.b
[b, a, ...][c, ...]2
3-4
c=(ab)mod232c = (a \cdot b) \bmod 2^{32}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32overflowing_madd[b, a, c, ...][e, d, ...]1d=(ab+c)mod232d = (a \cdot b+c) \bmod 2^{32}, e=(ab+c)/232e = \lfloor(a \cdot b+c) / 2^{32}\rfloor. Undefined if max(a,b,c)232\max(a,b,c) \geq 2^{32}.
u32wrapping_madd[b, a, c, ...][d, ...]2d=(ab+c)mod232d = (a \cdot b+c) \bmod 2^{32}. Undefined if max(a,b,c)232\max(a,b,c) \geq 2^{32}.
u32div
u32div.b
[b, a, ...][c, ...]2
3-4
c=a/bc = \lfloor a/b \rfloor. Fails if b=0b=0. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32mod
u32mod.b
[b, a, ...][c, ...]3
4-5
c=amodbc = a \bmod b. Fails if b=0b=0. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32divmod
u32divmod.b
[b, a, ...][d, c, ...]1
2-3
c=a/bc = \lfloor a/b \rfloor, d=amodbd = a \bmod b. Fails if b=0b=0. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.

Bitwise Operations

InstructionStack InputStack OutputCyclesNotes
u32and
u32and.b
[b, a, ...][c, ...]1
2
Bitwise AND. Fails if max(a,b)232\max(a,b) \geq 2^{32}.
u32or
u32or.b
[b, a, ...][c, ...]6
7
Bitwise OR. Fails if max(a,b)232\max(a,b) \geq 2^{32}.
u32xor
u32xor.b
[b, a, ...][c, ...]1
2
Bitwise XOR. Fails if max(a,b)232\max(a,b) \geq 2^{32}.
u32not
u32not.a
[a, ...][b, ...]5
6
Bitwise NOT. Fails if a232a \geq 2^{32}.
u32shl
u32shl.b
[b, a, ...][c, ...]18
3
c=(a2b)mod232c = (a \cdot 2^b) \bmod 2^{32}. Undefined if a232a \geq 2^{32} or b>31b > 31.
u32shr
u32shr.b
[b, a, ...][c, ...]18
3
c=a/2bc = \lfloor a / 2^b \rfloor. Undefined if a232a \geq 2^{32} or b>31b > 31.
u32rotl
u32rotl.b
[b, a, ...][c, ...]18
3
Rotate left. Undefined if a232a \geq 2^{32} or b>31b > 31.
u32rotr
u32rotr.b
[b, a, ...][c, ...]23
3
Rotate right. Undefined if a232a \geq 2^{32} or b>31b > 31.
u32popcnt[a, ...][b, ...]33Population count (Hamming weight). Undefined if a232a \geq 2^{32}.
u32clz[a, ...][b, ...]42Count leading zeros. Undefined if a232a \geq 2^{32}.
u32ctz[a, ...][b, ...]34Count trailing zeros. Undefined if a232a \geq 2^{32}.
u32clo[a, ...][b, ...]41Count leading ones. Undefined if a232a \geq 2^{32}.
u32cto[a, ...][b, ...]33Count trailing ones. Undefined if a232a \geq 2^{32}.

Comparison Operations

InstructionStack InputStack OutputCyclesNotes
u32lt
u32lt.b
[b, a, ...][c, ...]3
4
c={1,if a<b0,otherwisec = \begin{cases} 1, & \text{if } a < b 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32lte
u32lte.b
[b, a, ...][c, ...]5
6
c={1,if ab0,otherwisec = \begin{cases} 1, & \text{if } a \leq b 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32gt
u32gt.b
[b, a, ...][c, ...]4
5
c={1,if a>b0,otherwisec = \begin{cases} 1, & \text{if } a > b 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32gte
u32gte.b
[b, a, ...][c, ...]4
5
c={1,if ab0,otherwisec = \begin{cases} 1, & \text{if } a \geq b 0, & \text{otherwise} \end{cases}. Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32min
u32min.b
[b, a, ...][c, ...]8
9
c=min(a,b)c = \min(a,b). Undefined if max(a,b)232\max(a,b) \geq 2^{32}.
u32max
u32max.b
[b, a, ...][c, ...]9
10
c=max(a,b)c = \max(a,b). Undefined if max(a,b)232\max(a,b) \geq 2^{32}.

Stack Manipulation

Instructions for directly manipulating the operand stack. Only the top 16 elements are directly accessible.

InstructionStack InputStack OutputCyclesNotes
drop[a, ... ][ ... ]1Deletes the top stack item.
dropw[A, ... ][ ... ]4Deletes a word (4 elements) from the top of the stack.
padw[ ... ][0,0,0,0, ... ]4Pushes four 0 values onto the stack.
dup.n[ ..., a, ... ][a, ..., a, ... ]1-3Pushes 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, ... ]4Pushes 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-6Swaps 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, ... ]1Swaps 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 ... ]1Swaps words: 1st with 3rd, 2nd with 4th.
movup.n[ ..., a, ... ][a, ... ]1-4Moves the nth stack item (2-indexed) to the top. Valid for n in 2..=15.
movupw.n[ ..., A, ... ][A, ... ]2-3Moves the nth stack word (2-indexed) to the top. Valid for n in 2..=3.
movdn.n[a, ... ][ ..., a, ... ]1-4Moves the top stack item to the nth position (2-indexed). Valid for n in 2..=15.
movdnw.n[A, ... ][ ..., A, ... ]2-3Moves the top stack word to the nth word position (2-indexed). Valid for n in 2..=3.

Conditional Manipulation

InstructionStack InputStack OutputCyclesNotes
cswap[c, b, a, ... ][e, d, ... ]1If c = 1, d=b, e=a. If c = 0, d=a, e=b. Fails if c > 1.
cswapw[c, B, A, ... ][E, D, ... ]1If c = 1, D=B, E=A. If c = 0, D=A, E=B. Fails if c > 1.
cdrop[c, b, a, ... ][d, ... ]2If c = 1, d=b. If c = 0, d=a. Fails if c > 1.
cdropw[c, B, A, ... ][D, ... ]5If 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

InstructionStack InputStack OutputCyclesNotes
push.a...[ ... ][c, b, a, ...]1-2Pushes 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

InstructionStack InputStack OutputCyclesNotes
clk[ ... ][t, ... ]1Pushes current clock cycle t.
sdepth[ ... ][d, ... ]1Pushes current stack depth d.
caller[A, b,...][H, b,...]1In context 0, overwrites the top 4 stack items with hash H of the function that syscall'd into the current context, or [0, 0, 0, 0] when not servicing a SYSCALL. In any other context, H corresponds to the hash of the function that entered the current context.
locaddr.i[ ... ][a, ... ]2Pushes absolute memory address a of local memory at index i.
procref.name[ ... ][A, ... ]4Pushes MAST root A of procedure name.

Nondeterministic Inputs (Advice Provider)

Reading from Advice Stack

InstructionStack InputStack OutputCyclesNotes
adv_push.n[ ... ][a, ...]nPops 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, ...]1Pops 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',...]1Pops 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:

InstructionStack InputStack OutputNotes
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:

InstructionStack InputStack OutputNotes
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

InstructionStack InputStack OutputCyclesNotes
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_be
mem_loadw_be.a
[a, 0,0,0,0,...][A, ... ]1
2
A ← mem[a..a+3] (word, big-endian). 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_loadw_le
mem_loadw_le.a
[a, 0,0,0,0,...][A, ... ]4
5
A ← mem[a..a+3] (word, little-endian). Overwrites top 4 stack elements (mem[a] is top). Equivalent to mem_loadw_be reversew. 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_be
mem_storew_be.a
[a, A, ... ][A, ... ]1
2-3
mem[a..a+3] ← A. Stores word A in big-endian order (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_storew_le
mem_storew_le.a
[a, A, ... ][A, ... ]9
8-9
mem[a..a+3] ← A. Stores word A in little-endian order (top stack element at mem[a]). Equivalent to reversew mem_storew_be reversew. 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 2162^{16} locals per procedure, 23112^{31} - 1 total. Rounded up to multiple of 4.

InstructionStack InputStack OutputCyclesNotes
loc_load.i[ ... ][v, ... ]5-6v ← local[i]. Pushes element from local memory at index i.
loc_loadw_be.i[0,0,0,0, ...][A, ... ]5-6A ← local[i..i+3]. Reads word in big-endian order, local[i+3] is top of stack. Fails if i not multiple of 4.
loc_loadw_le.i[0,0,0,0, ...][A, ... ]9-10A ← local[i..i+3]. Reads word in little-endian order, local[i] is top of stack. Equivalent to loc_loadw_be reversew. Fails if i not multiple of 4.
loc_store.i[v, ... ][ ... ]6-7local[i] ← v. Pops v to local memory at index i.
loc_storew_be.i[A, ... ][A, ... ]5-6local[i..i+3] ← A. Stores word in big-endian order, top stack element at local[i+3].
loc_storew_le.i[A, ... ][A, ... ]13-14local[i..i+3] ← A. Stores word in little-endian order, top stack element at local[i]. Equivalent to reversew loc_storew_be reversew.

Cryptographic Operations

Common cryptographic operations, including hashing and Merkle tree manipulations using Rescue Prime Optimized.

Hashing and Merkle Trees

InstructionStack InputStack OutputCyclesNotes
hash[A, ...][B, ...]20B ← hash(A). 1-to-1 Rescue Prime Optimized hash.
hperm[B, A, C, ...][F, E, D, ...]1D,E,F ← permute(C,A,B). Rescue Prime Optimized permutation. C=capacity, A,B=rate, E=digest.
hmerge[B, A, ...][C, ...]16C ← hash(A,B). 2-to-1 Rescue Prime Optimized hash.
mtree_get[d, i, R, ...][V, R, ...]9Verifies 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', ...]29Updates 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, ...]16Merges 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,...]1Verifies 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:
    if.true
    # instructions for true branch
    else
    # instructions for false branch
    end
    Or with if.false (condition inverted). The else block is optional.
  • Stack Input: [cond, ...] (where cond 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 if cond = 1, second (else) block if cond = 0.
    • if.false: Executes first block if cond = 0, second (else) block if cond = 1.
    • Empty or elided branches are treated as a nop.
    • Ensure stack consistency at join points if modifications persist beyond a branch.

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, ...] (where cond is 0 or 1)
  • Cycles: Overhead per iteration for condition check.
  • Notes:
    1. Pops cond from the stack. If 0, skips loop. Fails if not boolean.
    2. If cond = 1, executes loop body.
    3. After body execution, pops a new cond. If 1, repeats body. If 0, exits loop. Fails if not boolean.

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 in if statements.

Events

Instructions for communicating with the host through events and tracing.

InstructionStack InputStack OutputCyclesNotes
emit.<event_id>[...][...]3Emits 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, ...]1Emits 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>[...][...]0Emits 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
log_precompile[COMM, TAG, PAD, ...][R1, R0, CAP_NEXT, ...]1Absorbs a precompile commitment into the transcript used for deferred verification. Takes a precompile commitment (TAG and COMM) from the stack and performs an RPO256 permutation to update the transcript capacity (sponge capacity). Outputs [R1, R0, CAP_NEXT]; callers normally drop all three words immediately. See “Precompile flow” for initialization details.

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 top N stack items (0 < N < 256).
    • debug.mem: Prints entire RAM.
    • debug.mem.A: Prints memory at address A.
    • debug.mem.A.M: Prints memory from address A to M (inclusive, M >= A).
    • debug.local: Prints entire local memory of the current procedure.
    • debug.local.I: Prints local memory at index I (0 <= I < 65536).
    • debug.local.I.M: Prints local memory from index I to M (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.