【问题标题】:Mips assembly, "function calls" and storing return addresses onto the stackMips 汇编、“函数调用”并将返回地址存储到堆栈中
【发布时间】:2013-12-06 21:41:45
【问题描述】:

对于了解这一点的人来说,这是一个快速的问题。但我的问题是我有一个任务,要使用各种方法的选择排序,我正在尝试弄清楚如何使用堆栈来保存返回地址。我的问题是我可以让它一直到最后一个加载返回地址代码块,但是我在数据/堆栈读取中得到了一个错误的地址,有人可以指出我在保存到哪里可能搞砸了堆栈?非常感谢!

main:
 sub $sp, $sp, 4
 sw $ra, ($sp)
 jal sort

 j exit

swap:
 sub $sp, $sp, 8
 sw $fp, 4($sp)
 add $fp, $sp, 4
 sw $ra, ($fp)

 lw $ra, ($fp)
 jr $ra

min:
 sub $sp, $sp, 8
 sw $fp, 4($sp)
 add $fp, $sp, 4
 sw $ra, ($fp)

 lw $ra, ($fp)
 jr $ra

sort:
 sub $sp, $sp, 8
 sw $fp, 4($sp)
 add $fp, $sp, 4
 sw $ra, ($fp)

 jal min

 jal swap

 lw $ra, ($fp)        <---- Bad address in data/stack read Exception
 lw $fp, 4($fp)
 jr $ra

exit:

 li $v0, 10                 #exit
 syscall

【问题讨论】:

    标签: function sorting assembly return mips


    【解决方案1】:

    一般惯例是在堆栈中存储任何可以被覆盖的寄存器。因此,如果在排序过程中要保存$ra,则需要在堆栈上保留 1 个字。在从程序返回之前完成所有计算后,您需要恢复 $ra 和堆栈指针:

    sort:
       addi $sp, $sp, -4
       sw $ra, 0($sp)   # saves $ra on stack
    
       # do calculations
    sort_end:
       lw $ra, 0($sp)
       addi $sp, $sp, 4
       jr $ra
    

    【讨论】:

      【解决方案2】:

      还有使用帧指针的理由吗? 您正在以一种非常复杂的方式使用堆栈。

      swap:
       sub $sp, $sp, 8 ; room for 2 words
       sw $fp, 4($sp)  ; store sp in the first
       add $fp, $sp, 4 ; fp = sp + 4 ? Why?
       sw $ra, ($fp)  ; store return address
      
       lw $ra, ($fp)  ; get return address - leave the fp and sp alone
       jr $ra         ; return, and leave the sp and fp unbalanced
      

      现在,您应该在调用者或被调用者中处理堆栈帧以保持清晰。 制作一个新框架,并在子例程完成后将其删除。

      在排序中,您调用 min 和 swap,然后两者都更改 sp 和 fp 而不恢复它们。

      This 可能会有所启发...

      [编辑]

      如果你坚持使用框架:

      push ra
      push fp
      fp = sp
      { push local variables }
      
      do the deed
      
      sp = fp
      pop fp
      pop ra
      ret
      

      这样你就有了 fp 链,如果你的堆栈损坏了,你仍然可以返回 美好的。不需要push sp,因为sp存储在fp中。

      【讨论】:

      • 感谢您的 awnser,我只是对如何使用堆栈以及何时何地存储东西感到非常困惑。所以当我这样做时(添加 $fp, $sp, 4),我什至需要这样做吗?
      • 除非需要遍历调用树,否则不需要栈帧。
      猜你喜欢
      • 2017-02-24
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多