As assembler and emulator for a custom RISC instruction set architecture.
The language is for a machine with four registers:
- Two registers, A & B, arranged as an internal stack.
- A program counter, PC
- A stack pointer, SP
These registers are 32 bits in size. Instructions have either no operands or a single operand. The operand is a signed 2's complement value. The encoding uses the bottom 8 bits for opcode and the upper 24 bits for operand.
The language is line based (one statement per line). Comments: Comments begin after a ; and anything after a ; is ignored. Trailing and leading Whitespaces are ignored as well.
An instruction involves a label followed by an optional statement. For branch instructions label use should calculate the branch displacement. For non-branch instructions, the label value should be used directly.
Valid Label Name: An alphanumeric string beginning with a letter.
Valid Operand: An operand is either a label or a number, the number can be decimal, hex or octal.
The following are permitted lines.
; a comment
; another comment
label1: ; a label on its own
ldc 5 ; an instruction
label2: ldc 5 ; a label and an instruction
adc 5 ; an instruction
label3:ldc label3 ;look no space between label and mnemonic The produces three files:
- A log (
*.log) file showing the error logs. - The assembler listing (
*.lst) file showing the assembly instructions along with their corresponding machine code, and what value is stored at each address. - The object (
.o) file of the produces machine code.
| Mnemonic | Opcode | Operand | Formal Specification | Description |
|---|---|---|---|---|
| data | value | Reserve a memory location, initialized to the value specified |
||
| ldc | 0 | value | B := A;A := value; |
|
| adc | 1 | value | A := A + value; |
Add the value specified to the accumulator |
| ldl | 2 | offset | B := A;A := memory[SP + offset]; |
Load Local |
| stl | 3 | offset | memory[SP + offset] := A;A := B; |
Store Local |
| ldnl | 4 | offset | A := memory[A + offset]; |
Load non-local |
| stnl | 5 | offset | memory[A + offset] := B; |
Store non-local |
| add | 6 | A := B + A; |
Addition | |
| sub | 7 | A := B - A; |
Subtraction | |
| shl | 8 | A := B << A; |
Shift Left | |
| shr | 9 | A := B >> A; |
Shift Right | |
| adj | 10 | value | SP := SP + value; |
Adjust Stack Pointer |
| a2sp | 11 | SP := A;A := B; |
Transfer A to Stack | |
| sp2a | 12 | B := A;A := SP; |
Transfer Stack top to A | |
| call | 13 | offset | B := A;A := PC;PC := PC + offset |
Call Procedure |
| return | 14 | PC := A;A := B; |
Return from procedure | |
| brz | 15 | offset | if A == 0 then:PC := PC + offset |
If accumulator is zero, branch to the specified offset. |
| brlz | 16 | offset | if A < 0:PC := PC + offset |
If accumulator is less than zero, then branch to the specified offset. |
| br | 17 | offset | PC := PC + offset |
Branch to the specified offset. |
| HALT | 18 | Stops the emulator. This is not a 'real' instruction, but needed to tell your emulator when to finish. | ||
| SET | value | Set the label on this line to the specified value (rather than the PC). |
The assembler produces a listing file in the following format
00000000 label:
00000000 00000000 ldc 0
00000001 fffffb00 ldc fffffb00
00000002 00000500 ldc 500
00000003 loop:
- The loads the object file and emulates the program.
- The
-beforeand-afteroptions can be used to produce the memory dump of program, before and after execution respectively, as specified. - The
-traceoption can be used to view the trace of instructions being executed. Can be particularly helpful in debugging.