Perdo - Virtual ASM Simulator
About PerdoCode
PerdoCode is a flexible, minimalist assembly-like language. Designed to give students in undergraduate compiler design courses an easy to use target language, PerdoCode has an extremely simple and forgiving syntax. It's fourteen basic instructions encompass arithmetic, branch, load, and store operations.
Virtual Architecture
Perdo is designed to provide the programming appearance of a dedicated microcontroller. Program code is loaded into a special 'code space' which provides an effectively infinite ammount of storage (in so far as there are no programmatic limits on its size). Live data storage consists of 8 general purpose registers, accessed through the labels regA ... regH. Off cpu storage, in its default PerdoCode configuration, consists of 64k of memory cells. All data representation is handled in integers with effectively infinite range.
Certain conditions, documented below, can cause 'soft exceptions'. A soft exception is an error which occurs during program execution that is the result of logic problem. By default a soft exception will result in program termination. However, when configured for continous run, soft exceptions will simply cause the virtual CPU to reset.
Unrecoverable internal errors that are unrelated to the PerdoCode logic will be reported as 'hard exceptions'. Hard exceptions will unconditionally result in Perdo termination.
Special Registers
PerdoCode exposes non-computational related hardware support functions as special registers. These special registers can be used anywhere it is syntactically correct to use general purpose registers. Below is a definition list showing the in-code label for each of the currently supported special registers and their intended purpose.
- out_num
-
Takes any value written to it and outputs its value to stdout as a numical
string.
Soft ExceptionAttempting to read from out_num will result in an IO soft exception.
- out_char
-
Takes any value written to it and outputs its value to stdout interpretted
as an ASCII character.
Soft ExceptionAttempting to read from out_char will result in an IO soft exception.
Syntax
Programming in PerdoCode follows a very simple assembly language format. One instruction per line, consisting of an optional label, an instruction mnemonic, various operation specific operands, and end of line comments as desired.
label: mnemonic op1, op2, op3 ; comment
By convention operands are separated by commas. PerdoCodes's simplicity, however, allows the parser to relax the requirement. Therefore, a simple space between each part of the instruction will also work.
label: mnemonic op1 op2 op3 ; comment
Labels can exist on lines without an instruction on them, but one label per line is legal. The label is assigned the value of the next instruction encountered unless there are no more instructions found, in which case it will be assigned a value past the end of valid code space.
Comments consist of all content following a semi-colon, and can, therefore, be used to sheild any or all content that is desired to be ignored. Partial lines, or full lines, all that matters is that anything between a ';' and a '\n' is thrown away.
All extraneous whitespace is also ignored making the following line valid.
label: mnemonic , op1 ,op2, op3 ; comment
Instruction Set
Operands accepted by instructions can one of the following classes of data types:
- VAL
- An Immediate Value, the contents of a General Purpose Register, or the contents of a Special Purpose (PerdoCode) Register.
- REG
- The contents of a General Purpose Register, or the contents of a Special Purpose (PerdoCode) Register.
- MEM
- The value of the memory location pointed to by an Immediate Value, the contents of a General Purpose Register, or the contents of a Special Purpose (PerdoCode) Register.
The operand types listed for instructions are specified using the format [{]CLASS:LABEL[[=DEFAULT]}], where CLASS is one of the three operand classes and LABEL is the operand label used in the operation listing. When operands are surrounded by {}, the operand is optional and can be left out. Optional operands may also be listed a default value, where applicable.
Arithmetic Operations
Add
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| add | VAL:A | VAL:B | REG:result | result <= A + B |
Subtract
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| sub | VAL:A | VAL:B | REG:result | result <= A - B |
Multiply
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| Mult | VAL:A | VAL:B | REG:result | result <= A * B |
Divide
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| div | VAL:A | VAL:B | REG:result | result <= A / B |
Modulus
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| mod | VAL:A | VAL:B | REG:result | result = A % B |
Conditional Operations
All conditional instructions will execute the instruction immediately following themselves if the condition is true. If the condition is false, the next instruction will be skipped.
main: # some code ... if-equ regA, regB jump label # continue on with current section # entrance to separate code section label: add regA, regB, regC
If Equal To
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| if-equ | VAL:A | VAL:B | {REG:result} | {result <= (A == B)} if (!result) PC += 1 |
If Greater Than
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| if-gtr | VAL:A | VAL:B | {REG:result} | {result <= (A > B)} if (!result) PC += 1 |
If Less Than
| Instruction | Operand A | Operand B | Destination | Operation |
|---|---|---|---|---|
| if-less | VAL:A | VAL:B | {REG:result} | {result <= (A < B)} if (!result) PC += 1 |
Memory Accesss Operations
Load
| Instruction | Source | Destination | Offset | Operation |
|---|---|---|---|---|
| load | MEM:S | REG:D | {VAL:O=0} | D <= Mem(S + O) |
Store
| Instruction | Source | Destination | Offset | Operation |
|---|---|---|---|---|
| store | VAL:S | MEM:D | {VAL:O=0} | Mem(D + O) <= S |
Memory Copy
| Instruction | Source | Destination | Offset | Operation |
|---|---|---|---|---|
| mem-copy | MEM:S | MEM:D | {VAL:O=0} | Mem(D) <= Mem(S + O) |
Miscellaneous Operations
Jump
| Instruction | Target | Operation |
|---|---|---|
| jump | VAL:T | PC <= T - 1 |
Value Copy
| Instruction | Source | Destination | Operation |
|---|---|---|---|
| val-copy | VAL:S | REG:D | D <= S |
No Operation
| Instruction | Operation |
|---|---|
| nop | Do nothing for one cycle. |

