objvm - asm0/asm1 bytecode syntax
The bytecode syntax is a variable length bytecode instruction where the given instruction defines the usage of the next byte in the sequence. This applies to the low level format and for asm0 and asm1 code formats.
Bytecode can be specified as multiple operations on a single line:
; jmp to code at 0x12+0x14
PUSH CONSTANT 0x12 PUSH CONSTANT 0x14 ADD DEC POP REGISTER(0x00) JMP REGISTER(0x00)
Multi-argument opcodes
Data in multi-argument opcodes is encoded with prefixes that define how it is used and the size of the data.
For example, PUSH CONSTANT 0x12
encodes to
0x40 0x00 0x12
. PUSH is a 1-argument op where the argument
is decoded by looking at the first bit after the operation.
The supporting bits here are:
- CONSTANT - the next value in the code is pushed directly on the stack as an 8bit int
- SPECIAL - the next value in the code is an index into the “SPECIAL TABLE”, which includes the zero-bit, the instruction pointer, the stack pointer.
- REGISTER - the next value in the code is an index into the “REGISTER TABLE”.
The following opcodes support this argument:
- PUSH - push onto stack
- POP - pop from stack into SPECIAL or REGISTER
- JMP, JNZ, JZE - jump to the position in code specified by the next value.
As of now there are no 2-argument ops but opcodes like
MOV %sp, %r0
can be simulated via POP and PUSH:
PUSH REGISTER 0x00
POP SPECIAL SP
Zero-argument operations
These operations typically operate on the stack and set one of the SPECIAL BITS.
They include:
- ADD, MUL, INC - sets the CARRY SPECIAL BIT, ZERO SPECIAL BIT after modifying the stack
- SUB, DIV, DEC - sets the ZERO SPECIAL BIT after modifying the stack
- DEBUGOP - a debug operation
- CALL - call a function external to the bytecode
- RET - returns to the last call on the call stack
SPECIAL IP considerations
An expression like PUSH SPECIAL IP
will reference the IP
at the PUSH setup. Any reference to SPECIAL IP will, at best afford,
start at the opcode boundary and not at the location of IP or
SPECIAL.