Cybiko Bytecode Interpreter

The bytecode assembler (included in the SDK) converts .ASM files into .APP files that run on the Cybiko

Command line:

vas [options ] <infile>

options:

-i display version information (logo),
-d disassemble its own output to stdout (check output integrity),
-h display help (usage info, currently quite terse, to say the least),
-o outfile name output file (stdout by default).
-O Optimize output assembler code
-v Verbose mode – statistic messages about module to be compiled will be generated

Also:

Registers

R0 (accumulator/pointer for indirect loads),

R1 (aux data register/pointer for indirect saves),

Instruction Set

seteq

Compares R0 to R1, sets R0 to 1 if registers are equal, or to 0 otherwise.

setlt

Compares R0 to R1, sets R0 to 1 if R1 is less than R0, or to 0 otherwise.

setle

Compares R0 to R1, sets R0 to 1 if R1 is less than or equal to R0, or to 0 otherwise.

setgt

Compares R0 to R1, sets R0 to 1 if R1 is greater than R0, or to 0 otherwise.

setge

Compares R0 to R1, sets R0 to 1 if R1 is greater than or equal to R0, or to 0 otherwise.

setz

Tests R0 and sets it to 1 if it was zero, or to 0 otherwise, effectively performing 'logical not' upon contents of R0. Roughly equivalent to the following opcode sequence: move load0 seteq.

setnz

Tests R0 and sets it to 1 if it was non-zero; roughly equivalent to the following opcode sequence: move load0 setne. This is effectively 'convert to boolean' operator performed upon contents of R0.

cmpe.c <num>

Compares R1 to signed byte <num> (-128..127), sets R0 to 1 if they are equal, or to 0 otherwise. Same as the 'load.c <num> seteq' sequence but more efficient.

cmpe.s

Compares R1 to signed word <num> (-32768..32767), sets R0 to 1 if they are equal, or to 0 otherwise. Same as the 'load.s <num> seteq' sequence but more efficient.

cmpe.l <num>

Compares R1 to signed double word <num>, sets R0 to 1 if they are equal, or to 0 otherwise. Same as the 'load.l <num> seteq' sequence but more efficient.

switch

After this opcode, there must be a table of 16-bit words formed with the respective number of .disp directives, which denote jump displacements for switch values 0, 1, 2, etc. Number of .disp directives must not be less than maximum switch value expected. No bound checks are currently performed at run time (for the sake of effectiveness), so use of this opcode may be tricky! Used for switchfast C statement implementation.

jump.c <label>

Unconditional branch to instruction that is within the -128..127 range relative to the instruction immediately following this one. If target <label>is not within the reach of this instruction, assemble will try to use its 'long' counterpart, jump.s.

jumpz.c <label>

If R0 is zero, then branch to instruction that is within the -128..127 range relative to the instruction immediately following this one. If target <label> is not within the reach of this instruction, assemble will try to use its 'long' counterpart, jumpz.s.

jumpnz.c <label>

If R0 is not zero, then branch to instruction that is within the -128..127 range relative to the instruction immediately following this one. If target <label> is not within the reach of this instruction, assemble will try to use its 'long' counterpart, jumpnz.s.

jump.s <label>

Unconditional branch to instruction that is within the -32768..32767 range relative to the instruction immediately following this one.

jumpz.s <label>

If R0 is zero, then branch to instruction that is within the -32768..32767 range relative to the instruction immediately following this one.

jumpnz.s <label>

If R0 is not zero, then branch to instruction that is within the -32768..32767 range relative to the instruction immediately following this one.

calln.s <label>

Push address of the instruction immediately following call itself on stack, then jump to the instruction that is within the -32768..32767 range from the immediately following one.

calli

Indirect call: push address of the instruction immediately following call itself on stack, then jump to the instruction whose address is currently within R1.

callx.b <index>

Call extension functions represented with its index within the table of extension functions.

calls12.w <index>

Call the CyOS function which takes 0, 1, or 2 arguments. For 1-argument system functions, simply evaluate (just before call) the necessary expression so that the evaluation result is in R0, then use calls12.w. For 2-argument functions, evaluate the second argument, use move, then evaluate the first argument, then use calls12.w (or, if R1 is likely to be lost in the process of evaluation of the first argument, evaluate second argument, use push, evaluate first argument, use pop, then use calls12.w).

