previous page - PiLAR index - next page

PiLAR official logo
PiLAR is a 16-bit stack-based task-oriented microprocessor. Click here for the main documentation page.

PiLAR microprocessor details

«16-bit» means that the addressable memory for a task is limited to 16-bit addressing - that is, up to 65536 bytes for program code and up to 65536 bytes for data and stack.
The processor can manipulate data in 8-bit, 16-bit and 32-bit formats. The address bus of this (experimental) processor release is 20-bit large, so that the processor can handle up to 1024 kilobytes of total memory (future versions will use up to 32-bit addressing without changing anything; current use of extended addressing is "memory-mapped I/O"). The byte order is "less-significant-first".

«Stack-based» means that there are no general purpose registers (like "accumulator", "counter", "pointer", etc) but only program, data/heap and stack pointers. Every common operation is done using the stack, and their result remains on the stack.

«Task-oriented» means that interrupts, exceptions, task-switching, operating system calls mechanisms, are all included in a machine supported task handling scheme. Also, a memory protection system allows a task to use only a specified range of memory, raising an exception in case of unauthorized memory access.


Task registers

A task is defined by:

Note: code space and data space need not to be contiguous in main memory. They can even be moved (i.e. phisically relocated) in any moment without affecting program execution, because the task does not need to know where is exactly located in main memory (it just trusts pointer registers). Also, the operating system - with proper caution - can even reduce or enlarge "on the fly" code and data spaces.

There are nine 16-bit internal processor registers: pointers, limiters, system identifiers.

Pointer registers:

Limit registers:

System identifier registers:

A task context structure is a 16 byte memory block containing all the registers, in the order shown above, except the task pointer.

The theoretical available memory to a single processor is thus (up to 65536 tasks)×(64k code + 64k data)=8 Gb.


System tasks

The first sixteen tasks are reserved for operating system uses, and have special behavior. The system tasks are:

A task can be interrupted by an explicit SCHEDULE or SYSCALL, by an exception or by an interrupt.

The above described system tasks, when raised by any reason, get on their stack an uword containing the task pointer of the calling task.


Data types and addressing

There are six available integer data types:

respectively 7 bit signed, 8 bit unsigned, 15 signed, 16 unsigned, 31 signed, 32 unsigned.

The six data types will be here shortened by "typ"; an object data size (1, 2 or 4 bytes) will be shortened by "siz" and named after the signed types; the signed data types will be shortened by "sig".

Addresses can be:


Instructions

There are three different classes of instructions:

All memory and I/O addresses are checked before executing the instruction with the proper bound registers, generating an exception in case of access to unallowed areas, boundary-crossing, unallowed instructions.

Excluding the SPECIAL prefixed sequences, every instruction is one byte (instruction code) followed by no more than two bytes (one 8-bit or 16-bit immediate data object).

Below, a general introduction to processor instructions follows; instruction details are here.


Stack operations

General stack expand/reduce operations:

Pushing immediate data on the stack:


Arithmetic operations

These all work with the top-of-stack object, which size (and sometimes its sign) is specified by the operation.

Increment and decrement operations (the value of the data object on the top of the stack is changed):

Arithmetic operations (the value and/or the size of the data object on the top of the stack is changed):

Classic operations (two data objects x,y of the same size become one object of the same size):


Logical and bit operations

Logical operations (two data objects of the same size become one ubyte of value 0 or 1):

Bit operations (two objects, a data object and an ubyte object, become one object of the original data object size):

The bit test operation (two object, a data object and an ubyte object, become one ubyte valued 0 or 1):


Repeating operations

Some operations work repetitively until an "ending condition" has been reached. They can be interrupted by an exception or interrupt before all elements are processed, and can continue execution later because interruption restacks updated address values. These instructions, which work only in the data/stack space, are:

Notice that these operations need special care if the two areas overlap or the byte count happens to be bigger than 32767.

Notice also that except COPY BLOCK, the above operations can reach the "ending condition" before all elements were processed.


Program control

The jump/call conditions, which will be called "way", are:

The four call/return modes are:

The program control instructions are:

CALL and CALLREF instructions do these operations:

  1. get the call-address from the stack if it was a CALLREF;
  2. push a zero-valued object of requested size if needed, to prepare space for the function return value (if non-void);
  3. push the next instruction pointer on the stack;
  4. change the instruction pointer to specified address;
  5. push the context pointer on the stack;
  6. set the new context pointer to current stack pointer;

This mechanism makes the new stack frame containing these data at the specified offset (when the callee gets control):

So, a RETURN instruction does these operations:

  1. sets the current stack pointer to the context pointer (freeing locally allocated area);
  2. pops the old context pointer from the stack;
  3. pops the next instruction pointer from the stack;
  4. get the requested-size return object in a temporary internal space;
  5. discard parameters from the stack (discard the specified number of bytes);
  6. push the return object again on the stack;
  7. jump to the old instruction pointer.

This CALL/RETURN mechanism allows interesting code savings while keeping a clean handling on a number of common compiler conditions:


System calls

Two special instructions let a task invoke the operating system resources:

The general system task is the one which task pointer equals to zero; the system library task has a task pointer equal to one (see above, "System tasks").

The SYSCALL instruction switches to the system library task keeping the current data/stack registers and zeroing the instruction pointer. The next instruction fetched will be the first code space instruction of the system task, and will be able to read/write data from the calling task data/stack space.

The SCHEDULE instruction has some extra properties:


Special operations

These instructions are available to all tasks:

These instructions are only available to system tasks:

Note: in unprivileged mode these instructions do nothing more than discarding data from the stack (from 1 to 8 bytes, except 3 bytes). They thus have an alias:


Assembler directives

These are not instructions but directives for the assembler program:


Mugnano del Cardinale (near Naples, Italy)

previous page - PiLAR index - home page - send e-mail - next page