This appendix provides the complete instruction set reference for the Minichain virtual machine. Each instruction includes:
- Opcode number (hexadecimal byte value)
- Assembly syntax (how to write it in assembly code)
- Effect (what it does to VM state)
- Gas cost (computational cost)
- Usage examples and tips
Control the program counter and execution flow.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x00 | HALT | HALT | Stop execution successfully | 0 |
0x01 | NOP | NOP | Do nothing (no operation) | 0 |
0x02 | JUMP | JUMP Rtarget | Unconditional jump: PC = R[target] | 8 |
0x03 | JUMPI | JUMPI Rcond, Rtarget | Conditional jump: if R[cond] != 0, PC = R[target] | 8 |
0x04 | CALL | CALL Rtarget | Call subroutine: push return address to R14, jump to R[target] | 700 |
0x05 | RET | RET | Return from subroutine: jump to address in R14 | 8 |
0x0F | REVERT | REVERT | Abort execution with error | 0 |
Perform mathematical operations on register values.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x10 | ADD | ADD Rdst, Rs1, Rs2 | R[dst] = R[s1] + R[s2] (wrapping) | 2 |
0x11 | SUB | SUB Rdst, Rs1, Rs2 | R[dst] = R[s1] - R[s2] (wrapping) | 2 |
0x12 | MUL | MUL Rdst, Rs1, Rs2 | R[dst] = R[s1] * R[s2] (wrapping) | 3 |
0x13 | DIV | DIV Rdst, Rs1, Rs2 | R[dst] = R[s1] / R[s2] (unsigned, traps if Rs2 = 0) | 5 |
0x14 | MOD | MOD Rdst, Rs1, Rs2 | R[dst] = R[s1] % R[s2] (unsigned modulo) | 5 |
0x15 | ADDI | ADDI Rdst, Rsrc, imm | R[dst] = R[src] + imm (add immediate) | 2 |
Perform bit-level operations.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x20 | AND | AND Rdst, Rs1, Rs2 | R[dst] = R[s1] & R[s2] (bitwise AND) | 2 |
0x21 | OR | OR Rdst, Rs1, Rs2 | R[dst] = R[s1] | R[s2] (bitwise OR) | 2 |
0x22 | XOR | XOR Rdst, Rs1, Rs2 | R[dst] = R[s1] ^ R[s2] (bitwise XOR) | 2 |
0x23 | NOT | NOT Rdst, Rsrc | R[dst] = ~R[src] (bitwise NOT) | 2 |
0x24 | SHL | SHL Rdst, Rs1, Rs2 | R[dst] = R[s1] << R[s2] (logical left shift) | 5 |
0x25 | SHR | SHR Rdst, Rs1, Rs2 | R[dst] = R[s1] >> R[s2] (logical right shift) | 5 |
Compare values and produce boolean results (1 for true, 0 for false).
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x30 | EQ | EQ Rdst, Rs1, Rs2 | R[dst] = (R[s1] == R[s2]) ? 1 : 0 | 3 |
0x31 | NE | NE Rdst, Rs1, Rs2 | R[dst] = (R[s1] != R[s2]) ? 1 : 0 | 3 |
0x32 | LT | LT Rdst, Rs1, Rs2 | R[dst] = (R[s1] < R[s2]) ? 1 : 0 (unsigned) | 3 |
0x33 | GT | GT Rdst, Rs1, Rs2 | R[dst] = (R[s1] > R[s2]) ? 1 : 0 (unsigned) | 3 |
0x34 | LE | LE Rdst, Rs1, Rs2 | R[dst] = (R[s1] <= R[s2]) ? 1 : 0 | 3 |
0x35 | GE | GE Rdst, Rs1, Rs2 | R[dst] = (R[s1] >= R[s2]) ? 1 : 0 | 3 |
0x36 | ISZERO | ISZERO Rdst, Rsrc | R[dst] = (R[src] == 0) ? 1 : 0 | 3 |
Access temporary linear memory. Memory is fast and cheap, but data is lost when execution ends.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x40 | LOAD8 | LOAD8 Rdst, Raddr | R[dst] = Memory[R[addr]] (1 byte) | 3 |
0x41 | LOAD64 | LOAD64 Rdst, Raddr | R[dst] = Memory[R[addr]] (8 bytes, little-endian) | 3 |
0x42 | STORE8 | STORE8 Raddr, Rsrc | Memory[R[addr]] = R[src] (1 byte) | 3 |
0x43 | STORE64 | STORE64 Raddr, Rsrc | Memory[R[addr]] = R[src] (8 bytes, little-endian) | 3 |
0x44 | MSIZE | MSIZE Rdst | R[dst] = size of memory in bytes | 2 |
0x45 | MCOPY | MCOPY Rdst, Rsrc, Rlen | memcpy(R[dst], R[src], R[len]) | 3 + len |
Access persistent contract storage. Storage is slow and expensive, but data persists across transactions.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x50 | SLOAD | SLOAD Rdst, Rkey | R[dst] = Storage[R[key]] (persistent, 32-byte slot) | 100 |
0x51 | SSTORE | SSTORE Rkey, Rvalue | Storage[R[key]] = R[value] (persistent, 32-byte slot) | 5,000 or 20,000 |
Load constants and move data between registers.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x70 | LOADI | LOADI Rdst, imm64 | R[dst] = imm64 (load 64-bit constant) | 2 |
0x71 | MOV | MOV Rdst, Rsrc | R[dst] = R[src] (register copy) | 2 |
Query the execution environment and blockchain state.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0x80 | CALLER | CALLER Rdst | R[dst] = caller's address (as u64, truncated) | 2 |
0x81 | CALLVALUE | CALLVALUE Rdst | R[dst] = value sent with this call | 2 |
0x82 | ADDRESS | ADDRESS Rdst | R[dst] = this contract's address | 2 |
0x83 | BLOCKNUMBER | BLOCKNUMBER Rdst | R[dst] = current block number | 2 |
0x84 | TIMESTAMP | TIMESTAMP Rdst | R[dst] = current block timestamp | 2 |
0x85 | GAS | GAS Rdst | R[dst] = remaining gas | 2 |
Output values for debugging and logging.
| Opcode | Instruction | Syntax | Effect | Gas |
|---|
0xF0 | LOG | LOG Rsrc | Log R[src] value (appears in execution trace) | 2 |
Complete opcode listing sorted by category and number:
| Opcode | Mnemonic | Gas |
|---|
| 0x00 | HALT | 0 |
| 0x01 | NOP | 0 |
| 0x02 | JUMP | 8 |
| 0x03 | JUMPI | 8 |
| 0x04 | CALL | 700 |
| 0x05 | RET | 8 |
| 0x0F | REVERT | 0 |
| Opcode | Mnemonic | Gas |
|---|
| 0x10 | ADD | 2 |
| 0x11 | SUB | 2 |
| 0x12 | MUL | 3 |
| 0x13 | DIV | 5 |
| 0x14 | MOD | 5 |
| 0x15 | ADDI | 2 |
| Opcode | Mnemonic | Gas |
|---|
| 0x20 | AND | 2 |
| 0x21 | OR | 2 |
| 0x22 | XOR | 2 |
| 0x23 | NOT | 2 |
| 0x24 | SHL | 5 |
| 0x25 | SHR | 5 |
| Opcode | Mnemonic | Gas |
|---|
| 0x30 | EQ | 3 |
| 0x31 | NE | 3 |
| 0x32 | LT | 3 |
| 0x33 | GT | 3 |
| 0x34 | LE | 3 |
| 0x35 | GE | 3 |
| 0x36 | ISZERO | 3 |
| Opcode | Mnemonic | Gas |
|---|
| 0x40 | LOAD8 | 3 |
| 0x41 | LOAD64 | 3 |
| 0x42 | STORE8 | 3 |
| 0x43 | STORE64 | 3 |
| 0x44 | MSIZE | 2 |
| 0x45 | MCOPY | 3+N |
| Opcode | Mnemonic | Gas |
|---|
| 0x50 | SLOAD | 100 |
| 0x51 | SSTORE | 5K-20K |
| Opcode | Mnemonic | Gas |
|---|
| 0x70 | LOADI | 2 |
| 0x71 | MOV | 2 |
| Opcode | Mnemonic | Gas |
|---|
| 0x80 | CALLER | 2 |
| 0x81 | CALLVALUE | 2 |
| 0x82 | ADDRESS | 2 |
| 0x83 | BLOCKNUMBER | 2 |
| 0x84 | TIMESTAMP | 2 |
| 0x85 | GAS | 2 |
| Opcode | Mnemonic | Gas |
|---|
| 0xF0 | LOG | 2 |
The Minichain VM instruction set includes:
- 43 instructions across 9 categories
- Simple encoding (1-10 bytes per instruction)
- Register-based (16 general-purpose registers)
- Gas metered (prevents infinite loops)
- Memory + Storage (RAM vs Disk model)
- Minimal but complete: Only essential instructions, no redundancy
- Ethereum-inspired: Familiar to Solidity/EVM developers
- Register-based: More efficient than stack-based (fewer instructions needed)
- Learning-focused: Simple enough to understand completely
Counter pattern (most common smart contract):
LOADI R0, 0 ; Storage key 0
SLOAD R1, R0 ; Load counter
ADD R1, R1, R2 ; Increment
SSTORE R0, R1 ; Save back
Access control pattern:
LOADI R1, OWNER_ADDR ; Load owner
EQ R2, R0, R1 ; Check equality
JUMPI R2, authorized ; If equal, continue
REVERT ; Otherwise, abort
Loop pattern:
LT R5, R0, R10 ; R0 < R10?
JUMPI R5, loop ; If yes, continue
For implementation details, see: