Instructions: This is a closed book, closed note exam. Calculators are not permitted. If you have a question, raise your hand and I will come to you. Please work the exam in pencil and do not separate the pages of the exam. For maximum credit, show your work. Good Luck! Your Name (please print) 1 2 3 4 total 25 25 24 26 100 1
Problem 1 (5 parts, 25points) Code Fragments and Short Answers Part A (7 points) Write a MIPS code fragment that adds the value 0x4FA2C3 to register $1 and puts the result in $2. Modify only registers $1 and $2. (You may use hexadecimal immediate values.) For maximum credit, include comments. Label Instruction Comment Part B (10 points) Write a C code fragment that loops through an array of integers A until it hits one that is zero. It should compute and store in the variable p the running product of the nonzero integers that occur in the array before the zero. Assume that A contains at least one zero and it contains at least one nonzero integer before the first zero. For maximum credit, choose the most appropriate loop construct and declare and initialize variables as needed. int A[] = {..., 0,...; int p; Part C (2 points) In the following command, what does -Wall tell gcc to do? gcc HW1-2.c g Wall o HW1-2 Part D (2 points) Suppose your current working directory is ece2035 and it has a subdirectory called HW1. Write a Linux command to change to the subdirectory HW1. Part E (4 points) Suppose you give the Linux command: mv P1-1-shell.c P1-1.c What is argc? What is argv[0]? Argc = Argv[0] = 2
Problem 2 (1 part, 25 points) Flow Control Draw a control flow diagram for the following C code fragment based on the HW1-2.c set intersection baseline. int i, j, k=0, x; for (i = 0; i < 10; i++) { x = SetA[i]; for (j = 0; j < 10; j++) { if (x == SetB[j]) { printf("%d\n", x); k++; break; printf("size: %d\n", k); 3
Problem 3 (2 parts, 24 points) Baseline Reverse Engineering Consider the following code fragment based on a simplification of the HW2 maximum mode baseline. This code loops through the Nums array of values. It maintains the following variables in these registers: $1 I (index into Nums array) $7 ModeFreq (max frequency encountered so far) $2 Mode (most frequently occuring element so far) $8 Predicate register $3 Nums[I] (current element) $9 Array bound $6 Freq (current element's frequency) Part A (12 points) For the instructions that have no comments (i.e., those in lines 3-9), provide a description of each instruction in terms of the variables given in the table above. Label Instruction Comment OuterLoop: lw $3, Array($1) # load current value (i.e., Nums[I]) 1... 2 slt $8, $7, $6 # 3 bne $8, $0, Update # bne $7, $6, NextElt # slt $8, $2, $3 # beq $8, $0, NextElt # 4 5 6 7 Update: addi $2, $3, 0 # 8 addi $7, $6, 0 # 9 NextElt: addi $1, $1, 4 # increment array pointer index 10 bne $1, $9, OuterLoop # exit loop if hit array bound 11 Part B (12 points) The code in lines 3-7 can be used to implement a compound predicate that determines whether Mode and ModeFreq are updated in the following loop (also based on the HW2 baseline). Fill in the blank line with the compound predicate that lines 3-7 implement. for (I = 0; I < 100; I++) { Freq = 0; for (J = I; J < 100; J++) if (Nums[I] == Nums[J]) Freq++; if ( ) { Mode = Nums[I]; ModeFreq = Freq; 4
Problem 4 (2 parts, 26 points) Subroutines and Stack Part A (12 points) Complete this MIPS subroutine that takes three inputs: an integer in $3, a running sum in $5, and a count in $7. If the integer in $3 is odd, it adds it to the running sum in $5 and increments the count in $7. You may use additional registers. Label Instruction Comment CountOdd: # is integer in $3 even? Return: # then return to caller # else add $3 to running sum $5 # increment count in $7 # return to caller Part B (14 points) The following MIPS subroutine computes the average of all the odd numbers in an integer array starting at location labeled Array. Registers are used as follows: $1 Array index $5 Running sum of odd numbers; output average $2 Size of the array in bytes $7 Running count of odd numbers $3 Current Array element $8 Predicate register Complete the routine by adding MIPS code to preserve registers before the jal by pushing them on the stack and to restore them after the subroutine call. Assume CountOdd can modify any registers, not just the ones your version modified in Part A. OddAvg: addi $1, $0, 0 # init Array index addi $2, $0, 400 # init Array size addi $5, $0, 0 # init Array index addi $7, $0, 0 # init Array index Loop: lw $3, Array($1) # load in current element jal CountOdd # in: $3, $5, $7; out: $5, $7 addi $1, $1, 4 # inc Array index bne $1, $2, Loop # if end not reached, loop div $5, $7 # odd running sum / odd count mflo $5 # put odd number avg in $5 jr $31 # return to caller 5
MIPS Instruction Set (core) instruction example meaning arithmetic add add $1,$2,$3 $1 = $2 + $3 subtract sub $1,$2,$3 $1 = $2 - $3 add immediate addi $1,$2,100 $1 = $2 + 100 add unsigned addu $1,$2,$3 $1 = $2 + $3 subtract unsigned subu $1,$2,$3 $1 = $2 - $3 add immediate unsigned addiu $1,$2,100 $1 = $2 + 100 set if less than slt $1, $2, $3 if ($2 < $3), $1 = 1 else $1 = 0 set if less than immediate slti $1, $2, 100 if ($2 < 100), $1 = 1 else $1 = 0 set if less than unsigned sltu $1, $2, $3 if ($2 < $3), $1 = 1 else $1 = 0 set if < immediate unsigned sltui $1, $2, 100 if ($2 < 100), $1 = 1 else $1 = 0 multiply mult $2,$3 Hi, Lo = $2 * $3, 64-bit signed product multiply unsigned multu $2,$3 Hi, Lo = $2 * $3, 64-bit unsigned product divide div $2,$3 Lo = $2 / $3, Hi = $2 mod $3 divide unsigned divu $2,$3 Lo = $2 / $3, Hi = $2 mod $3, unsigned transfer move from Hi mfhi $1 $1 = Hi move from Lo mflo $1 $1 = Lo load upper immediate lui $1,100 $1 = 100 x 2 16 logic and and $1,$2,$3 $1 = $2 & $3 or or $1,$2,$3 $1 = $2 $3 and immediate andi $1,$2,100 $1 = $2 & 100 or immediate ori $1,$2,100 $1 = $2 100 nor nor $1,$2,$3 $1 = not($2 $3) xor xor $1, $2, $3 $1 = $2 $3 xor immediate xori $1, $2, 255 $1 = $2 255 shift shift left logical sll $1,$2,5 $1 = $2 << 5 (logical) shift left logical variable sllv $1,$2,$3 $1 = $2 << $3 (logical), variable shift amt shift right logical srl $1,$2,5 $1 = $2 >> 5 (logical) shift right logical variable srlv $1,$2,$3 $1 = $2 >> $3 (logical), variable shift amt shift right arithmetic sra $1,$2,5 $1 = $2 >> 5 (arithmetic) shift right arithmetic variable srav $1,$2,$3 $1 = $2 >> $3 (arithmetic), variable shift amt memory load word lw $1, 1000($2) $1 = memory [$2+1000] store word sw $1, 1000($2) memory [$2+1000] = $1 load byte lb $1, 1002($2) $1 = memory[$2+1002] in least sig. byte load byte unsigned lbu $1, 1002($2) $1 = memory[$2+1002] in least sig. byte store byte sb $1, 1002($2) memory[$2+1002] = $1 (byte modified only) branch branch if equal beq $1,$2,100 if ($1 = $2), PC = PC + 4 + (100*4) branch if not equal bne $1,$2,100 if ($1 $2), PC = PC + 4 + (100*4) jump jump j 10000 PC = 10000*4 jump register jr $31 PC = $31 jump and link jal 10000 $31 = PC + 4; PC = 10000*4 6