gpt4 book ai didi

汇编(MIPS)正确使用: Registers vs.堆栈

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

在编写 MIPS 程序时,我听说保持寄存器干净通常是一种好的做法,即在程序结束时将寄存器的值清除为 0。所以我的第一个问题是如何/为什么这是必要的/良好的做法?

其次,如果我们有一个函数调用,参数(p1,p2)存储在$4和$5中;在函数定义结束时,是否有必要清除 $4 和 $5 处的值,或者更好地将它们保留为函数调用开始时的状态?

我还看到过将参数推送到堆栈的示例,如下所示:

addi $29, $29, -8
sw $4, 0($29)
sw $5, 4($29)
; At the end of our program:
addi $29, $29, 8

何时以及为何需要这种必要/好的做法?

最后,如果我们要在程序中使用一些常量,例如 4 和 1,那么将它们保存在寄存器中还是堆栈中更好?例如:

lis $8
.word 4
lis $9
.word 1

然后我们可能会以某种方式在我们的程序中使用这些值,然后将它们清除为 0。

或者我们可以选择通过前后移动堆栈指针将它们存储在堆栈上。哪种方法更好?

最佳答案

首先,you usually want to use $zero 代替 $0$v0–$v1 代替 $2–$3 等等...比普通数字更容易理解(和内存),汇编器也理解这种表示法,所以这一面没有问题。此外,这还会从数字中抽象出您的代码,因此,如果标准发生变化(例如,$zero 不再是 $0,而是 $256),您的代码仍将被正确汇编。

在每个 CPU 架构中,对于如何使用寄存器进行调用以及如何在函数中使用寄存器,都有一些约定。这称为调用约定。您可以看到here MIPS 调用约定的简要说明。

I've heard that its generally good practice to keep the registers clean i.e. to clear the values of the registers to 0 at the end of the program. So my first question is how/why is this necessary/good practice?

我个人从未听说过这种做法,但我不太同意。更好的做法是在程序启动之前恢复以前的值。

Secondly, If we have a function call with parameters(p1, p2) stored in $4 and $5; at the end of our function definition, is it necessary to clear the values at $4 and $5 or better to leave them as they were at the beginning of the function call?

您应该将它们保留在函数调用开始时的位置。对于调用者来说,修改这个寄存器是没有意义的。

堆栈上的空间为 $a0-$a3 保留,以防被调用者需要保存其参数,但调用者不会将寄存器存储在那里。

I've also seen examples of pushing parameters to the stack like this. When and why is this necessary/good practice?

根据定义,堆栈是一个临时存储。如果您想备份寄存器值(例如您想使用 $aX 或 $sX),则将它们放在那里。与之前相同:

堆栈上的空间为 $a0-$a3 保留,以防被调用者需要保存其参数

addi $sp, $sp, -8

移动堆栈指针寄存器(按照惯例它是$29)。这在堆栈中保留了 8 个字节。

sw $a0, 0($sp)
sw $a1, 4($sp)

将 $a0 保存到堆栈顶部,并将 $a1 作为堆栈中的第二个(请记住,堆栈向较低地址增长)。这将填充保留空间(8 字节)。这称为函数入口协议(protocol)

; At the end of our program:
; You forgot, and it's important:
lw $a0, 0($sp)
lw $a1, 4($sp)
addi $sp, $sp, 8

您恢复保存的寄存器并将堆栈指针放回原始值。然后调用者的堆栈和参数将保持不变。这称为函数退出协议(protocol)

If we are to use some constants in our program, say 4 and 1, is it better to keep them on the registers or the stack?

都不是。常量应用作立即操作数:

li $t0, C   ; Load 16-bit constant into $t0
lui $t0, C ; Load upper 16-bit half-word of $t0

关于汇编(MIPS)正确使用: Registers vs.堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15169498/

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