Nested routines 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 am using PCSpim. Why does it just stop working? What is my mistake?

+4
source share
3 answers

When you jump and link in func, you execute the func2 function, and the return address ($ ra) is set to the line immediately after the jump and link (PC + 4). Inside the func2 routine, you immediately return to the position stored at the return address (sll in func). After the change, you again try to go to the return address, which is sll in func, which leads to an infinite loop.

In other words, when you make consecutive subroutine calls, you need 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).

+4
source

After jal func , ra contains the address to which func should return. 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 save ra before all calls and restore it after all calls and before returning.

+3
source

You must save the return address

For instance:

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

All Articles