objvm - Useful constructs

Some useful constructs. All code samples are written in asm1/asm0

For/While loops

For loops can be implemented by decrementing a value on the stack while storing the start of your code block in a register.

We store the IP into the stack, add it to 0x0a to get the start of the code

DEC decrements the top of the stack and sets the Z flag if the value is zero.

All you have to make sure is that your own code POPs any existing values off the stack.

; i = 0x03; do { ...; i--; } while(i != 0);
PUSH CONSTANT(0x03)
PUSH SPECIAL IP PUSH CONSTANT 0x0a ADD POP REGISTER 0x00
    ... my code ...
    DEC
JNZ REGISTER 0x00

Data region/Code region separation

For asm0 and asm1, if you want data and code segment separation you need to create a header at the start of the code segment that calculates the position to jump to.

This is tedious as you have to know how big your data segment is to know where to jump to.

; position of the code we want to jump
; to is the size of our data region plus
; the size of this header, which is 0x0a
PUSH CONSTANT size-of-data ; size=3 cp=0
PUSH CONSTANT 0x0a         ; size=3 cp=3
ADD                        ; size=1 cp=6
JMP SPECIAL STACK          ; size=3 cp=7
; cp=0x0a

; data region
0xaa 0xaf 0xcc ...

; code region
POP ; start of code, empty the stack , cp=0x0a+size-of-data
...

Data region / Code region separation (2)

There could be another way of implementing this, where we have a data block called DATA REGION. once at 0x04 and once at the end of the data region. finding the code region means iterating the a value on the stack and reading the code until we find it.

While this seems excessive to embed in every raw bytecode file, we could essentially build a stage of our assembler in the bytecode itself.

(asm2 will have a better solution)

JMP CONSTANT 0x11 0x00
0x44 0x41 0x54 0x41
0x20 0x52 0x45 0x47
0x49 0x4f 0x4e 0x00

PUSH CONSTANT 0x00
STORE_IP REGISTER 0x00
  INC
  ; TODO: compare strings at 0x04 with the string at code pointer in stack.
  ; keep jumping
JNZ REGISTER(0x00)
PUSH CONSTANT 0x10 ADD ; skip to position after end of
JMP SPECIAL STACK

0x44 0x41 0x54 0x41
0x20 0x52 0x45 0x47
0x49 0x4f 0x4e 0x00
; code region
POP ; start of code, empty the stack , cp=0x0a+size-of-data
...