Reputation: 21
I'm implementing the following code from c to mips assembly
/*
Given an array arr terminated by entry -1, transform the array by adding
to each entry the sum of the remainder of the array after that entry.
That is, if initially arr == [a_0, a_1, ..., a_n, -1], then finally
arr == [b_0, b_1, ..., b_n, -1], where b_j = sum(a_i for i in j..n-1).
*/
uint32_t reverse_prefix_sum(uint32_t *arr) {
uint32_t r;
if(*arr == -1) return 0;
r = reverse_prefix_sum(arr+1) + (uint32_t)*arr;
*arr = r; /* may discard MSB */
return(r);
}
My current program is the following:
reverse_prefix_sum: # Let the address of array arr be in $a0
# adjust the stack pointer to save $a0 and $ra
addi $sp,$sp,-8
sw $a0,0($sp)
sw $ra,4($sp)
# Load *arr
lw $t0,0($a0)
beq $t0,-1,exit1 # r is in $v0
# *arr = *arr + 1
addu $a0,$a0,4 # recursive call
jal reverse_prefix_sum
addu $v0,$v0,$t0
# restore $a0
lw $a0,0($sp)
#restore $ra
lw $ra,4($sp)
add $sp,$sp,8
sw $v0,0($a0)
jr $ra
exit1:
# restore $a0
lw $a0,0($sp)
#restore $ra
lw $ra,4($sp)
addi $sp,$sp,8
# return 0
li $v0,0
jr $ra
With input 1 2 3 4 -1, I'm getting output -4 -3 -2. I'm wondering where this could be improved to fix the output being incorrect.
Upvotes: 1
Views: 321
Reputation: 12455
The problem is that t0 isn’t preserved across the function call. Reload it from 0(a0) after restoring a0 after the function returns.
Upvotes: 2