Lab 2 - A Simple Instruction Interpreter

The purpose of this lab is to familiarize you with the Nios II address modes and assembly language programming.

You are to write a Nios II assembly program that acts as a simple "interpreter". Your program will "read" the "instructions" (not Nios II instructions, but a simple set described below) from memory and do one of a few simple calculations depending on an operation code. The instruction in memory will also contain the data to be operated on, and the address of the next instruction to be executed.

The calculations are stored in a word-length "accumulator" which must be located in main memory (i.e., not in a register).

The format of the instructions, which consist of three items of different size, is as follows:

Item #1 (word size)Op Code
0 = Clear accumulator
1 = Add number to accumulator
2 = Subtract number from accumulator
3 = Exit program
Item #2 (word size) Number to be operated on, if applicable
Item #3 (word size) Address of next "instruction," if applicable

For example, the instruction created by the following assembly language directives:

INSTR1:
.word 1
.word 107
.word 0x1001000

is an instruction to add the number 107 to the accumulator, and then to go find the next instruction at address 0x1001000. As another example, the following "program" clears the accumulator, adds the number 77, subtracts the number 15, and then exits. Notice the use of .org statements illustrates that different instructions do not have to follow each other in consecutive memory locations.

START:
.word 0
.word INSTR1
INSTR1:
.word 1
.word 77
.word INSTR2
.org 0x1000
INSTR2:
.word 2
.word 15
.word FIN
FIN:
.word 3

To summarize, you are to write a program that reads these "instructions" from memory, beginning with the instruction at address START, and executes the instructions as described above. Your program can assume that the first "instruction" is always labelled START.

If the "program" contains an op-code other than a legal one (0, 1, 2, or 3), your program should exit with the number 0xFFFFFFFF in the accumulator.

You should test your program with different "programs" that you create yourself. Use the debugger to check the contents of your accumulator after the "program" has executed.

Preparation

Write code for the interpreter program described above (don't forget to comment) as well as a sample input program of "instructions" such as the one above to test it on. Put both in one file named lab2.s and compile it with the command:

   make SRCS="lab2.s" compile

CODING TIP: For this lab, you only really need a single register plus two more for temporary values. You can use more to make your life easier, but using too many might be an indication that you're making the lab harder than it needs to be.

In the Lab

Demonstrate your working program by running it on the DE2. Use the same command as above but change the "compile" to "run".

BONUS (1 mark): Write "code" for the interpreter which implements a mathematical absolute function. You'll need 2 new instructions for the interpreter: (i) a subtract reverse instruction which subtracts the accumulator from the operand and stores the result in the accumulator; and (ii) a "test if less than 0" instruction which tests if the accumulator is less than 0 and if it is branches to a given address, otherwise proceed to the next "instruction". Use these two new instructions to write "code" which computes the absolute value of the accumulator and stores it back in the accumulator.