I have supplied a sample implementation of the vm for the assignment. You can't see the C++ code of course, but you can run it. That means that if something goes wrong with your implementation you will be able to see whether it is your vm or the assemply language program it was running that went wrong. You'll also be able to get a feel for how something like this is supposed to behave, that might be helpful too. Put an assembly language program, or just part of one in a file in your rabbit account. Let's say you called the file prog. Just type the command vm218 prog and it will run. If you have used different opcode names from me, that isn't a problem, the program can adapt. If you have a file called vm_setup.txt in the directory you are working in, you can easily tell the vm how to translate. The opcodes I used are: STOP ADDR ADDN ADDM SUBR SUBN SUBM MULR MULN MULM DIVR DIVN DIVM JUMP JNEG JZER JPOS LOADR LOADN LOADM STORE READN OUTR OUTSR OUTSN CALL RET PUSH POP If for example your opcode for adding a constant to a register is ADDKR and your opcode for halting the program is HALT, just put these two lines in vm_setup.com translate ADDKR ADDN translate HALT STOP You can also translate directives (I used LABEL, DATA, and STRING) and register names (I used R0 to R15). I set the sizes of the VM's memory areas to be 8192 for code and data and unlimited for strings. If you are using another size, maybe 1000, just add these lines code 1000 data 1000 My instruction format has 5 bits for the opcode, 4 bits for the register number and 23 bits for the operand. If your sizes are different add (examples) opcode 6 register 5 operand 21 You don't need to do anything about capital or little letters, my version doesn't care, ADDR is the same as addr. The main reason this may be helpful is that you can set options to produce debugging output. Options are set when you run the VM like this: vm218 -a prog the available options are a, e, and s. You can turn any or all of them on in various ways: vm218 -aes prog vm218 -e -s prog etc -a shows what the assembler does. After reading each instruction of the program or any directive it prints a line showing exactly how it was converted into a 32 bit instruction, with opcode, register, and operand separate and all combined into the final result. -e traces the execution of the binary program. Before each instruction is executed it prints the current values of whatever register and memory location the instrction mentions, and shows the instruction itself. After the instruction has been executed it also shows the new values of the register and memory location. This can produce a lot of output, so ... -s slows it down, and is only meaningful when -e is also turned on. With -s, the VM stops after showing you the current register and memory values and the instruction, and waits until you press enter before continuing. Instead of just pressing enter, you can also type r to see the values of all of the registers, or some number to see the content of that memory location and the corresponding entry in the strings memory. Remember that you are not expected to try to duplicate what I've done, just implement the things you are required to implement and make sure that what happens is understandable. "required" isn't quite the right word, as there is an extra credit part and you can add anything you like too.