Home > OS >  Assembly return address $ra doesn't get back where it should
Assembly return address $ra doesn't get back where it should

Time:07-12

So i'm new to the assembly language and mips . Im trying to use a procedure (or function). I checked with debug the values are ok but the problem comes when the program should get out of the function and get back in the "main" .

This is the body of the main (plus the stored data) :

.data
N:.word 3
vet: .space 12
max: .word 0
msg:.asciiz "Inserisci elemento vettore ---> "
msg2: .asciiz "Il valore massimo è : "
.text

la $s0,vet
la $s1,N
lw $s1,0($s1)
la $s2,max

add $t0,$zero,$zero
FOR: 
    slt $t1,$t0,$s1
    beq $t1,$zero,ENDFOR
    
    sll $t2,$t0,2
    add $t2,$t2,$s0
    
     li $v0,4
     la $a0,msg
     syscall
     
     li $v0,5
     syscall
    
     sw $v0,0($t2) 
     addi $t0,$t0,1
     j FOR
    
ENDFOR :
    
     add $a0,$s0,$zero      #VALORE INDIRIZZO BASE SALVATO IN A0
     add $a1,$s1,$zero      #VALORE N SALVATO A1
    
     jal trovaMax
     

     sw $v0,0($s2)          
     
     li $v0,4
     la $a0,msg2
     syscall
     
     li $v0,1
     syscall
     
     li $v0,10
     syscall     

So after i call the function trovamax with jal it goes in the following function

trovaMax: 
    #PER PRIMA COSA ALLOCHIAMO LO SPAZIO PER LO STACK POINTER
    
     addi $sp,$sp,-8
     sw $s0,4($sp)
     sw $s1,0($sp)
     
     add $s0,$zero,$zero        #I=0
     add $s1,$zero,$zero        #max=0
     
     FOR2: 
     slt $t1,$s0,$a1
     beq $t1,$zero,ENDFOR
     
     sll $t2,$s0,2
     add $t2,$t2,$a0
     lw  $t3,0($t2)     
     slt $t1,$s1,$t3
     beq $t1,$zero,ENDIF
     add $s1,$t3,$zero
     ENDIF:
     addi $s0,$s0,1
     j FOR2
     ENDFOR2:
     #DOPO AVER SVILUPPATO IL CORPO DELLA FUNZIONE DOBBIAMO SALVARE IL VAL. RITORNO IN V0 COSI DA POTER RESTITUIRE QUESTO ALLA FUNZIONE CHIAMANTE
     
     add $v0,$s1,$zero
     #ripristino lo stato dello stack pointer 
     
     lw $s1,0($sp)
     lw $s0,4($sp)
     addi $sp,$sp,8
     jr $ra

So the problem comes after the procedure does what it is supposed to , after using jr $ra it is supposed to go back into the main (since ra saves the address of the calling function ?) here :

 sw $v0,0($s2)

Instead checking debug i can see it starts reading again

    add $a0,$s0,$zero
    add $a1,$s1,$zero
    jal trovaMax

And of course it calls again the function and all. So I wonder why it doesn't just go back returning the value.

CodePudding user response:

I don't think there's anything wrong with $ra.  However, you have a non-local goto in function trovaMax that jumps into main

 FOR2: 
 slt $t1,$s0,$a1
 beq $t1,$zero,ENDFOR
 

A non-local goto is a branch without call or return that goes from one function's code to another function's code.  (This control flow is impossible in most other languages, modulo exception handling.)

Pretty sure you wanted ENDFOR2 there.  You have the right idea, just need to be careful with label names.  (Some assemblers help with this by restricting the scope of label to a single function, but that is not this assembler.)

You should be able to observe this issue during single step debugging.  Maybe go a bit slower.

  • Related