Rubycpu
An assembler compiler and bytecode virtual machine implemented in ruby for a made up CPU.
Install / Use
/learn @eviltrout/RubycpuREADME
rubycpu
rubycpu is a virtualized CPU that's similar to x86 written in ruby.
The goal of the project was to learn how to implement a bytecode compiler and interpreter, not performance.
The project includes an assembler compiler and virtual machine that interprets the compiled bytecode, as well as a comprehensive test suite.
Trying it out
bundle installto install necessary gems.ruby run.rb asm/fib.asmto run the fibonacci sample program.
CPU Design
All values in the CPU are 32-bit, little endian and unsigned.
You can configure how much memory the Virtual Machine has and its stack size using class methods:
VirtualMachine.memory_size = 1000
VirtualMachine.stack_size = 200
There are 4 general purpose registers: eax, ebx, ecx and edx.
The stack pointer and base pointer are available as esp and ebp.
Instruction Set
The instruction set is somewhat close to x86 assembly language. The Wikibooks articles on the language are excellent. Right now the following instructions are supported:
General:
- nop
- mov
- cmp
- push
- pop
Arithmetic:
- inc
- add
- sub
- dec
- mul
- div
- mod
- rem
Jumping/Calling:
- jmp
- call
- ret
- je
- jl
- jle
- jg
- jge
- jne
Bit Functions:
- and
- not
- or
- xor
- shl
- shr
Special:
- prn (outputs the value of the register or memory to STDOUT)
Machine Layout
All registers are mapped to addresses in memory and can be accessed directly.
+---+---+---+---+---+---+---+---+-----+---+---+---+---+---------+
|eax|ebx|ecx|edx|esp|ebp|eip|rem|flags|...|...|...|...|stack end|
+---+---+---+---+---+---+---+---+-----+---+---+---+---+---------+
0 1 2 3 4 5 6 7 8 ... mem_size
You can use square brackets around an integer to access any address of mapped memory. This means that:
mov ebx, 13
mov edx, 20
is equivalent to:
mov [1], 13
mov [3], 20
The stack begins at the end of memory and goes downwards until VirtualMachine.stack_size is exhausted.
Running the Tests
There are specs for compiling and running every command the CPU is capable of. Simply run rake test to execute the entire suite.
Acknowledgments
-
The tinyvm project was a great inspiration, in fact many of the sample programs were lifted directly from them. Thanks!
-
@notch's tweets about designing a CPU that inspired the project.
-
My former co-worker @aronmgough's excellent tutorial on treetop which inspired my parser.
License
rubycpu is released under the MIT License.
