以下是我在学校教授MIPS函数的方式。我只是被告知要“记住”“序幕”和“结语”,但从未解释过它的概念。这是:
首先,初始化堆栈指针$sp
。然后拨打jal f
:
li $sp, 0x7ffffffc
jal f # call function f
当在函数内部时,首先执行“序言”:
sub $sp, $sp, 8 # set new stack pointer
sw $ra, 8($sp) # save return address in stack
sw $fp, 4($sp) # save old frame pointer in stack
add $fp, $sp, 8 # set new frame pointer
返回时,请执行“结语”:
lw $ra, 8($sp) # load return address from stack
lw $fp, 4($sp) # restore old frame pointer from stack
add $sp, $sp, 8 # reset stack pointer
jr $ra # return to caller using saved return address
问题:
$ra
内存储的值从未改变(除非我的函数使用它,但我不应该首先使用$ra
)。序言只是将其保存在堆栈中,并在返回时将相同的值恢复为$ra
。 jr
正在对同样的事情采取行动,那么为什么首先将$ra
存储在必要的堆栈中呢?如果它从未改变过,为什么我需要恢复它?
将$fp
存储在堆栈中是有意义的,因为$fp
已更改。但是$ra
只是返回的地址。处理器是否通过堆栈查看$ra
内的值与堆栈中的值匹配?
答案 0 :(得分:0)
为什么首先将$ ra存储在必要的堆栈中?为什么呢 如果它从未改变过,我需要恢复吗?
在您的特定情况下,$ ra永远不会更改。但是如果函数调用另一个函数会发生什么?在这种情况下,$ ra确实会发生变化。事实上,你的函数序言缺少保存$ sX寄存器,这些寄存器也应该(基于MIPS ABI)被被调用者保存。
处理器是否正在查看堆栈以匹配内部值 $ ra与堆栈中的那些?
不,在MIPS中,处理器不了解什么" stack"是。堆栈是一个软件构造,硬件并不关心它。