2007 Fall Exam1 Solpp
2007 Fall Exam1 Solpp
1 40
2 20
3 40
Total 100
1
Question 1: Write a recursive MIPS function (40 points)
The fundamental theorem of arithmetic states that every natural number greater than 1 can be written as a
unique product of prime numbers. The number of prime factors of a number can be computed by the
recursive function count_factors by passing 2 as the second argument. For example, the number 20 has
prime factors (2, 2, 5) so count_factors(20,2) will return 3. Translate count_factors into a
recursive MIPS assembly language function; iterative versions (i.e., those with loops) will not receive full
credit. You will not be graded on the efficiency of your code, but you must follow all MIPS conventions.
Comment your code!!!
unsigned
Note: pseudo instructions exist
count_factors(unsigned num, unsigned factor) {
for the modulo (%) and
if (num == 1) {
divison (/) operations. See the
return 0;
reference at the end of the test.
}
You can assume these work
if ((num % factor) == 0) {
for unsigned integers.
return 1 + count_factors(num/factor, factor);
}
return count_factors(num, factor+1);
}
count_factors:
bne $a0, 1, cf_recurse # if (num == 1)
move $v0, $0 # return 0;
jr $ra
cf_recurse:
sub $sp, $sp, 4
sw $ra, 0($sp)
cf_recurse1:
addi $a1, $a1, 1
jal count_factors # count_factors(num, factor + 1)
cf_end:
lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra
2
Question 2: Concepts (20 points)
Write a short answer to the following questions. For full credit, answers should not be longer than two
sentences.
Part a) Write the body of a function that takes an integer “in” and returns the same value with the “n”th bit
inverted (i.e., 0->1, 1->0). This can be done using just bit-wise logical operations and shifts. No control
flow (e.g., loops/ifs) are needed. (10 points)
Example: flip_nth_bit(0x04F2, 7)→ 0x0472
unsigned 0 4 F 2
0000 0100 1111 0010
flip_nth_bit(unsigned in, unsigned n) {
return in ^ (1<<n);
0000 0100 0111 0010
-- or --
0 4 7 2
li $t0, 1
sll $t0, $t0, $a1
xor $v0, $t0, $a0
jr $ra
}
Part b) What is an abstraction layer? How does it relate to instruction set architectures (ISAs)? (5 points)
ISAs are an example of an abstraction layer because they describe the interface to hardware, without
details of the implementation. This idea enables binary compatibility across generations of hardware.
Part c) Why does MIPS have multiple instruction formats (e.g., R-type, I-type, J-type)? What is the
motivation for including each format ? (5 points)
There are a limited number of bits in the instruction; the different instruction formats spend them
differently.
R-types are used when instructions have two sources and a destination register (allocate the remainder
of bits for extra opcode space: the func field). I-type are used when two registers and an immediate
are needed. J-type enable using almost all of the instruction bits for an immediate.
3
Question 3: Understanding MIPS programs (40 points)
foo: li $t0, 1
li $v0, 0
A: bge $t0, $a1, B
sll $t1, $t0, 2
add $t1, $t1, $a0
lw $t2, 0($t1)
lw $t3, -4($t1)
ble $t2, $t3, C
add $t0, $t0, 1
j A
B: li $v0, 1
C: jr $ra
Part (a)
Translate the function foo above into a high-level language like C. Your function header should list the types
of any arguments and return values. Also, your code should be as concise as possible, without any gotos or
pointer arithmetic. We will not deduct points for syntax errors unless they are significant enough to alter the
meaning of your code. (30 points)
int
foo(int *arr, int n) {
for (int i = 1; i < n; i++) {
if (arr[i] <= arr[i - 1]) {
return 0;
}
}
return 1;
}
Part (b)
Describe briefly, in English, what this function does. (10 points)
foo takes an int array $a0 of length $a1 and returns true if the integers in the array are in ascending
order.
4
MIPS instructions
These are some of the most common MIPS instructions and pseudo-instructions, and should be all you
need. However, you are free to use any valid MIPS instructions or pseudo-instruction in your programs.
The second source operand of the arithmetic, logical, and branch instructions may be a constant.
Register Conventions
The caller is responsible for saving any of the following registers that it needs, before invoking a function.
$t0-$t9 $a0-$a3 $v0-$v1
The callee is responsible for saving and restoring any of the following registers that it uses.
$s0-$s7 $s8/$fp $sp $ra
Pointers in C:
Declarartion: either char *char_ptr -or- char char_array[] for char c
Dereference: c = c_array[i] -or- c =*c_pointer
Take address of: c_pointer = &c 5
Hexadecimal Notation
C and languages with a similar syntax (such as C++, C# and Java) prefix hexadecimal numerals with "0x",
e.g. "0x5A3". The leading "0" is used so that the parser can simply recognize a number, and the "x" stands
for hexadecimal.