gpt4 book ai didi

assembly - 在 Assembly 的过程调用中将寄存器保存在堆栈上

转载 作者:行者123 更新时间:2023-12-02 01:01:24 24 4
gpt4 key购买 nike

我正在参加有关汇编的入门类(class),我遇到了以下代码。我不确定堆栈在这里是如何工作的。这是应该被翻译成汇编的 C 代码:(对不起,我忘了提到我们正在使用 MIPS)

int leaf_example (int g, h, i, j) {
int f;
f = (g + h) - (i + j);
return f;
}

在类里面,教授说正确的翻译应该是:(我在评论中添加了我的问题)

leaf_example:
addi $sp, $sp, -12 # Why do we need to allocate 3 bytes for each register?
sw $t1, 8($sp) # I don't really understand the meaning of this line and the next two lines
sw $t0, 4($sp)
sw $s0, 0($sp)
add $t0, $a0, $a1
add $t1, $a2, $a3
sub $s0, $t0, $t1
add $v0, $s0, $zero
lw $s0, 0($sp) # After we sw the registers on the stack, why do we need to load them back?
lw $t0, 4($sp)
lw $t1, 8($sp)
addi $sp, $sp, 12
jr $ra

我想我对 $s 寄存器和 $t 寄存器的区别有一个模糊的理解:当调用一个函数时, $s 寄存器的内容保持不变,但不能保证 $t 寄存器的内容保持不变。但是这个事实与将寄存器压入堆栈有什么关系呢?非常感谢您的帮助!

最佳答案

没有保证,只有约定。您可以编写一个破坏 $s 寄存器或做其他坏事的函数。惯例是preserve $s0-$s7, $gp, $sp and $fp .如果不这样做,很可能会导致调用链上游的某个功能以某种方式失败(如果已评分,则会扣分)。

因此,如果您要使用 $s 寄存器,则必须以某种方式备份它们,并在返回之前恢复它们。

这就是代码所做的,尽管在我看来称其为“ 正确的翻译”是一种误导。这是一种方式。但它也保留了 $t 寄存器,虽然它不是必须的。它还可以将 $s0 保存在 $t 寄存器中。它甚至可以首先不使用 $0,这更简单。它将结果放在 $s0 中只是为了立即将它移动到 $v0 无论如何,它可以直接把它放在那里然后一切都变得简单:

leaf_example:
add $t0, $a0, $a1
add $t1, $a2, $a3
sub $v0, $t0, $t1
jr $ra

没有更多的废话。

但也许目标是展示叶函数的一般工作原理。或者您可能必须严格遵守某些特定的转换规则,例如始终专门为局部变量分配一个寄存器,并且始终为 return x 语句生成到 $v0 的移动。

关于assembly - 在 Assembly 的过程调用中将寄存器保存在堆栈上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28178848/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com