1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: Mips subroutines

  1. Apr 6, 2012 #1
    This is the program i was asked to do

    Write two subroutines, one iterative and one recursive, that gets an unsigned integer as argument and returns the sum of all decimal digits in the integer. For example if the argument is 75080 then the sum to be returned is 20 (7+5+0+8+0). Write a main routine that prompts for an integer, calls these two subroutines with the input integer as argument and displays the returned value on the screen. Test your program.

    my code

    prompt: .asciiz "Enter the decimal number: "
    ans1: .asciiz "\nAnswer for iterative subroutine: "
    ans2: .asciiz "\nAnswer for recurseive subroutine: "


    ## asking for the decimal
    la $a0, prompt
    li $v0, 4

    li $v0, 5

    move $a0, $v0 #storing the integer in $t0
    jal iterative #calling subroutine
    add $s0, $v0,$zero

    # reading answer and printing answer
    la $a0, ans1
    li $v0, 4

    li $v0, 1
    move $a0, $s0

    li $v0, 10

    li $t1, 10
    div $a0, $t1 #dividing the integer by 10
    mfhi $t2 #obtaining the reminder and setting it on $t2
    mflo $t3 #setting the quotient to $t3
    add $s0, $s0,$t2 #adding the reminder to $s0
    move $a0, $t3
    beq $t3,0,exitloop
    j iterative


    move $v0, $s0
    jr $ra

    it is working but i think that am not getting the subroutines part right because from what i seen you need the stack pointer and saving spaces on the stack and stuff, and i don't think am doing it right.. any suggestions on how to go about this? , am barley getting used to mips this is like my 3rd time trying to write a program :D
  2. jcsd
  3. Apr 7, 2012 #2
    The recursive solution is about the same as the iterative one except instead of either ending the iteration or jumping to iterate once more, you either end the iteration by returning your answer to whoever called you or else call the function again.

    The purpose of the stack in all of this recursion is to allow you to keep data between calls. A function that calls itself cannot be sure most of the registers it can use will have the same data in it when it regains control. It can also be positive that the return address register ($ra) will have a different value. So if your function was not careful, it could be called by main, call itself, regain control, and then have no idea how to get back to main.

    To get by this problem, functions agree to a few things with respect to sp_0, the pointer address the function sees the moment it is called. They agree always to return to their caller with $sp = sp_0. They also agree never to alter any bytes located at address $sp >= sp_0. In this way, you can store things on the stack by putting things at $sp < sp_0 and then setting $sp equal to an address for which all your data is located in addresses greater than or equal to the current address. You call your function, pull your stuff off the stack, put the stack pointer where it was originally, and you have no problems.

    So in your example, your recursive function is almost exactly the same as your iterative one (since your iterative solution jumps to the top of the function itself). But you need to replace a few sections of code. Instead of j iterative, you need to subtract 8 bytes from the stack pointer to "allocate" space for you to use by convention. You then save your $ra to storage with the address $sp (which uses your 4 bytes). Then, save your remainder at the storage with the address $sp + 4 (another 4 bytes). You then jal to the recursive function (making sure your quotient is in your argument register).

    When, inside your recursive function, you have an answer, you need to do a few things:
    1.) retrieve your stored data from the stack
    2.) calculate what you know is the answer
    3.) return the stack to sp_0
    4.) return to your caller using jr $ra

    1.) you use lw using $sp (into your $ra) and $sp + 4 (to get your remainder).
    2.) the answer is the returned answer (in $v0) plus the the remainder you yourself computed (the contents of $sp + 4). Put the sum inside $v0 so that the next function you return to knows where to find the answer.
    3.) add 8 to the $sp since the function knows it subtracted 8 from it. This allows whatever function to which it returns to know how to find its data on the stack. Image a world where you call a function and have no idea where your data is on the stack anymore, because $sp is not equal to sp_0 when you return.
    4.) jr $ra
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook