Steve Jenson's blog

Sunday I wrote my first virtual machine. It only runs a single program (not even written to disk yet, but stored as an array of bytes):

b0 0b 00 00 01 FA

b0 0b 00 is how I determine that I'm running a program written such that my VM can understand it. (it's magic number)

The following 00 is an instruction who's mnemonic is NOP, for No Operation. It does nothing. 01 is an instruction who's mnemonic is INC (at least in this instruction set but I'll get to that later), and FA is the data that 01 works on. So the VM reads in 01, increments the IP (the instruction pointer, which is how the VM knows where to start looking to reading. i.e. a placeholder). 01 takes the next byte and places it on the stack, increments the IP, then increments the contents on the top of the stack (FA becomes FB).

And that's it.

Now the kicker is that I abstracted out the vm instruction set. So now you can write any instruction set you want. This means that you can interpret any set of bytes in the any program anyway you want and as long as you follow my implicit protocol you'll be fine (fine meaning that the vm won't crash). Instead of 01 meaning INC, you could instead have it map to your own DEC function which would then decrement the following byte, so instead of being left with FA you'd be left with F9.

Consider it as micro-p-coding. ;-) (psst. if you get this joke please feel free to email me and criticize or offer insight. I'd appreciate it.)

Tomorrow I'll finish up the last of my checklist and put the code online in a web-accessible CVS tree.

Geez, I don't know how other people figure out how to do this, there are no reference texts on the subject and even the fourth section of the Blue Book is a tad sketchy on some things. I just made it all up as I went along.

# — 14 January, 2002