ABCD
ABCD

Reputation:

Nested subroutine calls on MIPS

.data

.text
    .globl __start
    __start:

main:
    jal func
    sll $0,$0,0
    j end

func:
   jal func2
   sll $0,$0,0  
   jr $ra
   sll $0,$0,0

func2:
    jr $ra
    sll $0,$0,0

end

I'm using PCSpim. Why it just stops working? What is my error here?

Upvotes: 5

Views: 7731

Answers (3)

sr.WhiteSkull
sr.WhiteSkull

Reputation: 21

You must save the return address

For example:

 main:
 ...
 jal func1
 ...

 func1:
    sw $ra, ($sp) # save address   
    ...
    jal func2
    ...
    lw $ra, ($sp) # load
    jr $ra

 func2:
    ....

Upvotes: 1

Phyllostachys
Phyllostachys

Reputation: 161

When you do the jump and link in func then you are executing the func2 function and the return address ($ra) is set to the line right after the jump and link (PC+4). Inside the func2 subroutine, you are immediately returning to the position saved in the return address (the sll in func). After the shift you are trying to jump to the return address again which is the sll in func which results in a infinite loop.

In other words, when you do successive subroutine calls, you have to save and restore the return address before and after the subroutine call, respectively.

foo:
    #do some functiony stuff
    mov    $s0, $ra    #save return address into s0
    jal    bar         #do the bar subroutine
    mov    $ra, $s0    #restore return address that was saved into s0
    jr     $ra         #jump there

bar:
    #do some more functiony stuff
    jr     $ra

You also need to make sure your 'end' is marked as a label (add a colon after it).

Upvotes: 5

Alexey Frunze
Alexey Frunze

Reputation: 62048

After jal func, ra contains the address that func must return to. jal func2 overwrites ra. func2 then returns to func1 and func1 returns to the same address, looping forever.

If a function calls another function, it must preserve ra before all calls and restore it after all calls and before returning.

Upvotes: 3

Related Questions