Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

If you'd like to see some further tips on writing good/clean asm, based on my own personal experience, see my answer here: http://stackoverflow.com/questions/36538325/mips-linked-list/36560575#36560575 https://stackoverflow.com/questions/36538325/mips-linked-list/36560575#36560575

If you'd like to see some further tips on writing good/clean asm, based on my own personal experience, see my answer here: http://stackoverflow.com/questions/36538325/mips-linked-list/36560575#36560575

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

Post Migrated Here from stackoverflow.com (revisions)
Source Link

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: http://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

lang-lisp

AltStyle によって変換されたページ (->オリジナル) /