Your program is correct. I ran it and verified the results against a C program. So, it works and the code is pretty good, too.
You did a good job of commenting. Especially, the top block where you detail the algorithm and the intended register usage. And, putting a sidebar comment on each asm line is also very good.
But, you also wanted to know how to improve it. So, a few things ...
I realize you're just starting out, but sidebar comments should talk about intent. That is, what are we doing with the algorithm, instead of just rehashing the mechanics of the asm instruction.
I tightened things up a bit. Instead of what you did (in C/pseudo code):
int i;
int val;
for (i = 0; i <= (length - 1); ++i) {
val = array[i];
...
}
I changed this into:
int *arrptr;
int *arrend;
int val;
arrptr = array;
arrend = &array[length];
for (; arrptr < arrend; ++arrptr) {
val = *arrptr;
...
}
I was also able to eliminate a few extra instructions by changing some of the registers being used and eliminate a extra branch instruction in the loop
Anyway, here's the cleaned up/improved code [please pardon the gratuitous style cleanup]:
.data
array: .word 23,-2,45,67,89,12,-100,0,120,6
arrend:
sumMessage: .asciiz "The sum of the array(sign) is: "
squareMessage: .asciiz "The sum of the squares(sign) is: "
newLine: .asciiz "\n"
# array = {23,-2,45,67,89,12,-100,0,120,6}
# the sum of the integers (in array) is 0
# the square sum of the integers (in array) is 0
# Algorithm being implemented to sum an array
# sum = 0 (use $t0 for sum)
# squarSum = 0 (use %t5 for squarSum)
# for i = 0 to length-1 do (use $t1 for i)
# sum = sum + array[i] (use $t2 for length-1)
# squareSum = squareSum + array[i]*array[i]
# end for (use $t3 for base addr. of array)
# registers:
# t0 -- sum
# t5 -- squarSum
#
# t3 -- pointer to current array element (e.g. arrptr)
# t2 -- pointer to end of array
#
# t4 -- current value fetched from array
# t6 -- temp to hold squared value
.text
main:
li $t0,0 # sum = 0
li $t5,0 # squarSum = 0
la $t3,array # load base addr. of array
la $t2,arrend # load address of array end
j test
loop:
lw $t4,0($t3) # load array[i]
addi $t3,$t3,4 # increment array pointer
add $t0,$t0,$t4 # update sum
mul $t6,$t4,$t4 # get val * val
add $t5,$t5,$t6 # update squareSum
test:
blt $t3,$t2,loop # more to do? if yes, loop
# print sum message
li $v0,4
la $a0,sumMessage
syscall
# print value of sum
li $v0,1
addi $a0,$t0,0
syscall
# print new line
li $v0,4
la $a0,newLine
syscall
# print square sum message
li $v0,4
la $a0,squareMessage
syscall
# print value of squareSum
li $v0,1
addi $a0,$t5,0
syscall
li $v0,10
syscall
If you'd like to see some further tips on writing good/clean asm, based on my own personal experience, see my answer here: https://stackoverflow.com/questions/36538325/mips-linked-list/36560575#36560575
UPDATE:
I didn't understand the "arrend" part. how does it know that $t2 = 10
?
$t2
no longer has a count. It was repurposed to hold the address of the array's end address. The two loops are fundamentally different in how they iterate and terminate. This was evidenced in the C samples given above.
Your code used $t2
to hold the length/count of array
, which was 10
. Your loop was using an index variable [contained in $t1
] to iterate through the array and stopping when the index value hit the count. It was incrementing the index value by 1
on each loop iteration.
In the modified code, $t2
holds the address of arrend
. This is "one beyond" the last element of array
. The loop stops when the pointer to the current array value [in $t3
] hits/equals the array end. It was incrementing the pointer by 4
on each iteration.
In strictest terms, the loop doesn't use or care about the count. What it cares about is: "If I know the address of the array end, has my current address/pointer gone past it?"
Just for completeness, let's go the other way. In mars
, array
has address 0x10010000
and arrend
has address 0x10010028
. If we subtract the addresses, arrend
is offset from array
by 0x28
bytes, which is 40
(decimal). If we divide this by 4 [the size of a word] to get the count, we have 10