#rakulang An assembler for a virtual machine

I have implemented a Forth, a BASIC, and a formula interpreter for a spreadsheet. The idea of a virtual instruction set keeps cropping up from time-to-time with me.

In this post, I shall be looking into my github repo bennett . It contains source code from the book “Introduction to Compiling Techniques: A First Course using ANSI C, LEX and YACC”, by JP Bennett. I have made my own modifications to improve compilation on modern hardware, as well as re-implementing the assembler and disassembler in Raku (formerly Perl6, of course).

The purpose of the book is to implement a Basic-like language which supports recursion. The assembler is therefore a perfectly capable one. The assembly language consists of 15 instructions: HALT (to stop the machine), NOP (does nothing), TRAP (outputs a byte), ADD/SUB/MUL/DIV (arithmetic), STI/LDI/LDA/LDR (storing/retrieving values) and BZE/BNZ/BRA/BAL (branching).

The major limitations is that it does not take in keyboard input, and doesn’t have a facility for incorporating foreign functions. These shouldn’t be too difficult to add, especially the former.

The repo does have a C implementation of the VSL (Very Simple Language, i.e. a form of BASIC, which compiles to assembler), VAS (assembler, which compiles to machine instructions), VAM (a virtual machine executer).

Raku enthusiasts may be more interested in the stuff that I’ve implemented for Raku, though. It is available in the myvm directory . asm.p6 is the assembler, and disasm.p6 is the disassembler. It is satisfying to note that the assembler takes only slightly more than 100 lines to implement using Raku’s grammar facilities. The line count could be reduced further if offsets were stored in little-endian format rather than big-endian. I chose to stick with Bennett’s way of implementing things, though, for compatibility.

If you want to test things out, then compile the top level directory:

autoreconf -iv
./configure
make
cd examples
make

The examples will compile to VAS and VAM using Bennett’s implementations. You can write your own assembly programs, but you’ll probably want to use the examples in the first instance. If you are in the examples directory, and have already issued a make in accordance with the instructions above, then you can prove that the Raku assembler works by issuing a command like:

../asm.p6 fact.vas

This will create a file called out.vam, which should be identical to fact.vam. You can run the compiled code by issuing the command:

./vc out.vam

The next step might be to implement the virtual machine in Raku, and a little more ambitiously, the parser for VSL.

Some directions I personally might want to take:

  1. see if the assembly language is a good base implementation for a Schorre Meta-II compiler. That would be an interesting project.
  2. see if I can implement co-routines or continuations in an easy fashion.

If there’s significant interest, I’ll post some details on Bennett’s instruction set, and what’s going on under the hood of the compiler. The repo does contain some info in vam.txt for those interested in writing some assembler.

That’ll do for now, though.

Update 2020-06-30

I’ve made a few exciting updates to the assembler and VM. Surprisingly perhaps, Bennett’s VM didn’t have an N flag, to test for negativity. There were no branch instructions based on this. So you could only branch unconditionally, on zero, or not-zero.

Consequently, I have added BLTZ (branch on less than zero) and BGTZ (branch on greater than 0).

I have also added a SYS instruction, in order to make system calls (“interrupts”). The format for it is:

SYS n

where n is the call number. Currently there is only one system call you can make: 0 (for getchar()). You can extend the VM to make other calls, though.

See examples/echo.vsl , which copies stdin to stdout. Here is its implementation:

\ added by mcarter 2020-06-30
\ test of syscalls
\ this just echos stdin to stdout

loop:
        SYS 0           \ getchar into R15
        LDR R15, R15    \ check for EOF
        BLTZ fin        \ if EOF then finished
        TRAP
        BRA loop
fin:
        HALT

You can read more about the VM instructions here.

About mcturra2000

Computer programmer living in Scotland.
This entry was posted in Uncategorized. Bookmark the permalink.

1 Response to #rakulang An assembler for a virtual machine

  1. Pingback: 2020.26 Cloud Gone – Rakudo Weekly News

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s