Assembler instruction reference
This page lists every instruction form accepted by the MB8 assembler. Mnemonics are ordered alphabetically. Forms within a mnemonic are ordered as core, immediate, label, and other pseudo forms.
Conventions
rD,rS,rA, andrBare 8-bit registers.rH:rLis a pair of 8-bit registers containing a 16-bit value.imm8andimm16are hexadecimal immediate values.off8is the encoded 8-bit value of a signed relative offset.labelis a label defined in the assembled program.- An immediate operand may also be supplied through a constant such as
@NAME. - Square brackets denote an address or a memory operand and are part of the syntax.
hi(value)andlo(value)are compiler expressions that select the high and low bytes.rel8(target)is the signed offset from the following instruction totarget.{id}is the unique source-instruction index used in compiler-generated labels.- Registers read and written list actual accesses made by the emitted instructions, including temporary accesses. Scratch registers state whether those temporary values are preserved.
Mnemonics
ADD · AND · CALL · CMP · DEC · HALT · INC · INC16 · JCR · JMP · JNCR · JNZR · JR · JZR · LD · LDI · MEMCPY · MOV · MUL · NOP · NOT · OR · POP · PUSH · RET · SHL · SHR · ST · STRCMP · SUB · SWAP · SYS · XOR · ZERO
ADD
ADD rD, rS
Kind: Core.
Operands: rD is the destination and left operand; rS is the right operand.
Compiles to:
ADD rD, rS
Operation: Adds rS to rD, stores the wrapped 8-bit result in rD, and updates arithmetic
flags.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C on
unsigned overflow.
AND
AND rD, rS
Kind: Core.
Operands: rD is the destination and left operand; rS is the right operand.
Compiles to:
AND rD, rS
Operation: Stores the bitwise AND of rD and rS in rD.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and clears C.
CALL
CALL [rH:rL]
Kind: Core.
Operands: rH:rL contains the absolute destination address.
Compiles to:
CALL [rH:rL]
Operation: Pushes the address of the following instruction and sets PC to the address in
rH:rL.
Registers read: rH, rL, PC, SPH, SPL.
Registers written: PC, SPH, SPL.
Scratch registers: None.
Stack: Pushes a two-byte return address; net stack-pointer change is -2 bytes.
Flags: Reads: None; writes: None.
CALL [imm16]
Kind: Pseudo.
Operands: imm16 is the absolute destination address.
Compiles to:
LDI IH, hi(imm16)
LDI IL, lo(imm16)
CALL [IH:IL]
Operation: Loads imm16 into IH:IL, pushes the address of the following instruction, and
sets PC to imm16.
Registers read: PC, SPH, SPL, IH, IL.
Registers written: IH, IL, PC, SPH, SPL.
Scratch registers: IH, IL are clobbered.
Stack: Pushes a two-byte return address; net stack-pointer change is -2 bytes.
Flags: Reads: None; writes: None.
CALL [label]
Kind: Pseudo.
Operands: label identifies the absolute destination address.
Compiles to:
LDI IH, hi(label)
LDI IL, lo(label)
CALL [IH:IL]
Operation: Loads the address of label into IH:IL, pushes the address of the following
instruction, and transfers control to label.
Registers read: PC, SPH, SPL, IH, IL.
Registers written: IH, IL, PC, SPH, SPL.
Scratch registers: IH, IL are clobbered.
Stack: Pushes a two-byte return address; net stack-pointer change is -2 bytes.
Flags: Reads: None; writes: None.
CMP
CMP rD, rS
Kind: Core.
Operands: rD is the left operand; rS is the right operand.
Compiles to:
CMP rD, rS
Operation: Computes rD - rS for flags without modifying either operand.
Registers read: rD, rS.
Registers written: F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the difference is zero, N from difference bit 7, and
C on unsigned underflow.
CMP rD, imm8
Kind: Pseudo.
Operands: rD is the left operand; imm8 is the right operand.
Compiles to:
PUSH A
LDI A, imm8
CMP rD, A
POP A
Operation: Compares rD with imm8 while preserving the original value of A.
Registers read: rD, A, SPH, SPL.
Registers written: A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when rD == imm8, N from difference bit 7, and C when
rD < imm8.
DEC
DEC rD
Kind: Pseudo.
Operands: rD is the register to decrement.
Compiles to:
PUSH A
LDI A, 0x01
SUB rD, A
POP A
Operation: Subtracts one from rD with 8-bit wrapping while preserving A.
Registers read: rD, A, SPH, SPL.
Registers written: rD, A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C when
the decrement underflows.
HALT
HALT
Kind: Core.
Operands: None.
Compiles to:
HALT
Operation: Stops VM execution with an encoded low byte of 0x00.
Registers read: None.
Registers written: None.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
HALT imm8
Kind: Core encoded form.
Operands: imm8 is placed in the low byte of the instruction.
Compiles to:
HALT imm8
Operation: Stops VM execution. The current processor ignores the encoded low byte after
decoding.
Registers read: None.
Registers written: None.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
INC
INC rD
Kind: Pseudo.
Operands: rD is the register to increment.
Compiles to:
PUSH A
LDI A, 0x01
ADD rD, A
POP A
Operation: Adds one to rD with 8-bit wrapping while preserving A.
Registers read: rD, A, SPH, SPL.
Registers written: rD, A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C when
the increment overflows.
INC16
INC16 rH:rL
Kind: Pseudo.
Operands: rH:rL contains the 16-bit value to increment.
Compiles to:
PUSH A
LDI A, 0xFF
CMP rL, A
POP A
JZR rel8(__mb8_inc16_hi_{id})
PUSH A
LDI A, 0x01
ADD rL, A
POP A
JR rel8(__mb8_inc16_end_{id})
__mb8_inc16_hi_{id}:
LDI rL, 0x00
PUSH A
LDI A, 0x01
ADD rH, A
POP A
__mb8_inc16_end_{id}:
NOP
Operation: Increments rH:rL; increments only rL unless it was 0xFF, in which case it
sets rL to zero and increments rH. A is preserved.
Registers read: rH, rL, A, F, PC, SPH, SPL.
Registers written: rH conditionally, rL, A, F, PC, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte at a time; maximum depth is 1 byte and net stack-pointer change
is 0.
Flags: Reads: Z for the generated branch; writes: Z, N, and C from the byte incremented
by the final ADD.
JCR
JCR off8
Kind: Core.
Operands: off8 is the encoded signed offset from the following instruction.
Compiles to:
JCR off8
Operation: Adds the signed offset to PC when C is set; otherwise continues at the following
instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JCR [imm16]
Kind: Pseudo.
Operands: imm16 is an absolute target address converted to a relative offset.
Compiles to:
JCR rel8(imm16)
Operation: Branches to imm16 when C is set. The target must fit a signed 8-bit offset from
the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JCR [label]
Kind: Pseudo.
Operands: label is converted to a relative offset.
Compiles to:
JCR rel8(label)
Operation: Branches to label when C is set. The target must fit a signed 8-bit offset from
the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JMP
JMP [rH:rL]
Kind: Core.
Operands: rH:rL contains the absolute destination address.
Compiles to:
JMP [rH:rL]
Operation: Sets PC to the 16-bit address in rH:rL.
Registers read: rH, rL.
Registers written: PC.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
JMP [imm16]
Kind: Pseudo.
Operands: imm16 is the absolute destination address.
Compiles to:
LDI IH, hi(imm16)
LDI IL, lo(imm16)
JMP [IH:IL]
Operation: Loads imm16 into IH:IL and transfers control to it.
Registers read: IH, IL.
Registers written: IH, IL, PC.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
JMP [label]
Kind: Pseudo.
Operands: label identifies the absolute destination address.
Compiles to:
LDI IH, hi(label)
LDI IL, lo(label)
JMP [IH:IL]
Operation: Loads the address of label into IH:IL and transfers control to it.
Registers read: IH, IL.
Registers written: IH, IL, PC.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
JNCR
JNCR off8
Kind: Core.
Operands: off8 is the encoded signed offset from the following instruction.
Compiles to:
JNCR off8
Operation: Adds the signed offset to PC when C is clear; otherwise continues at the
following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JNCR [imm16]
Kind: Pseudo.
Operands: imm16 is an absolute target address converted to a relative offset.
Compiles to:
JNCR rel8(imm16)
Operation: Branches to imm16 when C is clear. The target must fit a signed 8-bit offset
from the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JNCR [label]
Kind: Pseudo.
Operands: label is converted to a relative offset.
Compiles to:
JNCR rel8(label)
Operation: Branches to label when C is clear. The target must fit a signed 8-bit offset
from the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: C; writes: None.
JNZR
JNZR off8
Kind: Core.
Operands: off8 is the encoded signed offset from the following instruction.
Compiles to:
JNZR off8
Operation: Adds the signed offset to PC when Z is clear; otherwise continues at the
following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
JNZR [imm16]
Kind: Pseudo.
Operands: imm16 is an absolute target address converted to a relative offset.
Compiles to:
JNZR rel8(imm16)
Operation: Branches to imm16 when Z is clear. The target must fit a signed 8-bit offset
from the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
JNZR [label]
Kind: Pseudo.
Operands: label is converted to a relative offset.
Compiles to:
JNZR rel8(label)
Operation: Branches to label when Z is clear. The target must fit a signed 8-bit offset
from the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
JR
JR off8
Kind: Core.
Operands: off8 is the encoded signed offset from the following instruction.
Compiles to:
JR off8
Operation: Unconditionally adds the signed offset to PC.
Registers read: PC.
Registers written: PC.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
JR [imm16]
Kind: Pseudo.
Operands: imm16 is an absolute target address converted to a relative offset.
Compiles to:
JR rel8(imm16)
Operation: Branches to imm16. The target must fit a signed 8-bit offset from the following
instruction.
Registers read: PC.
Registers written: PC.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
JR [label]
Kind: Pseudo.
Operands: label is converted to a relative offset.
Compiles to:
JR rel8(label)
Operation: Branches to label. The target must fit a signed 8-bit offset from the following
instruction.
Registers read: PC.
Registers written: PC.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
JZR
JZR off8
Kind: Core.
Operands: off8 is the encoded signed offset from the following instruction.
Compiles to:
JZR off8
Operation: Adds the signed offset to PC when Z is set; otherwise continues at the following
instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
JZR [imm16]
Kind: Pseudo.
Operands: imm16 is an absolute target address converted to a relative offset.
Compiles to:
JZR rel8(imm16)
Operation: Branches to imm16 when Z is set. The target must fit a signed 8-bit offset from
the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
JZR [label]
Kind: Pseudo.
Operands: label is converted to a relative offset.
Compiles to:
JZR rel8(label)
Operation: Branches to label when Z is set. The target must fit a signed 8-bit offset from
the following instruction.
Registers read: F, PC.
Registers written: PC when the branch is taken.
Scratch registers: None.
Stack: None.
Flags: Reads: Z; writes: None.
LD
LD rD, [rH:rL]
Kind: Core.
Operands: rD is the destination; rH:rL contains the source address.
Compiles to:
LD rD, [rH:rL]
Operation: Reads one byte from memory at rH:rL into rD.
Registers read: rH, rL.
Registers written: rD.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
LD rD, [imm16]
Kind: Pseudo.
Operands: rD is the destination; imm16 is the source address.
Compiles to:
LDI IH, hi(imm16)
LDI IL, lo(imm16)
LD rD, [IH:IL]
Operation: Loads the address into IH:IL and reads one byte from it into rD.
Registers read: IH, IL.
Registers written: IH, IL, rD.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
LD rD, [label]
Kind: Pseudo.
Operands: rD is the destination; label identifies the source address.
Compiles to:
LDI IH, hi(label)
LDI IL, lo(label)
LD rD, [IH:IL]
Operation: Loads the address of label into IH:IL and reads one byte from it into rD.
Registers read: IH, IL.
Registers written: IH, IL, rD.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
LD rD, [rH:rL - imm8]
Kind: Pseudo.
Operands: rD is the destination; rH:rL is the base address; imm8 is subtracted from it.
Compiles to:
LDI A, imm8
SUB rL, A
JNCR rel8(__mb8_ld_no_borrow_{id})
PUSH A
LDI A, 0x01
SUB rH, A
POP A
__mb8_ld_no_borrow_{id}:
LD rD, [rH:rL]
Operation: Subtracts imm8 from rH:rL, leaves the adjusted address in the pair, and reads
one byte from that address into rD.
Registers read: rH, rL, A, F, PC, SPH, SPL.
Registers written: rH conditionally, rL, rD, A, F, PC conditionally, SPH, SPL.
Scratch registers: A is clobbered with imm8.
Stack: The borrow path uses one temporary byte; maximum depth is 1 byte and net stack-pointer
change is 0.
Flags: Reads: C for the generated branch; writes: Z, N, and C from subtracting
imm8 from rL, or from decrementing rH when a borrow occurs.
LDI
LDI rD, imm8
Kind: Core.
Operands: rD is the destination; imm8 is the byte to load.
Compiles to:
LDI rD, imm8
Operation: Stores imm8 in rD.
Registers read: None.
Registers written: rD.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
LDI rH:rL, imm16
Kind: Pseudo.
Operands: rH:rL is the destination pair; imm16 is the 16-bit value.
Compiles to:
LDI rH, hi(imm16)
LDI rL, lo(imm16)
Operation: Stores the high byte of imm16 in rH and the low byte in rL.
Registers read: None.
Registers written: rH, rL.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
LDI rH:rL, label
Kind: Pseudo.
Operands: rH:rL is the destination pair; label supplies its 16-bit address.
Compiles to:
LDI rH, hi(label)
LDI rL, lo(label)
Operation: Stores the high and low bytes of the address of label in rH:rL.
Registers read: None.
Registers written: rH, rL.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
MEMCPY
MEMCPY [dstH:dstL], [srcH:srcL], len
Kind: Pseudo.
Operands: dstH:dstL is the destination pointer, srcH:srcL is the source pointer, and len
is a register containing the last zero-based byte index.
Compiles to:
PUSH A
LDI A, 0x00
__mb8_memcpy_loop_{id}:
PUSH A
LD A, [srcH:srcL]
ST [dstH:dstL], A
POP A
CMP A, len
JZR rel8(__mb8_memcpy_end_{id})
PUSH R7
LDI R7, 0x01
ADD A, R7
POP R7
PUSH A
LDI A, 0xFF
CMP srcL, A
POP A
JZR rel8(__mb8_memcpy_src_{id}_hi)
PUSH A
LDI A, 0x01
ADD srcL, A
POP A
JR rel8(__mb8_memcpy_src_{id}_end)
__mb8_memcpy_src_{id}_hi:
LDI srcL, 0x00
PUSH A
LDI A, 0x01
ADD srcH, A
POP A
__mb8_memcpy_src_{id}_end:
NOP
PUSH A
LDI A, 0xFF
CMP dstL, A
POP A
JZR rel8(__mb8_memcpy_dst_{id}_hi)
PUSH A
LDI A, 0x01
ADD dstL, A
POP A
JR rel8(__mb8_memcpy_dst_{id}_end)
__mb8_memcpy_dst_{id}_hi:
LDI dstL, 0x00
PUSH A
LDI A, 0x01
ADD dstH, A
POP A
__mb8_memcpy_dst_{id}_end:
NOP
JR rel8(__mb8_memcpy_loop_{id})
__mb8_memcpy_end_{id}:
POP A
Operation: Copies len + 1 bytes. The source and destination pointers advance after every
byte except the last; A and R7 are restored.
Registers read: dstH, dstL, srcH, srcL, len, A, R7, F, PC, SPH, SPL.
Registers written: dstH, dstL, srcH, srcL, A, R7, F, PC, SPH, SPL.
Scratch registers: A and R7 are temporarily modified and restored.
Stack: Keeps the original A on the stack for the loop and uses one additional temporary byte;
maximum depth is 2 bytes and net stack-pointer change is 0.
Flags: Reads: Z and C in generated branches; writes: final Z = 1, N = 0, and C = 0
from the terminating equality comparison of the byte index with len.
MOV
MOV rD, rS
Kind: Core.
Operands: rD is the destination; rS is the source.
Compiles to:
MOV rD, rS
Operation: Copies the byte in rS to rD.
Registers read: rS.
Registers written: rD.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
MUL
MUL rD, rA, rB
Kind: Pseudo.
Operands: rD receives the product; rA is the repeated addend; rB is the iteration count.
Compiles to:
LDI rD, 0x00
PUSH rB
__mb8_mul_iter_{id}:
ADD rD, rA
PUSH A
LDI A, 0x01
SUB rB, A
POP A
PUSH A
LDI A, 0x00
CMP rB, A
POP A
JNZR rel8(__mb8_mul_iter_{id})
POP rB
Operation: Repeatedly adds rA to rD while decrementing rB to zero. The 8-bit result wraps;
the original values of rB and A are restored. An initial rB of zero performs 256 iterations.
Registers read: rA, rB, A, F, PC, SPH, SPL.
Registers written: rD, rB, A, F, PC, SPH, SPL.
Scratch registers: A and rB are temporarily modified and restored.
Stack: Keeps the original rB on the stack and uses one additional temporary byte; maximum
depth is 2 bytes and net stack-pointer change is 0.
Flags: Reads: Z for the generated loop branch; writes: final Z = 1, N = 0, and C = 0
from comparing the decremented rB with zero.
NOP
NOP
Kind: Core.
Operands: None.
Compiles to:
NOP
Operation: Advances to the following instruction without changing processor state.
Registers read: None.
Registers written: None.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
NOT
NOT rD
Kind: Pseudo.
Operands: rD is the register to invert.
Compiles to:
PUSH A
LDI A, 0xFF
XOR rD, A
POP A
Operation: Inverts every bit of rD while preserving A.
Registers read: rD, A, SPH, SPL.
Registers written: rD, A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when the inverted result is zero, N from result bit 7, and
clears C.
OR
OR rD, rS
Kind: Core.
Operands: rD is the destination and left operand; rS is the right operand.
Compiles to:
OR rD, rS
Operation: Stores the bitwise OR of rD and rS in rD.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and clears C.
POP
POP rD
Kind: Core.
Operands: rD is the destination register.
Compiles to:
POP rD
Operation: Increments the stack pointer and loads the byte at the new address into rD; halts
the VM on stack underflow.
Registers read: SPH, SPL.
Registers written: rD, SPH, SPL.
Scratch registers: None.
Stack: Pops one byte; net stack-pointer change is +1 byte.
Flags: Reads: None; writes: None.
PUSH
PUSH rS
Kind: Core.
Operands: rS is the source register.
Compiles to:
PUSH rS
Operation: Writes rS at the current stack pointer and decrements it; halts the VM on stack
overflow.
Registers read: rS, SPH, SPL.
Registers written: SPH, SPL.
Scratch registers: None.
Stack: Pushes one byte; net stack-pointer change is -1 byte.
Flags: Reads: None; writes: None.
RET
RET
Kind: Core.
Operands: None.
Compiles to:
RET
Operation: Pops a two-byte return address into PC; halts the VM on stack underflow.
Registers read: SPH, SPL.
Registers written: PC, SPH, SPL.
Scratch registers: None.
Stack: Pops two bytes; net stack-pointer change is +2 bytes.
Flags: Reads: None; writes: None.
SHL
SHL rD, rS
Kind: Core.
Operands: rD is the value and destination; rS contains the shift count.
Compiles to:
SHL rD, rS
Operation: Repeatedly shifts rD left by the count in rS, discarding high bits.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C from
the last high bit shifted out; C is clear for a zero shift count.
SHL rD, imm8
Kind: Pseudo.
Operands: rD is the value and destination; imm8 is the shift count.
Compiles to:
PUSH A
LDI A, imm8
SHL rD, A
POP A
Operation: Shifts rD left by imm8, preserving the original value of A.
Registers read: rD, A, SPH, SPL.
Registers written: rD, A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C from
the last high bit shifted out; C is clear for a zero shift count.
SHR
SHR rD, rS
Kind: Core.
Operands: rD is the value and destination; rS contains the shift count.
Compiles to:
SHR rD, rS
Operation: Repeatedly shifts rD right logically by the count in rS, inserting zero bits.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C from
the last low bit shifted out; C is clear for a zero shift count.
SHR rD, imm8
Kind: Pseudo.
Operands: rD is the value and destination; imm8 is the shift count.
Compiles to:
PUSH A
LDI A, imm8
SHR rD, A
POP A
Operation: Shifts rD right logically by imm8, preserving the original value of A.
Registers read: rD, A, SPH, SPL.
Registers written: rD, A, F, SPH, SPL.
Scratch registers: A is temporarily modified and restored.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C from
the last low bit shifted out; C is clear for a zero shift count.
ST
ST [rH:rL], rS
Kind: Core.
Operands: rH:rL contains the destination address; rS contains the byte to store.
Compiles to:
ST [rH:rL], rS
Operation: Writes rS to memory at the address in rH:rL.
Registers read: rH, rL, rS.
Registers written: None.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
ST [imm16], rS
Kind: Pseudo.
Operands: imm16 is the destination address; rS contains the byte to store.
Compiles to:
LDI IH, hi(imm16)
LDI IL, lo(imm16)
ST [IH:IL], rS
Operation: Loads imm16 into IH:IL and writes rS to that address.
Registers read: IH, IL, rS.
Registers written: IH, IL.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
ST [label], rS
Kind: Pseudo.
Operands: label identifies the destination address; rS contains the byte to store.
Compiles to:
LDI IH, hi(label)
LDI IL, lo(label)
ST [IH:IL], rS
Operation: Loads the address of label into IH:IL and writes rS to that address.
Registers read: IH, IL, rS.
Registers written: IH, IL.
Scratch registers: IH, IL are clobbered.
Stack: None.
Flags: Reads: None; writes: None.
STRCMP
STRCMP result, temp, srcH, srcL, dstH, dstL
Kind: Pseudo.
Operands: srcH:srcL and dstH:dstL point to zero-terminated strings; result receives the
comparison result; temp receives bytes from the second string.
Compiles to:
__mb8_strcmp_loop_{id}:
LD result, [srcH:srcL]
LD temp, [dstH:dstL]
CMP result, temp
JNZR rel8(__mb8_strcmp_error_{id})
PUSH A
LDI A, 0x00
CMP temp, A
POP A
JZR rel8(__mb8_strcmp_success_{id})
PUSH A
LDI A, 0xFF
CMP srcL, A
POP A
JZR rel8(__mb8_strcmp_src_{id}_hi)
PUSH A
LDI A, 0x01
ADD srcL, A
POP A
JR rel8(__mb8_strcmp_src_{id}_end)
__mb8_strcmp_src_{id}_hi:
LDI srcL, 0x00
PUSH A
LDI A, 0x01
ADD srcH, A
POP A
__mb8_strcmp_src_{id}_end:
NOP
PUSH A
LDI A, 0xFF
CMP dstL, A
POP A
JZR rel8(__mb8_strcmp_dst_{id}_hi)
PUSH A
LDI A, 0x01
ADD dstL, A
POP A
JR rel8(__mb8_strcmp_dst_{id}_end)
__mb8_strcmp_dst_{id}_hi:
LDI dstL, 0x00
PUSH A
LDI A, 0x01
ADD dstH, A
POP A
__mb8_strcmp_dst_{id}_end:
NOP
LDI IH, hi(__mb8_strcmp_loop_{id})
LDI IL, lo(__mb8_strcmp_loop_{id})
JMP [IH:IL]
__mb8_strcmp_error_{id}:
LDI result, 0x01
JR rel8(__mb8_strcmp_end_{id})
__mb8_strcmp_success_{id}:
LDI result, 0x00
__mb8_strcmp_end_{id}:
Operation: Compares the strings byte by byte. Writes 0 to result when both reach the same
zero terminator and 1 on the first mismatch. Address pairs advance after equal nonzero bytes;
temp retains the last byte read from the second string.
Registers read: srcH, srcL, dstH, dstL, result, temp, A, IH, IL, F, PC,
SPH, SPL.
Registers written: srcH, srcL, dstH, dstL, result, temp, A, IH, IL, F,
PC, SPH, SPL.
Scratch registers: A is temporarily modified and restored; IH and IL are clobbered when
the loop repeats.
Stack: Uses one temporary byte at a time; maximum depth is 1 byte and net stack-pointer change
is 0.
Flags: Reads: Z and C in generated branches; writes: on mismatch, retains Z = 0 with N
and C from result - temp; on equality, ends with Z = 1, N = 0, and C = 0 from comparing
the zero terminator with zero.
SUB
SUB rD, rS
Kind: Core.
Operands: rD is the destination and left operand; rS is the right operand.
Compiles to:
SUB rD, rS
Operation: Subtracts rS from rD, stores the wrapped 8-bit result in rD, and updates
arithmetic flags.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and C on
unsigned underflow.
SWAP
SWAP rA, rB
Kind: Pseudo.
Operands: rA and rB are the registers to exchange.
Compiles to:
PUSH rA
MOV rA, rB
POP rB
Operation: Exchanges the values in rA and rB.
Registers read: rA, rB, SPH, SPL.
Registers written: rA, rB, SPH, SPL.
Scratch registers: None.
Stack: Uses one temporary byte; maximum depth is 1 byte and net stack-pointer change is 0.
Flags: Reads: None; writes: None.
SYS
SYS
Kind: Core.
Operands: None.
Compiles to:
SYS
Operation: Executes the reserved system opcode. Its VM operation is currently unimplemented.
Registers read: None.
Registers written: None.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.
XOR
XOR rD, rS
Kind: Core.
Operands: rD is the destination and left operand; rS is the right operand.
Compiles to:
XOR rD, rS
Operation: Stores the bitwise XOR of rD and rS in rD.
Registers read: rD, rS.
Registers written: rD, F.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: Z when the result is zero, N from result bit 7, and clears C.
ZERO
ZERO rD
Kind: Pseudo.
Operands: rD is the register to clear.
Compiles to:
LDI rD, 0x00
Operation: Stores zero in rD.
Registers read: None.
Registers written: rD.
Scratch registers: None.
Stack: None.
Flags: Reads: None; writes: None.