MIPS Subroutines: Get Sum of Decimal Digits

  • Thread starter Thread starter unoathingshad
  • Start date Start date
  • Tags Tags
    Mips
Click For Summary
The discussion focuses on creating two MIPS subroutines—one iterative and one recursive—that calculate the sum of decimal digits of an unsigned integer. The iterative subroutine is implemented, but there are concerns about properly managing the stack and return addresses in the recursive version. Key points include the importance of saving the return address and local data on the stack to maintain control flow during recursive calls. Suggestions emphasize adjusting the stack pointer and using load and store instructions to manage data effectively. Overall, understanding stack management is crucial for implementing the recursive solution correctly.
unoathingshad
Messages
4
Reaction score
0
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
.data

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

.text

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

li $v0, 5
syscall

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
syscall

li $v0, 1
move $a0, $s0
syscall

li $v0, 10
syscall

iterative:
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

exitloop:

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
 
Physics news on Phys.org
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

So
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
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
5K
  • · Replies 2 ·
Replies
2
Views
5K
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 4 ·
Replies
4
Views
10K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 3 ·
Replies
3
Views
13K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 12 ·
Replies
12
Views
11K
  • · Replies 1 ·
Replies
1
Views
24K