Professor Shai Simonson - CS304 - Computer Architecture


Assignment 2

Assembly Language Using MIPS
Arithmetic Bit Level Instructions and Applications

 

Due Friday, October 12.   (40 points)

Hints for program:

1.  It is really useful to use memory locations (RAM) to store items that you expect to use later.  Registers are fine for computing values, but if you use them for longer term storage, you will soon run out of registers.  To store a value from register $8 to a place called "value".  You should initialize a loacation called value in the data section like this:
  .data
value: .word 0
Then to store the value in rgeister $8 you use sw $3, value.  Then register $8 is free for other computations.  To restore the value you saved, use lw $8, value.

2.  You may feel a need to use functions or procedures in this program, and that is natural, but unless you look ahead you won't know how to do that.  So, don't bother!  To "simulate" procedures (functions, or methods) I suggest simply designing a code segment with certain registers marked for input and certain ones for output.  Then simply copy and paste the code everywhere you need it.  When using the code, make sure you provide the appropriate values in the correct registers.  This ad-hoc style will prepare you for how procedures really work in MIPS, and help you appreciate it better.

3.  To decide when you are finished processing a string of digits, look for an ascii value of 10 (carriage return), or else just look for the first non-digit.

0.  In the book.      Chapter 3:  1, 5, 37-39.

1.  Overflow

Solve each problem below and indicate if the operation results in overflow.  (Assume that the first two have 6-bit storage capacity, and the last problem has 8-bit capacity).  Check your work by converting to decimal. 

(a) Assume that the numbers are unsigned.
(b) Assume that the numbers are two's complement.  

     110110            001101         00000001
+   001011       +  011011     +  01111111

(c)  One way to check for overflow in 2’s complement addition is to check if the two numbers are positive but give a negative answer (i.e. the most significant bit in the result is 1), or the two numbers are negative but give a positive answer.  Design overflow circuitry to detect overflow using this scheme.  (It will appear later as the overflow “black box” of a ripple adder.)

(d) Another way to check for overflow in 2’s complement addition is to check when the carry_in to the most significant bit is not the same as the carry_out of the most significant bit.   Explain why this works.  Draw the overflow circuit for this and compare in size and speed to the previous problem.

2.  Simulating Instructions

a.  Show how to accomplish an SLL instruction using ROL (rotate left) pesudo-instruction and other logical MIPS commands (and, or, nor).
b.  Same question for an SRA instruction.

3.  Reading, Adding, and Displaying 64-bit Numbers

Write MIPS code that reads a string of digits (0-9), and stores the base 10 integer represented by that number in two 32-bit words.  You may assume that the integer is small enough to be stored in 64 bits.  Briefly, the algorithm works like this:  You process the string from left to right, and with each new digit you multiply the previous result by 10 and add the numerical value of the digit.  This is tricky because besides the need to convert ascii codes of 0-9 to values 0-9,  you also need to do multiplication and addition on a number stored in two words.  The multiplication by 10 can be done with shifts and addition (add 8x + 2x).  Hence, the only hard part is the addition of two 64-bit numbers. 

Write MIPS code to add two 64-bit numbers.  Adding two 64-bit numbers cannot be done with one ADD instruction because ADD instructions work only on 32-bit numbers.  The addition must be done in two stages - first the lower 32 bits and then the upper 32 bits.  The result of the two lower 32 bits is stored in the lower 32 bits of the result.  If this generates a carry then one must be added to the upper 32 bit addtion.  The result of the upper 32-bit addition (possibly with this carry) is stored in the upper 32-bits of the result.  All these adds are done with ADDU instructions, because there are no negative numbers.

Test your code by writing a program that accepts two large decimal integers as strings, stores each one in two 32-bit registers, adds them, and then prints out the 64-bit result in two separate 32-bit pieces.  For example:  28,772,997,619,311 + 28,772,997,619,311 =  0x 0000 3456 789A BCDE.  You can look in the registers to see if this looks right.  Note that when you print the two registers in decimal you will get 13,398 and 2,023,406,814.  The actual number is 13,398 × 232 + 2,023,406,814.  If you wanted to display the 64-bit number in one long decimal value 57,545,995,238,622, you would need to implement subtraction and division.  A detailed extra credit assigment to do this is outlined below.

Extra Credit (30 points)

Write MIPS code to subtract two 64-bit numbers.  This is very similar to the last problem, but now we are using negative numbers and two's complement arithmetic.  The lower 32 bits are subtracted first, and the carry calculated and stored.  Then the upper 32 bits can be subtracted.  You don't need to explicitly do the two's complement yourself since it is done implicitly through the subtraction command.  Finally, if there is no carry from the result of the two upper 32 bits, then subtract one from the subtraction of the upper 32 bits.

The reason for processing carry's this way is because the upper 32 bits being subtracted will have an EXTRA 1 added to the right end that should NOT be there.  If there was a carry from the lower 32 bit subtraction then we are all even and nothing needs to be done, but if there was no carry from the lower 32 bit subtraction, then we have an extra one in the upper 32 bit subtraction and we must subtract 1 to even it out.  Figuring out whether or not there is a carry requires looking at the leftmost bit of each number.  To find the leftmost bit of the two's complemented number, you can subtract 1 from the (32-bit) number and then toggle the leftmost bit. (This is equivalent to but easier than toggling the bits and then adding one).


Write MIPS code that takes two words (64 bits) and displays a string of digits that represents the 64-bit integer value in base 10.   The algorithm is similar to reading but in reverse.  You should generate the string from right to left, each time dividing the 2-word number by 10, calculating the remainder and quotient.  The remainder is converted to the next character and stored in a string for printing later.  The quotient is re-written into the two words and used in the next iteration.  The hard step is dividing a 64-bit (2-word) number by 10 to get the quotient and remainder.  This is somewhat like the long division you learned in grade school.  You will need to use the 64-bit subtracter from part c.  Details may be discussed in class.

Using these segments of code, write a program to read in two strings representing two large decimal numbers, convert them to binary, add them,  and display their sum.  Don't do the program directly from the strings.  Make sure to use the segments you wrote above.

back

 


shai@stonehill.edu

http://www.stonehill.edu/compsci/shai.htm