There are 4 formats : zero operand, one and two and three operands (all operands are 16 bits, this document shows the format for 16 bits systems).
[ Ic ] Arithmetic op, Logical op, etc. [ Ic #ref ] Literal, Lval, Rval, Jump, Wait, etc. [ Ic #nparam #nlocal ] function call [ Ic #pid #nparam #nlocal ] process call
Notation for describing the operational semantic of I-code,
CS[i] code segment at the address i.
DS[i] data segment at the address i.
SS[i] stack segment at the address i.
Both data segment and stack segment resided in the same address space and can be denoted by M[i] memory contained DS
and SS, at the address i.
Some operations take operand(s) from stack and leave a result on the stack. The state of stack can be described by a notation
that indicates the values in the stack (before an operation - after an operation ) when the top of stack is the left most item, the
"..." denotes the items that are of no interested to us.
Push(x) is defined as Sp = Sp + 1, SS[Sp] = x
x = Pop is defined as x = SS[Sp], Sp = Sp - 1
Literal
push the constant into the stack
[Literal #n ] push( n ) ( ... - n )
Variables access
Lvalue, push the address of that variable. If the variable is global its reference is its address. If the variable is global, its address
is the address of that variable in the current frame. Rvalue, push the value of that variable.
[Lvalueg #ref ] push( ref ) ( ... -- ref )
[Lvalue #i ] push( Fp-i ) ( ... -- ads )
[Rvalueg #ref ] push( DS[ref] ) ( ... -- value )
[Rvalue #i ] push( SS[Fp-i] ) ( ... -- value )
Fetch, get the value of the variable which its address is on the stack. Set, store a value to an address, both value and address
are on the stack. Index, which is used to access an array variable, calculates the address of that element of the array and
leaves the result on the stack.
[Fetch] push( M[ pop ] ) (ads - value)
[Set] M[ pop1 ] = pop2 (ads, value -- ...)
[Index] push( baseads + index ) ( base, index - ads )
Transfer of control
Jmp, Jz, jump to a location, without and with condition (Jz is jump if the top of stack is zero).
[Jmp #ads ] Ip = ads
[Jz #ads ] if pop = 0 then Ip = ads ( bool -- ...)
Call, push the return value and jump to that address to continue with the execution of a subprogram (a function or a process).
For a function, a new stack frame is created, the parameters are passed (by overlap stack frame) and the current state of
computation (of the caller) is saved, the execution is continue with the code of that function. For a process, a new process
descriptor is created, its state of computation is initialised and the process is awaked. Stop, terminate a process by removing
its process descriptor from the ready list. (discussion about process is in the next section). Return has two varieties : Ret0, and
Ret1. Both instructions remove the current stack frame, restore the previous state of computation (which is stored in the
current frame). For Ret1, a value will be returned to the caller's stack.
[Call #ads ] push( Ip ), Ip = ads ( ... - return_ads )
[Func #nparam #nlocal ] save state, new stack frame, pass parameters
[Proc #pid #nparam #nlocal] new process descriptor, initialise state, awake
[Ret0] remove stack frame, restore state
[Ret1] remove stack frame, restore state, return a value
[Stop] terminate the process
(Note that nparam + nlocal = total number of local variables of that function or process)
Arithmetic and Logic operators
Binary arithmetic operators (Aop) are Plus, Minus, Mul, Div. They will take 2 operands from the stack and return the result.
These are arithmetic on integer. Unary operators (Uop) are Minus and Not, will take one operand from the stack and return
the result. Binary logic operators (Lop) are LT, LE, EQ, NE, GE, GT, And, Or. They are similar to arithmetic operators
except the result is boolean.
[Aop] push ( pop1 Aop pop2 ) ( a, b - result as integer )
[Lop] push ( pop1 Lop pop2 ) ( a, b - result as boolean )
[Uop] push ( Uop pop ) ( a - result )
Output
Print, take an operand from stack and print it out as an integer. Printch is similar and print as a character.
[Print ] print an integer ( a -- ... )
[Printch ] print a character ( c -- ... )