Archives
Tags
- General (18)
- Food (1)
- Cooking (1)
- Ruby (6)
- Rails (2)
- Svn (2)
- Linux (9)
- Git (1)
- Firefox (8)
- Porn (1)
- Freyja (1)
- Witchhammer (6)
- Music (1)
- Merb (3)
- Poetry (0)
- Bolverk (3)
- Sinatra (1)
- Discogs (1)
- Centos (1)
- Python (1)
- Whinging (2)
- Travel (2)
- Scheme (7)
- Lisp (8)
- Sicp (1)
- Rot13 (1)
- Czech (2)
- Metal (3)
- Passenger (1)
- Fun (5)
- Fractals (2)
- Plt (2)
- Clojure (1)
- Continuations (1)
- Javascript (1)
- Presentation (1)
An assembler for the Bolverk machine emulator
After I finished writing the Bolverk emulator (source, implementation) in early 2009, I instantly had ideas about designing an assembly language for it's native instruction set. It sounded like an interesting project.
After reading the first few hundred pages of Michael L. Scott's brilliant book "Programming Language Pragmatics" during February of this year, I felt that I had enough knowledge about writing simple compilers (most assemblers are not really considered compilers, but shhhh) in order to get started. In fact, the whole process turned out to be far more challenging and rewarding than I would ever have guessed before.
An assembler provides a level of abstraction above the native language of the machine at hand. Most basic assemblers provide a one-to-one mapping between named instructions and native commands (generally ones and zeroes). Many more modern assemblers also support more advanced features like macro expansion and control structures over basic JUMPing.
With an assembler, we can now express instructions to Bolverk in atleast slightly more memorable instructions. This is the reason the primitive procedures defined in an assembly language are often referred to as "mnemonics".
Another great advantage of an assembler is it's ability to define arbitrary abstractions that defy the architectural restrictions of it's target machine. In particular, the bolverk machine specifies that only 4-bits are used to identify an instruction. This leaves us with only sixteen (0..F) possible options. If chosen correctly, these sixteen natives will be more than enough to define useful abstractions by compounding and naming them. As an example, the PVDS mnemonic used in the example below will actally compile to 3 lines of machine code.
With the finished product, we can now write something like this:
-- Print the sum of two decimal numbers (-10 and 120) -- followed by an exclamation mark. VALL 1, -10 VALL 2, 120 PVDS 1, 2 PVCH '!'
Instead of the very-hard-to-remember machine code equivalent:
21f6 2278 2421 5123 33a0 34a1 d1a0 d0a1 c000
The assembly version required only four instructions opposed to the nine required in the machine code version. It was also presented in much more readable manner.
Once we know the following semantics:
- VALL: Load into register X the value Y
- PVDS: Print to STDOUT the value of the sum of register X and register Y
- PVCH: Print to STDOUT, the value of X as though it's an ASCII character
The assembly version becomes very easy to understand.
The source code is openly available from my git repository here: http://github.com/buntine/Bolverk-Assembler. I will add a front-end for it into the web-based implementation of Bolverk (linked above) in the coming days. I've also published the grammar and a language specification in the same git repository.
I feel that my work on this set of projects could really be beneficial in teaching the ideas behind a Von Neumann machine to beginning computer science students. If found by the right person in the right position, I think they could do wonders with it. If you are that person - please give me an email or some feedback! I'd happily donate all of my work to your organisation if it can be put to good use.
Programming Bolverk; a simple example
Since Bolverk has gone live, I've had a few friends mention to me that "[It] sounds like a cool idea, but I have no idea where to start". Because of this, I've decided a small example of how one might go about programming her is in order.
I will demonstrate how to read in two binary numbers, determine their sum, and then print that value to the standard output.
0: Write the machine instructions
Below is an example of how you could write the solution (along with notes in parentheses).
2143 (LOAD register 1 with the decimal value 67) 220D (LOAD register 2 with the decimal value 13) 5123 (ADD register 1 and register 2 and store the result in register 3) 33A1 (STORE the contents of register 3 into the memory cell A1) D1A1 (PRINT the contents of memory cell A1 as a decimal number -- 80) C000 (HALT the program)
1. Load the instructions into main memory.
Click the "Write / Load Program" link and wait for the thickbox dialog to load up. Once ready, copy the following into the textarea:
2143 220D 5123 33A1 D1A1 C000
The "Starting cell" select can be left as is. Now click "Insert". You will notice that the program has been loaded into main memory. The populated cells will appear purple.
Note, you can manually change any single memory cell by double clicking it, changing the hexadecimal value, and then clicking out of the cell.
2. Initialise the program.
Click on the first cell of your program. You will notice the "Initialize Program" button will be enabled. Click it.
You will notice that the first two cells of your program code will be highlighted. This, as the legend shows, is the next instruction the machine will execute.
3. Run the program.
This is the easy part. You simply have to click the "Machine Cycle" button for each machine instruction in your program. At each instruction, you will see how the processor is being affected.
Try it! By the time the program ends, you should have the decimal number "80" printed to Standard Output.
Introducing Bolverk: 8-bit Microprocessor Emulator
Over the past few weeks, I have been developing a fun little application in an attempt to broaden my knowledge of the way a processor works at a low level.
What I've come up with is a Web-based, 8-bit Microprocessor Emulator with it's own Machine Language implementation. It contains 2kb of memory and is programmable in Hexadecimal.
I developed the "engine" first and then wrote a simple Web-wrapper for it using the Sinatra framework. Check it out here: http://bolverk.andrewbuntine.com. Or fork me on github!
I tried to keep the process enjoyable and did not worry myself too much with the finicky details that would undoubtedly plague engineers implementing a "real" machine. I questioned myself so many times that, after a while, I began to simply ignore my inner, logical self and simply kept hacking away. So even though writing a program to perform 8-bit floating point arithmatic in a machine language implemented using an interpreted and dynamic language is, quite obviously, far beyond ridiculous, I still reached my goal of... well, I don't know... total schizophrenia?
The true usefulness of such an application lies in it's effectiveness as an educational tool. Recently, I was watching some of the excellent Richard Buckland lectures from the UNSW Comp. Sci. course and I noticed that they were actually using something quite similar. The emulator they were using was only 4-bit and contained just 16 bytes of memory, but the concept was almost identical. What a confidence boost!!
Any feedback, bug reports, comments -- please send me an email!