This is a toy assembly compiler and virutal machine that can build and run 32-bit executables.
To compile assembly code into an output binary, use the 'asm' command.
picovm asm OUTPUT TYPE FORMAT INPUT
- OUTPUT - resulting .elf output file
- TYPE - elf32 and elf64 is the only supported package types
- FORMAT - pico is the only supported code/text format
- INPUT- source .asm assembly file
To inspect a binary, similar to the GNU 'readelf' command, use the 'inspect' command.
picovm inspect EXECUTABLE
- EXECUTABLE - file to parse
To run a binary in the virtual machine, use the 'run' command.
picovm run EXECUTABLE
- EXECUTABLE - file to run in the virtual machine
To compile and immediately run a binary in one command, use 'asmrun'.
picovm asmrun OUTPUT TYPE FORMAT INPUT
(Same parameters as asm)
The project is currently a single Main() function which performs the following steps:
- Reads in a .asm file
- Assembles the assembly code to bytecode
- Writes out an a.out file (experimental, in the future will be divided into workflow tools)
- Loads the bytecode into a virtual machine
- Executes the code
First, source code is processed by the BytecodeCompiler
class, which serves as a
lexer, parser, and bytecode compiler all in one. This produces a CompilationResult
which, if successful, contains a text section and a data section.
A primative loader allocates a byte array and copies the text and data segments, and
allocates an Agent
, which serves as the virtual machine. The executing instruction
pointer within the Agent begins at 0x00000000 and runs one bytecode command per Tick()
method call.
A rudimentary *nix syscall table is implemented to handle interrupts. The sys_write syscall, for instance, provides the Hello World program the ability to load a string and write it to Console.Out.
A small set of unit tests are included in the picovm.Tests directory
- ☑️ .asm file parsed into bytecode
- ☑️ 32/16/8-bit registers and MOV instruction handled
- ☑️ Data segment with directives DB and EQU
- ☑️ Constant value inline expansion
- ☑️ Interrupt vectors, initial sys_write syscall
- ☑️ BSS segment, initial sys_read syscall
- ☑️ Separate compliation and loader
- ☑️ Output syntactically correct ELF64 binary
- ☑️ Read ELF64 binary
- 🔲 x64 support
- 🔲 Create x64-compatible bytecode
- 🔲 Floating-point unit (FPU)