|
|
|
|
|
|
|
|
|
0
|
Lit | Lval | Lvalg | Rval | Rvalg | Fetch | Set | Index |
8
|
Jmp | Jz | Call | Func | Proc | Ret0 | Ret1 | Stop |
16
|
Add | Sub | Mul | Div | Minus | Not | And | Or |
24
|
Lt | Le | Eq | Ne | Ge | Gt | Printch | |
32
|
Send | Receive | Signal | Nop | TmSend | TmRec | TmWait | Delay |
40
|
Gettime |
[ 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
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(
base_ads + 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 #npara #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 Add, Sub, 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 – ... )