CS232, Spring 2008

Wombat Programming Assignments W2-1, W2-2, and W2-3

Exercise W2-1 (due Wednesday, February 27 at class time)

Redo Exercise W1-3 except use the Wombat2 computer (described below).

Write your program in such a way as to minimize memory accesses.  (In fact, from now on, I will expect you to write all your Wombat assembly code to minimize memory accesses, and so you need to learn to use the eight A registers to the maximum!)

After writing your program, answer the following questions:

  1. How many machine instructions get executed every time through one of your loops?
  2. How many of those instructions in the loop involve accessing data in main memory? Don't count the fetching of instructions from main memory into the IR.  Just count the number of loads and stores of data, which transfer data between a register and memory.

The CPU Sim machine file "Wombat2.cpu" can be found on the CS232 web page here (right-click or control-click on this link and save the link target as "Wombat2.cpu").

As usual, hand in a hard copy of your W2-1.a assembly language program including the answers to the questions above. Also, email me a copy of your program. Be sure and include your last name as part of the file name of any attachment you email me.

Exercise W2-2 (due Wednesday, February 27 at class time)

Add macros named READ and WRITE to the file "W1macrosForW2.i" to complete the sets of macros so that Wombat1 assembly programs (after being rewritten so that all opcodes are in capital letters) can be run on the Wombat2. Then test these macros by (a) rewriting W1-0.a so that all opcode names are in all capitals and then (b) running W1-0.a on the Wombat2. You will need to add one line of code to the top of the W1-0.a file:

  .include "W1MacrosForW2.i"

Don't forget the period before "include" and don't forget the quotes around "W1MacrosForW2.i".

Hand in a hard copy of your W1MacrosForW2.i file. You do not need to email me anything for this assignment.

Exercise W2-3 (due Friday, February 29 at class time)

Write and test a Wombat2 program to read in an arbitrarily long list of numbers and print them out in reverse order.  The number -999 will serve as sentinel and should not be printed out.  Be sure and add blank lines and lines containing only comments as necessary to make the assembly code more readable. The easier it is for me to understand what your program is doing, the better your grade.

Start early on this exercise, as there is one very tricky spot! You will almost surely not finish it if you start only the day before it is due. I will give you hints but only after you have shown me that you have already worked hard at trying to solve it yourself.  Do not modify the Wombat2 machine itself by, for example, adding new machine instructions or registers.

As usual, hand in a hard copy of your W2-3.a program and email me a copy of it. Be sure and include your last name as part of the file name of any attachment you email me.

 

The Wombat2 Computer

The Wombat2 is the second venture of the Australian Computer Corporation into computers.  Instead of using an accumulator, the Wombat2 has eight general-purpose 16-bit registers A[0],...,A[7] to store the results of operations.

Wombat2 assembly language instructions have 0, 1, or 2 operands. The "Usage" column in the table below shows the number of operands each instruction takes. In the following descriptions, i and j are indices of A registers, and so they must be integers from 0 to 7, m refers to a memory address, and c(m) indicates the contents of memory location m.  The symbol "-->" indicates data movement (copy).

               Op-code
Mnemonic   (bin)(hex)(dec)  Usage          Description                
exit        00000  0   0    exit          stop execution of the program
load        00001  1   1    load i m      c(m) --> A[i]  
store       00010  2   2    store i m     A[i] --> c(m)
add         00011  3   3    add i j       A[i] + A[j] --> A[i]
subtract    00100  4   4    subtract i j  A[i] - A[j] --> A[i]
multiply    00101  5   5    multiply i j  A[i] * A[j] --> A[i]
divide      00110  6   6    divide i j    A[i] / A[j] --> A[i]
jmp         00111  7   7    jmp m         goto the instr at memory location m
jmpz        01000  8   8    jmpz i m      if A[i] = 0, go to m
jmpn        01001  9   9    jmpn i m      if A[i] < 0, go to m
move        01010  A  10    move i j      A[j] --> A[i]

For example, the assembly language statement "jmpz 1 24" says to jump to the instruction in memory location 24 if register A[1] contains the value 0.  The statement "add 1 2" says to add the contents of register A[2] to register A[1], leaving the result in A[1].

Another difference between the Wombat1 and Wombat2 is that there are no read and write machine instructions in the Wombat2. Modern computers do not have machine instructions that deal with I/O in this manner. Instead, they typically use memory-mapped I/O. In such an I/O design, there is a special memory address that actually refers to an I/O buffer instead of a location in memory. To do input, the CPU is just instructed to load from that special address. To do output, the CPU is just instructed to store at that address. In this way, there is no special I/O from the CPU's perspective and instead it thinks it is just loading from memory or storing to memory and it doesn't actually care that the data comes from or goes to someplace other than memory.

In the case of the Wombat2, the address 254 is the special I/O address. So to get input from the user and put it in register A[0], you should issue the instruction "load 0 254" and to output the value in register A[0], you should issue the instruction "store 0 254".

Another change to the Wombat2 is the stop instruction has been renamed exit, which more accurately describes what happens. A real CPU does not stop when a program stops. Instead, it begins executing a different process, which, if there are no other processes waiting to use the CPU, might just be an "idle" process that spins its wheels waiting for the user to do something.

The following is a sample assembly language program for the Wombat2 that reads in two integers and writes out the difference.

    load A0 IO      ;input an integer into A[0]
    load A1 IO      ;input an integer into A[1]
    subtract A0 A1  ;subtract A[1] from A[0]
    store A0 IO     ;output the value of A[0]
    exit            ;end the program
The symbols A0 and A1 are symbolic constants.  More precisely, A0 is a symbolic name for the value 0.  This means that anywhere in your code where you want to place a 0, you can instead place the symbol A0.  Similarly, A1 is a symbolic name for 1, A2 for 2, and A3 for 3, and so on up to A7 for 7.  Also, IO is a symbolic name for 254. Constants are used merely to make your code more readable.  These nine particular constants are so useful that they have been built into the Wombat2 machine.  To see the definitions of these built-in constants and to edit them or to create new ones in CPU Sim choose "EQU's..." from the Modify menu after loading the Wombat2 machine.  The constants listed in the EQU window are all stored in the Wombat2 machine and so can be used in any program you write for the Wombat2.  You are welcome to add new global constants to the Wombat2, in which case you should add them to this window.  However, sometimes you might also want to create local constants just for one particular program.  To do so, type in the definition of the constant at the top of the program, using the syntax "<symbol> EQU <value>", one per line.  For example, to create a local constant C with value 55, you would add a line at the top of your assembly code like the following:

   C EQU 55

To make your code more readable, be sure and use these symbolic constants wherever it is appropriate, instead of using the integer constants they represent.