# MIPS program to find the sum and square sum of 10 integers

I wrote a program (hard-code) in MIPS that gets an array of 10 integers and calculates the sum and the square sum of them. The array is {23,-2,45,67,89,12,-100,0,120,6}

.data
array: .word 23,-2,45,67,89,12,-100,0,120,6 # array = {23,-2,45,67,89,12,-100,0,120,6}
length: .word 10 # the length of the array is 10
sum: .word 0 # the sum of the integers (in array) is 0
squareSum: .word 0 # the square sum of the integers (in array) is 0
sumMessage: .asciiz "The sum of the array(sign) is: "
squareMessage: .asciiz "The sum of the squares(sign) is: "
newLine: .asciiz "\n"

# 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)

.text
main:

li $t0, 0 # load immediate 0 in register$t0 (sum)
li $t5, 0 # load immediate 0 in register$t0 (squarSum)
la $t3, array # load base addr. of array into$t3
lw $t2, length # load length in register$t2
addi $t2,$t2, -1 # $t2 = length - 1 li$t1, 0 # initialize i in $t1 to 0 loop: bgt$t1, $t2, exit # exit loop when i > (length-1) mul$t4, $t1, 4 # multiple i by 4 to get offset within array add$t4, $t3,$t4 # add base addr. of array to $t4 to get addr. of array[i] lw$t4, 0($t4) # load value of array[i] from memory into$t4
add $t0,$t0, $t4 # update sum mul$t6, $t4,$t4 # temp register %t6
add $t5,$t5,$t6 # update squareSum addi$t1, $t1, 1 # increment i j loop exit: # 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  Is this a good implementation? How can I improve it? ## 1 Answer 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 • I didn't understand the "arrend" part. how does it know that $t2 = 10? – ovedpo ovedpo Aug 13 '16 at 10:34