calls3.w <index>

Calls CyOS function which takes 3 or more arguments. This opcode first pops 3-rd off the stack, then acts exactly as calls12.w. So you must first evaluate and push arguments 3 and beyond in reverse order, then evaluate arguments 2 and 1, as shown above, then use calls3.w.

calld12.w <index>

Calls function located within CyOS dynamic library or even application that exports [some of] its functions. Very similar to calls12.w and even uses the same calling convention. However, it differs in that is must be immediately followed by the .disp directive which should define offset to a 4-byte static variable that holds address of export table of respective dynamic library. It is that table that is indexed with argument <index>.

calld3.w <index>

Just like calld12.w, calls function located within CyOS dynamic library or even application that exports [some of] its functions. Very similar to calls12.w (uses the same calling convention) and to calld12.w (requires .disp directive); see these opcodes for details.

retf

"Return far" — return from vm_exec().

retn

"Return near" — return from function called via calln.s.

retn.c <num>

Same as retn, but pop arguments off the stack upon return (here, <num> is number to be added to stack pointer just before return).

stack.c <num>

Add -128..127 to stack pointer.

push

Push R0.

pop

Pop R1.

popadd

The same as consequitive execution of pop and add operations. New in virtual machine version 11 (included in SysPack 55).

move

Move R0 to R1; same as "push pop" sequence, but by far more efficient. The "push pop" sequence, however, may also be more convenient sometimes, since it allows you to preserve R1. See calls12.w opcode description.

load0

Load 0 (zero) into R0.

load1

Load 1 (one) into R0.

load.c <num>

Load -128..127 into R0.

load.s <num>

Load -32768..32767 into R0.

load.l <num>

Load double word into R0.

loadic.b <num>

As same as loadic, but the parameter of this operation will be added to the byte pointer before execution. New in virtual machine version 11 (included in SysPack 55).

loadis.b <num>

As same as loadic, but the parameter of this operation will be added to the word pointer before execution. New in virtual machine version 11 (included in SysPack 55).

loadil.b <num>

As same as loadic, but the parameter of this operation will be added to the double word pointer before execution. New in virtual machine version 11 (included in SysPack 55).

leal.b <offset> <displacement>

Load effective address of 'auto' variable into R0.

leat.b <offset> <displacement>

Load effective address of 'object' variable into R0. If byte-sized offset specified in the instruction is 0, then such instruction actually means 'load this into R0'. Compilers for C++ and other OO languages may make use of this feature.

leag.u <label> <displacement>

Load effective address of 'static' variable or function into R0. If effective address is before, assemble will try to use its 'back' counterpart, leagb.u.

loadic

Load char pointed to by contents of R0 into R0.

loadis

Load short pointed to by contents of R0 into R0.

loadil

Load long pointed to by contents of R0 into R0.

storeic

Store char contained in R0 at the address pointed to by contents of R1.

storeis

Store short contained in R0 at the address pointed to by contents of R1.

storeil

Store long contained in R0 at the address pointed to by contents of R1.

loadlc.b <offset> <displacement>

Load char located at the address 'stack pointer' + 'next byte', into R0.

loadls.b <offset> <displacement>

Load short located at the address 'stack pointer' + 'next byte', into R0.

loadll.b <offset> <displacement>

Load long located at the address 'stack pointer' + 'next byte', into R0.

loadtc.b <offset> <displacement>

Load char located at the address 'this' + 'next byte', into R0.

loadts.b <offset> <displacement>

Load short located at the address 'this' + 'next byte', into R0.

loadtl.b <offset> <displacement>

storelc.b <offset> <displacement>

Store char from R0 at the address 'stack pointer' + 'next byte'.

storels.b <offset> <displacement>

Store short from R0 at the address 'stack pointer' + 'next byte'.

storell.b <offset> <displacement>

Store long from R0 at the address 'stack pointer' + 'next byte'.

storetc.b <offset> <displacement>

Store char from R0 at the address 'this' + 'next byte'.

storets.b <offset> <displacement>

Store short from R0 at the address 'this' + 'next byte'.

storetl.b <offset> <displacement>

Store long from R0 at the address 'this' + 'next byte'.

loadgc.u <label> <displacement>

Combines leag.u and loadic

