【发布时间】:2021-11-23 12:34:41
【问题描述】:
我正在学习 MIPS,我正在尝试用 MIPS 表达用 C 语言编写的代码。
其中,在研究应该保留的寄存器时,我认为我只是通过考虑寄存器的类型来决定是否保留。
int leaf_example (int g, int h, int i , int j)
{
int f;
f = (g+h)-(i+j);
return f;
}
比如有上面的代码,有条件g~j是$a0~a3,f是$s0,返回值存放在@987654333 @。
此时因为有问题,f存储在$s中,$s需要保留,所以我明白了$s0的值是存储在栈上然后@ 987654338@后来恢复了。
void sort(int v[],int n)
{
int i, j;
for (i = 0 i < n; i++){
for (j = i - 1; j >= 0 && v[j] > v[j + 1]; j-=1){
swap(v, j);
}
}
}
但是,当有像上面这样的代码时,它在 MIPS 中表示如下:
为什么sort()函数的参数进来的两个值是分开存放的,在$s没有存放的时候再使用呢?我不知道如何确定应该保留哪些寄存器。
在上面的代码中,我想知道为什么需要保留$a0$a1。也就是说,如果您能告诉我如何区分代码中应该保留哪些值,我将不胜感激。
【问题讨论】:
-
如果您在通话后需要您的注册器参数(或其他一些值),请将它们保存在某个地方,这样您就不会丢失唯一的副本。请参阅What are callee and caller saved registers?(这是不方便的术语:呼叫保留与呼叫破坏更清晰)。在叶子函数中,如果您用完了调用破坏的寄存器(如
$t0..9),则仅使用调用保留寄存器(如$s0..regs),因此它选择$s0..7用于休假中的int f本地变量函数是一个糟糕(低效)的选择,迫使您保存/恢复调用者的$s0值。 -
这能回答你的问题吗? What are callee and caller saved registers? - 我认为我的回答确实涵盖了您所询问的所有内容。也相关:MIPS registers preservation
-
非常感谢,虽然我浪费了很多时间我还是没看懂,但是感谢你我解决了它
标签: assembly mips cpu-registers calling-convention