Spring 2019 EE380 Assignment 3 Sample Solution

  1. For this question, check all that apply. Which of the following are correct statements about assembly languages for most modern computers?
    Enable masking is a key aspect of SIMD supercomputers and GPUs
    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
    Local variables for a function are usually allocated in registers or in the stack frame
  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?
    Each instruction is encoded in precisely one 32-bit word
    There are no conditional jump instructions, only conditional branches
    There is a call instruction that pushes the return address on the stack
    The result of a comparison for less than is a 32-bit integer value of 0 or 1
    To operate on a 32-bit value from memory, you must load it into a register first
  3. An array a of 32-bit integers is specified as shown below. On the MIPS architecture, suppose &(a[0]) is 4000. What is the lval of a[1]?
    int a[3] = { 22, 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
    	beq	$t1, $t1, l1
    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 addi $t0,$t1,2? 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 negy that will make x have the value which is the 2's complement negation of y (i.e., -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 popcount that will compute x=popcount(y);, the Population Count of y, the number of 1 bits in y's value. 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; t0 & (t0 - 1) removes the least-significant 1 bit from the value of t0.
    extern int x, y, z;
    
    void
    popcount(void)
    {
        int t0 = y;
        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 sort that will re-order the values of x, y, and z to be in decreasing order: the largest value should end up in x and the smallest in z. Your code should take advantage of the fact that x, y, and z are consecutive words in memory; you should treat x as an array of three elements. 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 mymin routine here.
  9. All the MIPS functions you wrote above were leaf functions, which means they don't call themselves nor any other functions. In each case, your function (subroutine) was called using jal and your code returned using jr $ra. Would that work for a non-leaf function or would you need to do something else? Briefly explain.
  10. What does the following C++ program print? Why?
    #include <iostream>
    using namespace std;
    int a=42, b=601;
    void f(int& x, int y) { ++x; ++y; }
    int main() {
      cout <<"a="<<a <<" b="<<b <<"\n";
      f(a,b);
      cout <<"a="<<a <<" b="<<b <<"\n";
    }
    


EE380 Computer Organization and Design.