loadgs.u <label> <displacement>

Combines leag.u and loadis

loadgl.u <label> <displacement>

Combines leag.u and loadil

load0p

Combines load0 and push.

load1p

Combines load1 and push.

loadp.c

Combines load.c and push.

loadp.s

Combines load.s and push.

loadp.l

Combines load.l and push.

lealp.b

Combines leal.b and push.

leatp.b

Combines leat.b and push.

leagp.s

Combines leag.u and push.

loadicp

Combines loadic and push.

loadisp

Combines loadis and push.

loadilp

Combines loadil and push.

loadlcp.b

Combines loadlc.b and push.

loadlsp.b

Combines loadls.b and push.

loadllp.b

Combines loadll.b and push.

loadtcp.b

Combines loadtc.b and push.

oadtsp.b

Combines loadts.b and push.

loadtlp.b

Combines loadtl.b and push.

loadgcp.s

Combines loadgc.u and push.

loadgsp.s

Combines loadgs.u and push.

loadglp.s

Combines loadgl.u and push.

load0m

Combines load0 and move.

load1m

Combines load1 and move.

loadm.c

Combines load.c and move.

loadm.s

Combines load.s and move.

loadm.l

Combines load.l and move.

lealm.b

Combines leal.b and move.

leatm.b

Combines leat.b and move.

leagm.s

Combines leag.u and move.

loadicm

Combines loadic and move.

loadism

Combines loadis and move.

loadilm

Combines loadil and move.

loadlcm.b

Combines loadlc.b and move.

loadlsm.b

Combines loadls.b and move.

oadllm.b

Combines loadll.b and move.

loadtcm.b

Combines loadtc.b and move.

loadtsm.b

Combines loadts.b and move.

loadtlm.b

Combines loadtl.b and move.

loadgcm.s

Combines loadgc.u and move.

loadgsm.s

Combines loadgs.u and move.

loadglm.s

Combines loadgl.u and move.

inc1

Add 1 to R0.

inc2

Add 2 to R0.

inc4

Add 4 to R0.

incic1

Add to byte addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

incis1

Add to word addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

incil1

Add to double word addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

dec1

Subtract 1 from R0.

dec2

Subtract 2 from R0.

dec4

Subtract 4 from R0.

decic1

Subtruct 1 from byte addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

decis1

Subtruct 1 from word addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

decil1

Subtract 1 from double word addressed by eR0 register. New in virtual machine version 11 (included in SysPack 55).

patch

Some words after this opcode are a list of patches. A zero word (.word 0) is a marker of the end of the list. Every word is a relative offset of a label (.disp). Every label is a label of ".ldisp" (address of variable). To each value of .ldisp the absolute address following it byte will be added. New in virtual machine version 11 (included in SysPack 55).

lshift1

Arithmetically shift R0 left by 1 bit.

lshift2

Arithmetically shift R0 left by 2 bits.

rshift1

Arithmetically shift R0 right by 1 bit.

rshift2

Arithmetically shift R0 right by 2 bits.

add

Add R1 to R0, result in R0.

add.c <num>

Add -128..127 to R0, result in R0.

add.s <num>

Add -32768..32767 to R0, result in R0.

add.l <num>

Add double word to R0, result in R0.

sub

Subtract R0 from R1 (!), result in R0.

neg

Negate R0.

mul

Multiply R0 by R1, result in R0.

mul.c

Multiply eR0 by parameter of this command. New in virtual machine version 11 (included in SysPack 55).

muladd.c

As same as consequtive execution of "mul.c" and "add" commands. New in virtual machine version 13 (included in SysPack 56).

jumple.c

Jump, if eR0 <= eR1. In that case eR0 = 0 after execution, otherwise eR0 = 1. New in virtual machine version 13 (included in SysPack 56).

jumpge.c

Jump, if eR0 >= eR1. In that case eR0 = 0 after execution, otherwise eR0 = 1. New in virtual machine version 13 (included in SysPack 56).

div

Divide R1 by R0 (!), result in R0.

mod

Divide R1 by R0 (!), remainder (result) in R0.

and

Bitwise AND of R0 and R1, result in R0.

or

Bitwise OR of R0 and R1, result in R0.

xor

Bitwise eXclusive OR of R0 and R1, result in R0.