I wrote a simple summation program in MARS to practice using loops and jump instructions. I feel like this is pretty lightweight and wanted some feedback on possible improvements:
- Lowering instruction count
- Organizational changes
Am I correct in assuming this is a "do-while" loop?
# Description: Summation program implementing a do-while loop
# Author: Evan Bechtol
.data
Prompt: .asciiz "Enter number to get summation: "
Output: .ascii "Sum of numbers is: "
.globl main
.text
main:
# Prompt for input
li $v0, 4
la $a0, Prompt
syscall
# Read input
li $v0, 5
syscall
add $s0, $zero, $v0
# Begin summation
addi $s1, $zero, 1 # $s1 used to store summation, starts at 1
addi $t1, $zero, 1 # $t1 used as counter, starts at 1
jal loop # Go to loop
# Display
li $v0, 4
la $a0, Output
syscall
li $v0, 1
add $a0, $zero, $s1
syscall
# Exit
la $v0, 10
syscall
loop:
addi $t1, $t1, 1
add $s1, $s1, $t1
bne $t1, $s0, loop
jr $ra
2 Answers 2
I see a number of things that might help you improve your program.
Use li
rather than la
to load a constant
As has already been noted, the la $v0, 10
instruction should actually be li $v0, 10
. It works that way because you're loading the address 10 into $v0
which has the same effect, but it's a little strange looking.
Put the $zero
at the end of the instruction
The instruction add $s0, $zero, $v0
is perfectly valid, but it might look a little odd to those experienced with MIPS assembly language. The typical idiom that I've seen is to put the constant at the end, so that instruction would instead read add $s0, $v0, $zero
which does exactly the same thing, but I find it easier to pick out the $zero
at the end rather than in the middle. That's purely a stylistic suggestion, though.
Minimize register use
You don't really need both a counter and a number. What you can do instead is to use the original input number in $s0
as the counter and decrement instead of incrementing.
Avoid the overhead of subroutine calls
There's nothing wrong with using subroutines, of course, but they add cycles to the program, and for such a small and simple program as this, the call isn't really necessary. Instead, you could put the loop inline.
Prefer to branch at the end of a loop
A while...
loop in higher level languages does not even execute once if its condition is false. A do ... while
loop executes at least once, which seems to me to be what is desired here. You can then minimize branching so that there is only one conditional branch at the end of the loop.
Use a better algorithm
Carl Friedrich Gauss came up with a clever algorithm as a child. You can read about it and see if you can implement it for even faster code.
Putting it all together
When we apply all but the last suggestion, we get something like this:
.data
Prompt: .asciiz "Enter number to get summation: "
Output: .ascii "Sum of numbers is: "
.globl main
.text
main:
# Prompt for input
li $v0, 4
la $a0, Prompt
syscall
# Read input
li $v0, 5
syscall
add $s0, $v0, $zero # s0 used as loop countdown
add $s1, $s1, $zero # s1 used for summation = 0
loop:
add $s1, $s1, $s0 # add number to summation
# Begin summation
addi $s0, $s0, -1 # decrement number
bgtz $s0, loop # keep going until 0
# Display
li $v0, 4
la $a0, Output
syscall
li $v0, 1
add $a0, $s1, $zero
syscall
# Exit
li $v0, 10
syscall
-
\$\begingroup\$ Thanks for all of the suggestions! I had never known that trick for deriving the summation, really clever! ;) The only reason I used the subroutine call was to get some practice with the jump instructions, otherwise I would put it in-line as you suggested. I do like your implementation though and wasn't aware of bgtz! \$\endgroup\$Evan Bechtol– Evan Bechtol2015年03月27日 13:37:41 +00:00Commented Mar 27, 2015 at 13:37
Am I correct in assuming this is a "do-while" loop?
If this refers to the code following a loop
label, the answer is almost. jal loop
makes a function call, so a Go to loop
comment is misleading.
Otherwise I don't see anything wrong, as long as it passes tests.
PS: I don't think that la $v0, 10
(aka Exit
) is correct. Perhaps li $v0, 10
?
-
\$\begingroup\$ Good catch on changing that "la" to "li"! I didn't even notice and am surprised it works how it is. Also, i did mean the code after "loop", when asking if it is a do-while. What do you man it is almost a do - while? \$\endgroup\$Evan Bechtol– Evan Bechtol2015年03月27日 12:36:14 +00:00Commented Mar 27, 2015 at 12:36