[virtmach] CHIP (My VM)
Fri, 16 Mar 2001 13:47:46 -0700
Iv'e been playing around with my vm
and have improved it a bit, and was wondering
if anyone would like to play with it for me.
Ive done some testing and havent found any bugs,
but Im sure there must be some :)
Its available at: (get v0.3)
inorder to run the tso.cxe example
you must get and install Allegro WIP
unfortunatly chip has only been tested on
linux and most likely wont compile on any
other OS without some tweeking.
In case any one needs more info, here it is:
CHIP and Casm INFO.
Ins Args Desc
NOOP 0 Does nothing.
MUL 2 8bit Multiply arg2 with arg1 (arg1 *= arg2)
DIV 2 8bit Divide arg2 with arg1 (arg1 /= arg2)
MOD 2 8bit Modulo arg2 with arg1 (arg1 %= arg2)
ADD 2 8bit Add arg2 with arg1 (arg1 += arg2)
SUB 2 8bit Subtract arg2 with arg1 (arg1 -= arg2)
MOV 2 8bit Copy arg2 to arg1
PUT 1 Puts a character to stdout. (non buffered)
GET 1 Gets a character from stdin (non buffered, noecho)
OR 2 8bit bitwise OR ( | )
XOR 2 8bit bitwise XOR ( ^ )
AND 2 8bit bitwise AND ( & )
POP 1 Pops a value off the stack to arg
POP0 0 Pops a value off the stack and forgets it (same as DEC
PUSH 1 Pushes a value to the stack
MULL 2 32bit Multiply arg2 with arg1 (arg1 *= arg2)
DIVL 2 32bit Divide arg2 with arg1 (arg1 /= arg2)
MODL 2 32bit Modulo arg2 with arg1 (arg1 %= arg2)
ADDL 2 32bit Add arg2 with arg1 (arg1 += arg2)
SUBL 2 32bit Subtract arg2 with arg1 (arg1 -= arg2)
INC 1 Increment arg (++arg)
DEC 1 Deincrement arg (--arg)
DUMP 0 Dumps the register values to stdout
MOVL 2 32bit Copy arg2 to arg1
JMP 1 Unconditional jump to arg
CMP 2 Compare arg1 to arg2
JE 1 Jump to arg if last CMP result was equal
JNE 1 Jump to arg if last CMP result was not equal
JL 1 Jump to arg if last CMP result was less than
JLE 1 Jump to arg if last CMP result was less than or equal
JG 1 Jump to arg if last CMP result was greater than
JG 1 Jump to arg if last CMP result was greater than or
LOOP 1 Loop to arg for times specified in register C
CALL* 1 Call 'function' arg.
RET* 1 Return from a 'function' and push arg to stack
HLT 0 Stops CHIP.
ORL 2 32bit bitwise OR ( | )
XORL 2 32bit bitwise XOR ( ^ )
ANDL 2 32bit bitwise AND ( & )
SHR 1 Bitwise right shift ( >> )
SHL 1 Bitwise left shift ( << )
XCHG 2 Exchanges the values of it's two arguments
LOR 2 Logical OR ( || )
LAND 2 Logical AND ( && )
INT* 1 Calls CHIP's 'BIOS' function 'arg' (returns nothing)
CALLEX* 1 Calls CHIP's 'BIOS' function 'arg' (returns int)
Aditional Instruction Information:
CALL is almost like JMP except that all the registers
are pushed on to the stack and arguments pushed onto
the stack before CALL are available in reverse order
using a '$' followed by a number, so arg $1 is the last
argument that was pushed onto the stack.
Also the CALLer is responsible for removing arguments
it provided to the CALLed 'function'.
All CALLed 'functions' must use RET to restore
the original register values.
After a 'function' RETurns it's return value
is PUSHed onto the stack. A POP is all that is needed to retrive it.
Any code that uses CALL must POP the return value
of the stack, or the stack can become extreamly
INT is basically a hack to easily add instructions
that don't need to be added directly to CHIP.
These extra 'instructions' are added by the program
that is using CHIP, i.e: [out|in]portb functionality
or setting SIG* callbacks.
There are 36 general registers %AA through %FF, and
one StackPointer (SP) register.
You must prefix all the general registers with %,
the SP register can be preixed by % but it is not required.
The first 6 registers can be abriviated as %A through %F
All registers can be preceded by MEM or ST (including SP :),
which refrences the value in the register to
a memory address or stack address in that order.
(you get the value at the memory/stack addr)
Also all general registers can be signed or unsigned and
bisected into thier individual 'words' (16 bits un/signed)
and those can be bisected into thier individual bytes
(8 bits un/signed).
The format for registers is:
%AA (short form for signed long int register 0, or just %A)
%AAUW1 (for unsigned high word of register 0, or just %AUW1)
%AAUW0 (for same as above but low word.)
Generally registers, memory addresses, '$' args, and
literal integers can be used as a parameter to any
instruction, with these exceptions:
1. A parameter can not be a literal integer if that parameter
gets modified by the instruction.
2. The second parameter for DIV DIVL MOD and MODL can not be
less than 1.
All parameters can be preceded by MEM or ST,
which refrences the value to a memory address
or stack address in that order.
(you get the value at the memory/stack addr)
Additional Casm information:
The Chip Assembler is Case insesitive, so
ADD is the same as AdD.
Also the CHIP Assembler includes lables (not case sensitive)
which are Identical to other assembler's labels, and
the psuedo instruction DB which stores the folowing string,
and DW which stores the following integer at the current
position in the compiled CHIP machine code.
DB and DW are really only usefull if they are preceded
by a lable so you don't have to calculate the address of the data.
"Computer programmers don't byte, they nybble a bit."