在递归函数中执行JAL之前,$ ra中存储的内容

问题描述 投票:0回答:1

enter image description here

在此函数的第一个迭代中,我们可以执行recur:并执行以下行:sw $ra, 0($sp),这是在任何jal语句之前完成的。据我了解,jal(跳转和链接)语句将输入到$ra寄存器中,即直接位于jal之后的位置。那么,如果$ra中还没有存储任何内容,示例中会发生什么?

function recursion assembly mips calling-convention
1个回答
2
投票

这是一个功能;在条目$ra上保留呼叫者希望您跳回的回信地址。

伴随$ a0 .. $ a3中的前4个整数args,这是调用方和被调用方之间的合同的一部分,这对于它们达成一致以使函数调用起作用是必需的。 calling Convention的这一部分当然是围绕MIPS jal指令设计的,因此每个函数的调用/返回都可以用一条指令完成。这就是$31具有符号名$ra =返回地址的原因。


寄存器不能保存“ nothing”,它始终是32位值。

如果某些代码将$ra设置为0或某个无效的地址,并使用j而不是jal跳转到此函数,则返回时它将崩溃,这将是调用者的错误。您的函数可以简单地假设$ra在函数入口上拥有有效的返回地址,无论是来自递归调用还是来自其他调用者。

(这是递归函数的要点,您实际上只是在对该函数进行函数调用,而从哪里调用都没有关系。)


请注意,程序中的顶级标签(例如,MARS模拟器中的标签)严格地是[[not函数。

[在MARS中,尽管事实上main保留有垃圾或$ra,但通常仍将其称为0,因此必须通过退出系统调用退出; jr $ra会崩溃。

((在C中,main是一个真正的函数,通常是从_start入口点到达的,该入口点在调用main之前进行了设置。在C中,main本身可以递归,没有任何特殊技巧。可以在真实的操作系统(而不是MARS模拟的玩具系统)下运行,通常可以使用_start:标签作为内核的真实入口点,或者您只需编写一个main并链接由C库提供的启动代码,该启动代码调用[ C0]。)

© www.soinside.com 2019 - 2024. All rights reserved.