Reputation: 7243
I have this function in C:
int func(int n0, int n){
if (n > 1){
int nFinal = func(n0, --n);
return (nFinal*nFinal) + n0;
}
return n0;
}
And want to to program it in Assembly. I have this code:
.data
.text
.globl func
func:
addi $29,$29, -4
sw $ra,0($29)
move $8,$4
move $9,$5
ble $9,1,fim
sub $9,$9,1
move $5,$9
jal func
move $4,$11
jal quadrado
add $11,$2,$8
j fim
quadrado:
mul $2,$4,$4
jr $31
fim:
lw $31,0($29)
move $2,$11
jr $31
If the parameters passed in $4 and $5 are 2 and 1 respectively, I can see that wen the program reaches the ble
instruction it works as expected. It jumps to the fim
label, restoring the return address from the stack and passing the return value to my main
function.
The problem is that value on parameter $5 is undefined. It can be any given value. And I believe the problem with my program it's that the return address from my main
function is lost and program can't return to it. I believe that wen program reaches the jal func
instruction, the main
return address its substituted by the jal func
instruction return address.
How can I solve this problem? (Not asking code but just some directions)
Upvotes: 0
Views: 1910
Reputation: 3190
Commenting your code would help tremendously. Your use of temporary registers probably complicated things even more. You only need to use one temporary register. Here's a little help with the func
routine. I assume you can complete the rest. And do remember to move the stack pointer when popping a return address.
func:
#push rtn. addr. onto stk
sw $ra, 0($sp)
subi $sp, $sp, 4
#result = arg0
move $t0, $a0
#if arg1 <= 1 return arg0
ble $a1, 1, rtn
#call func(arg0, arg1-1)
subi $a1, $a1, 1
jal func
#result = func(arg0, arg1-1)^2 + arg0
mul $t0, $v0, $v0
add $t0, $t0, $a0
rtn:
Upvotes: 1
Reputation: 46998
[...] And I believe the problem with my program it's that the return address from my
main
function is lost and program can't return to it. I believe that wen program reaches thejal func
instruction, themain
return address its substituted by thejal func
instruction return address.
Pretty much. You're decrementing the stack pointer ($29
/ $sp
) at the start of your function to create space to save the return address ($31
/ $ra
), but after reloading the return address at the end, you're missing the corresponding increment of the stack pointer -- you're looking at the value, but not actually popping it from the stack.
Upvotes: 1