ECE 30 Introduction to Computer Engineering Study Problems, Set #4 Spring 2015 Note: To properly study and understand the problems below, it is strongly recommended to implement and run your solution (and/or the proposed solution) in SPIM. 1. Write a program that allows the user to input two integers and calculates its sum. Solution:.data message:.asciiz "sum = ".text.globl main main: addiu $sp, $sp, -32 # begin callee organizational tasks; stack frame sw $ra, 20($sp) # $ra stored on stack frame sw $fp, 16($sp) # $fp stored on stack frame addiu $fp, $sp, 32 # end callee organizational tasks; setup $fp li $v0, 5 # system call for read_int move $s0, $v0 # move first number read to $s0 li $v0, 5 # system call for read_int add $t2, $s0, $v0 # add the two numbers and store in $t2 li $v0, 4 la $a0, message li $v0, 1 move $a0, $t2 lw $ra, 20($sp) lw $fp, 16($sp) addiu $sp, $sp, 32 jr $ra # system call for print_string # message to be printed # system call for print_int # number in $t2 is to be printed # begin callee organizational tasks; restore $ra # restore $fp # end callee organizational tasks; pop stack frame # return to caller 1
2. Write a procedure in MIPS R2000 assembly language that illustrates the use of switch-case in C language for selection. Suppose you have 8 different colours which are black, blue, yellow, green, red, purple, orange and white. Number them as 0, 1, 2, 3, 4, 5, 6 and 7 respectively. Your code should read an integer (i.e., 0, 1, 2, 3, 4, 5, 6 or 7), select the corresponding color and print it to the console. Solution:.text main: li $v0, 5 # system call for read_int move $s0, $v0 # move color number to $s0 bne $s0, 0, c1 # if s0!= 0 (black), jump to c1 la $a0, black # else load address of black in $a0 # jump to cx c1: bne $s0, 1, c2 # if s0!= 1 (blue), jump to c2 la $a0, blue # else load address of blue in $a0 # jump to cx c2: bne $s0, 2, c3 # if s0!= 2 (yellow), jump to c3 la $a0, yellow # else load address of yellow in $a0 # jump to cx c3: bne $s0, 3, c4 # if s0!= 3 (green), jump to c4 la $a0, green # else load address of green in $a0 # jump to cx c4: bne $s0, 4, c5 # same for red la $a0, red c5: bne $s0, 5, c6 # same for purple la $a0, purple c6: bne $s0, 6, c7 # same for orange la $a0, orange c7: bne $s0, 7, c8 # same for white la $a0, white c8: la $a0, other # default case: load address of other in $a0 2
cx: li $v0, 4 # system call for print_string.data black:.asciiz "black\n" blue:.asciiz "blue\n" yellow:.asciiz "yellow\n" green:.asciiz "green\n" red:.asciiz "red\n" purple:.asciiz "purple\n" orange:.asciiz "orange\n" white:.asciiz "white\n" other:.asciiz "other\n" 3. Write a program to compute 4 i=1 i2. Your code should print the following to the console: Result : 30. Solution: main: move $s0, $zero # $s0 : i move $s1, $zero # $s1 : sum addi $s2, $zero, 4 # $s2 : upper bound (4) for the sum loop: mul $t0, $s0, $s0 # Compute i^2 add $s1, $s1, $t0 # Accumulate sum addi $s0, $s0, 1 # Increase i ble $s0, $s2, loop # Loop control: if (i <= 4) goto loop # Print string "\nresult : " li $v0, 4 # system call for print_string (option: 4) la $a0, str # load the string address into $a0 (argument) # Print sum (integer) li $v0, 1 # system call for print_int (option: 1) move $a0, $s1 # Print string "\n" li $v0, 4 # system call for print_string (option: 4) la $a0, newl # load the string address into $a0 (argument) 3
.data str:.asciiz "\nresult : " newl:.asciiz "\n" 4. Write a procedure in assembly to calculate the n-th number in the Fibonacci sequence, 1 1 2 3 5 8 13... The pseudocode is written below. The main function prompts the user for the value of n and outputs an answer of the form f(6) = 8 (for n equal to 6). void main print_string("n = ") n = read_int v = fibonacci(n) print_string("f(") print_int(n) print_string(") = ") print_int(v) int fibonacci(int n) if n == 0 return 0 elseif n == 1 return 1 else return fibonacci(n-1) + fibonacci(n-2) You only need to write the code for fibonacci. The code for the main function is given below. Complete the program and run it in SPIM..data prompt:.asciiz "\nn = " str1:.asciiz "f(" str2:.asciiz ") = " main:.globl main.globl fibonacci.text # Establish new frame # 4
# decrement the stack pointer addiu $sp, $sp, -12 # save return address sw $ra, 8($sp) # save old frame pointer sw $fp, 4($sp) # set frame pointer addiu $fp, $sp, 12 # Run procedure # # print prompt li $v0, 4 la $a0, prompt # read N li $v0, 5 move $a0, $v0 # store N on stack sw $a0, 0($fp) # call fibonacci jal fibonacci # store V in temporary register $t0 move $t0, $v0 # print "f(" li $v0, 4 la $a0, str1 # print N li $v0, 1 lw $a0, 0($fp) # print ") = " li $v0, 4 la $a0, str2 5
# Pop stack # # print V li $v0, 1 move $a0, $t0 # restore return address lw $ra, 8($sp) # restore frame pointer lw $fp, 4($sp) # increment stack pointer addiu $sp, $sp, 12 # return to caller jr $ra fibonacci: # (your code here) Solution: fibonacci: # Establish new frame # # decrement the stack pointer addiu $sp, $sp, -16 # save return address sw $ra, 8($sp) # save old frame pointer sw $fp, 4($sp) # set frame pointer addiu $fp, $sp, 16 # Run procedure # # check if n == 0 bne $a0, $zero, skip1 6
# set V = 0 li $v0, 0 # jump to done j done skip1: # check if n == 1 li $t0, 1 bne $a0, $t0, skip2 # set V = 1 li $v0, 1 # jump to done j done skip2: # store N on stack sw $a0, 0($fp) # call fibonacci(n-1) addi $a0, $a0, -1 jal fibonacci # store fibonacci(n-1) on stack # this establishes two steps in one: # - store the result $v0 in temporary register $t0 # - push $t0 on the stack to conserve it through the next procedure call sw $v0, -4($fp) # restore N from stack lw $a0, 0($fp) # call fibonacci(n-2) addi $a0, $a0, -2 jal fibonacci # Pop stack # # restore fibonacci(n-1) from stack, into $t0 lw $t0, -4($fp) # fibonacci(n) = fibonacci(n-1) + fibonacci(n-2) add $v0, $t0, $v0 done: # restore return address lw $ra, 8($sp) 7
# restore frame pointer lw $fp, 4($sp) # increment stack pointer addiu $sp, $sp, 16 # return to caller jr $ra 8