Skip to main content
Version: 0.13 (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_mapval_count[K, ... ][K, ... ]Pushes number of elements in 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.

| 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 | | log_precompile | [COMM, TAG, PAD, ...] | [R1, R0, CAP_NEXT, ...] | 1 | Absorbs 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.