Favolas
Favolas

Reputation: 7243

assembly return address not working

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 mainfunction 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

Answers (2)

blackcompe
blackcompe

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

Matthew Slattery
Matthew Slattery

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 the jal func instruction, the main return address its substituted by the jal 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

Related Questions