This is a small project I started working on about a year ago, just to be able to run some small programs and write an assembler. The assembler is written in Python to make it super fast to write and extend, while the virtual machine is fully written in C for performance.
To assemble a demo, you can run the following commands:
python3 asm.py demos/hello/helloworld.dS # or any other demo!
./vm --prog demos/hello/helloworld.binTo debug, use the --debug or the --step-delay flags, or see the --help switch for a list of the available commands!
x0, x1, x2, x3 — general purpose registers
sp — stack pointer
bp — base pointer (start of the program)
pc — program counter. current location in program.
0x00 — stop execution
0x01 — print first byte of x0 register as character
0x02 — toggle step debug (register dump on every step)
0x03 — load file from disk
Input:
- x0 — memory address to load into
- x1 — pointer to path of the file
pushi [imm] — push an immediate value to the stack. always 16 bit
push [reg] — push a register to the stack. always 16 bit
pop [reg] — pop a value off the stack into a register
addi [imm] [reg] — add an immediate value to a register
add [reg] [reg] — add a register to a register
sys [imm8] — send a syscall to the cpu
cmp [reg] [reg] — compare two register values
cmpi [imm] [reg] — compare the value of a register to an immediate value
not [reg] — bitwise negate a register
andi [imm] [reg] — bitwise AND a register with an immediate value
ori [imm] [reg] — bitwise OR a register with an immediate value
b [label] — immediately branch to a label
blt [label] — branch to a label if a comparison result is a negative number
bgt [label] — branch to a label if a comparison result is a positive number
be [label] — branch to a label if a comparison result is zero
bne [label] — branch to a label if a comparison result is non-zero
.str [string] — encode data into the executable
{# [macro_name] [number of arguments]
; instructions here ...
;[instruction] #[index of argument]
; push #0
; or
; pop #1
#}for example,
; exchange the values between two registers
{# xchg 2
push #0
mov #1, #0
pop #1
#}would be used like:
xchg x1, x2and would result in the code generated as
push x1
mov x2, x1
pop x2