Runtime Revolution
 
Articles Other News

Coding an Assembler Interpreter in Revolution


by Andre Garzia


The problem

Andre Alves Garzia is 27 and lives in Brazil. He holds a BA in filmmaking and is an undergrad of Computer Science course at UniverCidade.

He's been programming since he was 14 and been involved with Runtime Revolution since 2001. His most useful contribution to the Revolution community so far has been RevOnRockets, a package to aid Revolution Web Developers.

In his spare time he likes travelling, reading sci fi books, cooking and finding new troubles. His latest projects are available from www.andregarzia.com.

Since the beginning of the year, I have been a computer science undergrad student. There in my new university, they are teaching me the joys and pains of learning about programming, hardware architecture and the like. Most of my fellow classmates never coded in their life and actually, some had no clue about how programming languages work. They are teaching us two courses in the first semester that involve programming.

Programming Techniques 101: This is our first formal introduction to programming and the newbie friendly and very readable language they choose to use is C, and it gets even better, we're using Turbo C from Borland circa 1991. I am only able to follow it because I actually learned to program using Turbo C in *1993* (give or take couple years). But this is not an article about C, it is about the other course.

Computer Architecture 101: Here we learn about bits and bytes, cpus, memories and all the hardware that is made in China, sold in the US and smuggled to Brazil. And here we learn Assembler. Students are supposed to learn to code in assembler for a non-existant x86 machine. For that we use some simulator called SIMx86 that has a newbie oriented assembler with commands such as GET that requests a numerical input from the keyboard. Our second examination was just made of assembler questions.

The problem is, I skipped the assembler classes, I don't know how to code in SIMx86 assembler! The bigger problem, SIMx86 just runs on Win32 machines and I have four macs. It is 10:00 PM, the exam is in 10 hours, I decide that learning assembler using my paper lectures is not much good because I can't test to see if my code is really working. Then I decide to undertake a huge project, code my own assembler simulator for the language used in SIMx86.

The result

A picture is worth a thousand typos, here comes a screenshot:

This is my finished assembler simulator, it can run all the examples we learned in class, it has a poor man debugger that allows me to step through the code line by line checking registers. The missing part is memory access, right now I have just implemented the registers, no access and manipulation of memory addresses but I'll in the future add a 64k memory.

The whole interpreter code is just 164 lines of transcript. It was fairly easy to do, the hardest part was the fact that SIMx86 math is all hexadecimal based and rev is all base 10, so I had to convert numbers before displaying and after input, that is not a problem *if you think of it before coding* - it took me two hours to remember that values should be hexadecimal and that was why my code was failing.

My interpreter has functions for adding and subtracting, conditional jumps, labels, some bitwise operations and variable copying. It can run all code we used in the class and even better, it allows one to step through. I also added context sensitive help, when stepping through, a little field contains all the info available for the current command being executed.

I finished coding this at 2:00 AM, the examination was at 7:30 AM.... it was not the wisest decision on earth, I used many hours to code and fine tune my own assembler interpreter when I should be studying. I am waiting for my grade on that examination, but no matter if I have a good or bad grade, I am proud of my silly interpreter, it even sports a nice eMac monitor for displaying the output.

The implementation

Implementing this interpreter was easy. There are couple of script local variables:

  • theSource - holds the source being executed.
  • tCL - the current line we're executing.
  • ax, bx, cx, dx - the registers.
  • t1, t2 - holds values for conditional implementation such as CMP AX, BX.

Then it is all done with two main functions - ExecuteASM and GetNextLine.

GetNextLine

it picks the line tCL of theSource and passes to ExecuteASM, it increments tCL then. Simple as that.

ExecuteASM

This function executes one Assembly instruction, it uses some helper functions such as ParseRegister to find values for the register and SetRegister to push back the values but it is all a big switch statement. If the "step line by line" checkmark button is not hilited, this function will call GetNextLine before finishing, if it is hilited then it just finishes and you can move to the next line by pressing the execute button which calls GetNextLine.

Interpreter is initialized by a function called StartASM, this function zeroes the registers and moves tCL (the current line) to the first line in the source. This is called on closeField of field "source" and also when tCL is the first line. This is how we refresh the interpreter after execution, when the HALT command is found we put 1 into tCL, so when GetNextLine happens, it will call StartASM since it is on the first line.

I am very proud of my conditionals and jumping. It was so easy to implement that in Revolution, I simply use lineOffset to find the line that contains the label and then change tCL to be that line, the next call to GetNextLine will execute from that line. All jumps, switches and loops are now easy to implement.

This is a simple story of how someone with raw knowledge of Assembly and some better knowledge of Revolution was able to implement in less than five hours, a simple interpreter to help him study for an examination. This is what I think Dan Shafer called the inventive user, that creates impromptu tools as the need arises. My own Assembly interpreter is not a product, it is a simple tool that helped me get a better grasp of how that language works and allowed me to experiment before an examination. Bonus it works on Macs, Windows and probably Linux (without the blends).

Since the original project, just for the kicks, I've added a built-in mini portal like RevOnline where users can upload and download assembly source code. I've added a couple, including a simple fibonacci series printer.

The subset of the assembly language implemented is very small, just enough to run the exercises from the chapter used in my examination. Also, I've not implemented memory access, all you have is four registers to play (ax, bx, cx, dx). 

It is an educational tool, I found it fun and decided to share. Of course there are a lot of bugs and places for improvement,  this is a little ad hoc interpreter, not a solution.

Its on my space in revOnline (under username "SoapDog") or you can download it here.

Instruction set:

GET - fetches a numeric input from keyboard.
PUT - display content of ax register.
MOV - copies content to target register
   MOV <target>, <register>
   MOV <target>, <number>
CMP - compares to registers
JA - jump if greater
JB - jump if smaller
JAE - jump if equal or greater
JBE - jump if equal or smaller
JNA - jump if not greater
JNB - jump if not smaller
JE - jump if equal
JNE - jump if not equal
JMP - jump!
XCHG - swaps two registers
ADD - sums
SUB - subtracts
AND - bitwise and
OR - bitwise or
XOR - exclusive or
CALL - call subroutine
RET - return from subroutine
HALT - finishes
SETE - set 1/0 if equal
SETNE - set 1/0 if not equal
SETLE - set 1/0 if lower or equal
SETL - set 1/0 if lower
SETG - set 1/0 if greater
SETGE - set 1/0 if greater or equal
SETNLE - set 1/0 if not lower or equal
SETNL - set 1/0 if not lower
SETNGE - set 1/0 if not greater or equal
SETNG - set 1/0 if not greater

Bonus points for the line by line execution and line hilighting. Minus point for not having an abort button when you enter infinite loops...

As I mentioned above, this was a very quickly coded solution, and it has plenty of bugs and room for improvement. Please do join in and submit your own assembly code :).

Alan J Perlis said, have fun coding...

 
©2005 Runtime Revolution Ltd, 15-19 York Place, Edinburgh, Scotland, UK, EH1 3EB.
Questions? Email info@runrev.com for answers.