Mic1MMV Introduction

Mic1MMV is a simulator for the Mic-1 microarchitecture. You can use it to assemble and load IJVM assembly programs, and then step through the execution.

Mic1MMV is part of the student resources for the course textbook. I have posted a copy of the student resources here: tanenbaum_sco6.zip

Unzip this file, and navigate to the Mic1MMV/bin directory. You should see the files Mic1MMV_hr.jar and Mic1MMV_lr.jar. The hr and lr stand for “high resolution” and “low resolution”.

If you are on the command line, run the high resolution version like so:

java -jar Mic1MMV_hr.jar

If you are in a GUI file browser, you should be able to double click on it to run it. If you run the high resolution version and it does not fit vertically on your screen, try the low resolution version.

Refer to Figure 4-11 in the text for the IJVM instruction set, and Figure 4-17 for the microprogram.

Running a Program

Open a new file in an editor, paste in the following text, and save it as print_chars.jas:

// this program displays all the visible printable ASCII values 33..126
.constant
one     1
start   33
stop    126
.end-constant

.main
        LDC_W start 
next:   DUP
        OUT
        DUP
        LDC_W stop
        ISUB
        IFEQ done
        LDC_W one
        IADD
        GOTO next
done:   POP
        HALT
.end-main

In the simulator, select File -> Assemble / Load JAS File, and select the file you just created. If all goes well you should see this in the window that pops up:

IJVM Assembler...
assembly complete

Press Load to load the program. Before running the program, note a few things.

The constant pool begins with this:

00010000:  00000001
00010004:  00000021
00010008:  0000007e

These are the 3 constants that were defined in the assembly file (1, 33, and 126 in decimal). CPP has the value 0x4000, and the first address in the constant pool is 0x10000. This is because CPP is a 4-byte word address, and the addresses show in the constant pool section are byte addresses. 0x4000 times 4 is 0x10000.

The stack addresses are organized the same way: SP and LV are word addresses, but the addresses shown in the Stack Area are byte addresses. The blue text Stack Area is the word pointed to by LV, and the red is the word pointed to by SP. The green values are the ones in between. I am not sure why the stack starts off with extra 0’s, but it does.

Now let’s run the the program. First, set the speed to IJVM, so that you can step through at the assembly language level. This will make it easier to understand at first. Now press the blue arrow three times. You should see the stack has changed, and the top value of the stack is now 0x21 (33). This is the result of the LDC_W start instruction, which pushes the constant named start onto the stack. Now each time you press the blue arrow it will step forward by 1 IJVM instruction (which may be numerous microinstructions).

I will walk you through one iteration of the program. After each instruction I will show the stack from the address 0x20044 and up, with the highest addressed value on top.

The first instruction is LDC_W start. This pushes the constant named start onto the stack, so the stack now looks like this:

0x00000021 (33)

The next instruction is DUP. This instruction is preceded by the label next, which the program will jump to later to accomplish the loop. DUP duplicates the top of the stack, so now the stack looks like this:

0x00000021 (33)
0x00000021 (33)

The next instruction is OUT. Technically this instruction is not part of the IJVM instruction set but it was added to the simulator to make output easier. OUT prints the character corresponding to the ASCII code of the top of the stack, and pops the stack. 0x21 is the exclaimation point, so after the OUT instruction has executed you should see ! in the Output Console, and the stack has become this:

0x00000021 (33)

DUP duplicates the top of the stack again:

0x00000021 (33)
0x00000021 (33)

LDC_W stop pushes stop onto the stack:

0x0000007e (126)
0x00000021 (33)
0x00000021 (33)

ISUB pops the top two values from the stack, subtracts them, and pushes the result. 33 - 126 is -93, which in 2’s complement is 0xffffffa3. Here’s the stack now:

0xffffffa3 (-93)
0x00000021 (33)

IFEQ done pops the stack and compares the value with 0. If it is 0, execution will jump to the label done, otherwise it continues. Since -93 is not zero, execution moves on normally and this is the stack:

0x00000021 (33)

LDC_W one adds 1 to the top of the stack:

0x00000001 (1)
0x00000021 (33)

IADD adds the top two values and replaces them with the sum:

0x00000022 (34)

GOTO next jumps execution up to the next label, and the process starts over again with 34 on the top of the stack. This process will repeat until the character 126 (which is ~). If you set the speed to Prog and press the blue arrow, the program will continue execution without showing you the steps until it halts. After running the entire thing you should see this in the Output Console:

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

If you reset and set the speed to Clock, you can step through the program again at the microprogram level and see the individual cycles of the data path. SubClock speed will show you how the data propagates within each clock cycle.

Editing the Program

This assignment came with the empty file every_other_letter.jas. In this file, write an IJVM assembly program that is very similar to the above program, except that it only prints out every other lowercase letter like so:

acegikmoqsuwy

Look up an ASCII table online so you can figure out where to start and stop. You will need to increment the value of the character by 2 each iteration instead of 1.

Submission

Push your assembly program to git-keeper.