Reputation:
Write a MIPS program that generates and adds up all even numbers from 1 to 100.
main:
li $t0, 0 # clear register $t0 to zero
li $t4, 0 # clear register $t4 to zero
loop:
add $t0, $t0, 2 # generating even numbers in register $t0
add $t4, $t4, $t0 # compute the sume
bne $t0, 100, loop # if t0 reached 100 then go to loop.
b endloop # branch to endloop
endloop:
li $v0, 10 # terminate program run and
syscall # Exit
Is this correct?
Upvotes: 5
Views: 40357
Reputation: 92795
I just completed my MIPs assembly class and I have a suggestion for you: Don't use PC Spim!
I've used PC Spim, Mars, and Qemu and the best for general course work is the Mars (Mips Assembler and Runtime Simulator). The editor is nice, it crashes a lot less and it allows you to easily debug and set breakpoints. It is free, open source and created by Missouri State University.
It comes as a .jar file so you can run it on both Windows and Linux.
[Mars Mips Emulator]
In the general case, an easy way to tell if a number is even or odd is to AND (bitwise) 1 with the number and if the result is 0 then the number is even.
However, since we want all the even numbers in a series we can just loop and increment our number by 2 like you did in your posted code.
When adding an immediate value you should use "addi" or "addu" instructions, not "add". You also said you wanted to put the result in register $r12 but this is not a valid MIPs register. Check out MIPs wikipedia link to see a list of all the registers: MIPS - Register Usage.
I've modified your program to work correctly. It stores the final result in $t1 and then prints the final result.
.text
.globl main
main:
li $t0, 0 # $t0 = loop counter
li $t1, 0 # $t1 = sum of even numbers
loop:
addi $t0, $t0, 2 # generating even numbers in register $t0
add $t1, $t1, $t0 # compute the sum
bne $t0, 100, loop # if t0 reached 100 then go to loop.
li $v0, 4
la $a0, result
syscall # print out "Sum = "
li $v0, 1
move $a0, $t1
syscall # print out actual sum
exit:
li $v0, 10 # terminate program run and
syscall # Exit
.data
result: .asciiz "Sum = "
After running this in Mars I get the following:
Sum = 2550
-- program is finished running --
Upvotes: 10
Reputation: 45104
Code looks ok. As cunwold said, the "b endloop" is unnecesary, since the branch target is the first branch (bne...) fallthrough. There is one mistake though.
You are using the same instruction (add) in two different ways. The instruction
add $t0,$t0,2
should be
addiu $t0,$t0,2
Since you are adding an inmediate, not two registers.
So, here it goes. I replaced the syscall part with an actual return to a function (value returns in $v0 register).
Hope it helps.
File main.c
#include <stdio.h>
extern int addEven();
int main(){
printf("%d\n",addEven());
return 0;
}
File addEven.S (assembly)
#include <mips/regdef.h>
/*
* int addEven();
* Adds even numbers between 0 and 100.
* 0 + 2 + 4 + 6 +....+100 = 2550
*/
.text
.align 2
.globl addEven
addEven:
li t0,0 # clear register $t0 to zero
li t4,0 # clear register $t4 to zero
loop:
addiu t0, t0,2 # generating even numbers in register $t0
add t4, t4,t0 # compute the sume (R12 = t4)
bne t0, 100, loop # if t0 reached 100 then go to loop.
endloop:
move v0,t4
jr ra
I compiled and linked these files. Here it goes.
root@:~/stackoverflow# gcc -c -g addEven.S
root@:~/stackoverflow# gcc -c -g main.c
root@:~/stackoverflow# gcc main.o addEven.o -o prog
root@:~/stackoverflow# ./prog
2550
root@:~/stackoverflow#
Upvotes: 1
Reputation: 10254
You should be able to use SPIM yourself. Also the line "b endloop" is unnecessary because if you don't branch back up to the top of loop the program will "fall into" endloop.
Download SPIM here:
http://pages.cs.wisc.edu/~larus/spim.html
Upvotes: 1