我在 MIPS 教程中读到,只有寄存器 $s0-$s7 在过程调用中被保留。
但我认为(也许我错了?)创建有副作用的程序并不优雅 - 我认为程序应该只更改 $v0、$v1 寄存器和堆栈(如果需要的话)(我是对的吗?)。
所以我认为在我的程序中我只能使用 $t0-$t9 寄存器。
但是当我在程序中调用一些过程时,它可以更改 $t0-$t9 寄存器。所以我必须存储临时寄存器并在程序中的过程调用后恢复它。但是当我的程序如下所示时:
call procedure1
compute something on temporary reginsters
call procedure2
compute something on temporary reginsters
call procedure3
compute something on temporary reginsters
...
我的程序需要大量的内存访问。
所以我的想法是使用:
Store at the begining of my procedure reginsters $s0-$s7.
Use reginsters $s0-$s7 in my procedure.
Restore old values of reginsters $s0-$s7.
它优雅吗?有什么不好的后果吗?
我在 MIPS 教程中读到,只有寄存器 $s0-$s7 在过程调用中被保留。
没有什么神奇的事情发生$s0
-$s7
整个通话过程中(例如jal some_routine
只需将返回地址粘贴到$ra
并跳转到some_routine
;没有其他事情发生)。
在调用过程中保存这些寄存器只是一种约定:它是标准“应用程序二进制接口”(ABI) 的一部分,这是一组涵盖寄存器使用、堆栈使用、数据格式等的约定。 -- 不同的代码位符合相同 ABI 的应用程序(应用程序、库等)将能够相互操作。
如果您希望您的代码可以从其他地方调用,您的代码需要符合调用者期望的 ABI。例如如果您正在编写一些需要从 C 代码调用的汇编例程,则需要符合 C 编译器生成的代码所使用的 ABI。
对于通常的 MIPS ABI,这意味着调用例程的代码将假定它输入的任何值$s0
- $s7
在调用之前仍然会在调用返回之后,但它会not假设内容$t0
- $t9
还是一样。 (类似地,如果您的代码调用库例程(例如),它可以做出相同的假设:调用返回后,任何在$s0
- $s7
已被保留,但是$t0
- $t9
可能包含任何东西。)
这意味着您的代码必须保存以下任何内容$s0
- $s7
在更改它们之前,并在返回之前恢复它们。保存和恢复它们之间的作用并不重要——重要的是调用者看不到任何变化。
所以,是的,你的想法是正确的(实际上也是明智的做法)。
(请注意,您的子程序(procedure1
, prodcedure2
etc.) 不一定必须符合此标准 ABI,if它们仅从您的主过程中调用,并且不会调用外部例程 - 因为在这种情况下,它们只需要与您的主过程进行互操作,而不需要与任何其他代码进行互操作。但无论如何,遵循 ABI 都是一个好主意,除非有充分的理由不这样做;它使得更容易阅读代码,更容易在必要时使内部过程之一更加公开,更容易添加对其他代码的调用,等等)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)