【问题标题】:Assembly return address $ra doesn't get back where it should程序集返回地址 $ra 没有回到它应该返回的位置
【发布时间】:2022-07-12 00:12:26
【问题描述】:

所以我是汇编语言和 mips 的新手。我试图使用一个过程(或函数)。我用调试检查了值是好的,但是当程序应该退出函数并回到“main”时问题就来了。

这是主要的主体(加上存储的数据):

.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     

所以在我用 jal 调用函数 trovamax 后,它会进入以下函数

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

所以问题出现在程序完成它应该做的事情之后,在使用jr $ra 之后它应该回到主程序(因为 ra 保存了调用函数的地址?) 这里:

 sw $v0,0($s2)

而不是检查调试,我可以看到它再次开始读取

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

当然,它会再次调用函数和所有函数。 所以我想知道为什么它不只是返回返回值。

【问题讨论】:

    标签: assembly mips32


    【解决方案1】:

    我认为$ra 没有任何问题。但是,您在函数 trovaMax 中有一个非本地 goto 跳转到 main

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

    非本地 goto 是一个没有调用或返回的分支,它从一个函数的代码转到另一个函数的代码。 (这种控制流在大多数其他语言中是不可能的,模异常处理。)

    很确定你想要ENDFOR2。你有正确的想法,只需要小心标签名称。 (一些汇编器通过将标签的范围限制为单个函数来帮助解决这个问题,但这不是这个汇编器。)

    您应该能够在单步调试期间观察到此问题。可能会慢一点。

    【讨论】:

      猜你喜欢
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2022-11-03
      • 2022-11-13
      • 1970-01-01
      相关资源
      最近更新 更多