EE380 Assignment 3 Solution

  1. For this question, check all that apply. Which of the following are correct statements about assembly languages for most modern computers?
    Arguments for a function are usually allocated in the stack frame
    A SIMD computer generally has some support for enable masking
    a+b is an add producing an rval, but a.b is an add that produces an lval
    The same add instruction could compute an integer result or an address
    Most computers have special instructions that implement if, else, while, and for
  2. For this question, check all that apply. MIPS is not a CISC architecture, but a RISC with a simple and highly regular instruction set. Which of the following attributes correctly describe the MIPS instruction set?
    There are special instructions for stack push/pop
    The processor has relative few registers; only eight
    Each instruction is encoded in precisely one 32-bit word
    To operate on a value from memory, you must load it into a register first
    Each word in memory has a few tag bits saying what type of data it holds
  3. An array a of 32-bit integers is specified as shown below. On the MIPS architecture, suppose &(a[0]) is 8000. What is the rval of a[2]?
    int a[3] = { 42, 86, 601 };
    

  4. Which of the following segments of C code best describes what the following MIPS assembly code does? (Note: oddly, unlike nearly every programming language, MIPS add detects integer overflow -- so you really should always use addu as this code does.)
    	la	$t0, x
    	lw	$t1, 0($t0)
    	la	$t2, y
    	lw	$t3, 0($t2)
    l1:	beq	$t1, $0, l2
    	addu	$t1, $t1, $t3
    l2:	sw	$t1, 0($t0)
    

    x=x+y;
    if (x==0) { x=x+y; }
    if (x!=0) { x=x+y; }
    while (x==0) { x=x+y; }
    while (x!=0) { x=x+y; }
  5. What is the 32-bit hexadecimal value used to represent the MIPS assembly language instruction ori $t0,$0,42? Hint: you can use SPIM to find out.
  6. This MIPS/SPIM program includes a subroutine called myadd that performs x=(y+z);. In the space below, replace the myadd subroutine with one named thrice that will make x have the value which is three times that of y (i.e., 3*y). You should test your routine using SPIM before you submit it, which will require merging it with a test framework like the one used in this MIPS/SPIM program -- but only submit the thrice routine here. Remember that you can and should comment your code, especially if there are any known bugs. Half off for documented bugs. :-)
  7. This (now familiar) MIPS/SPIM program includes a subroutine called myadd that performs x=y+z;. In the space below, replace the myadd subroutine with one named ham that will compute x=ham(y,z);, the Hamming Distance between y and z. Hamming Distance is defined as the number of bits that differ, and the following C code gives a simple algorithm to compute it. This uses a little trick credited to Brian Kernighan (and described here) to count the "population" of 1s in the XOR of the two numbers; t0 & (t0 - 1) removes the least-significant 1 bit from the value of t0.
    extern int x, y, z;
    
    void
    ham(void)
    {
        int t0 = y ^ z;
        int t1 = 0;
    
        while (t0) {
            t1 = t1 + 1;
            t2 = t0 - 1;
            t0 = t0 & t2;
        }
        x = t1;
    }
    

  8. This MIPS/SPIM program includes a subroutine called myadd that performs x=(y+z);. In the space below, replace the myadd subroutine with one named mymax that will make x=max(y,z). Your code may take advantage of the fact that x, y, and z are consecutive words in memory. You should test your routine using SPIM before you submit it, which will require merging it with a test framework like the one used in this MIPS/SPIM program -- but only submit the mymax routine here.
  9. In the space below, write MIPS code for a leaf subroutine mymul that will compute x=y*z;. Hint: use addu because add detects overflow. You should test your routine using SPIM before you submit it. Although there are many ways to do a multiply, here's C code for one of them that you might want to use:
    extern int x, y, z;
    
    void
    mymul(void)
    {
         /* do x = y * z the hard way... */
         int t0 = 0;
         int t1 = 1;
         int t2 = y;
         int t3 = z;
    
         while (t1 != 0) {
              if ((t1 & t3) != 0) {
                   t0 += t2;
              }
              t1 += t1;
              t2 += t2;
         }
    
         x = t0;
    }
    


EE380 Computer Organization and Design.