assembly - 何时在 MIPS 汇编语言中使用临时寄存器和保存寄存器?

标签 assembly mips

在这个问题中:

x = x + y - 10 - A[20]

x - $s0
y - $s1
A - $s3

对于我的回答,我写道:

add   $t0,   $s0,   $s1    # value of x ($s0) + y ($s1) gets stored in temp $t0
addi  $t0,   $t0,  - 10    # subtracts value of $t0 from 10. $t0 now holds the new value
lw    $t1,   80($s3)       # loads value of A[20] into new temp $t1
sub   $s0,   $t0,  $t1     # subtracts values $t0 from $t1 and stores it in x 
                           ($s0)

但是模型解决方案说:

add   $s0,   $s0,   $s1   
addi  $s0,   $s0,  - 10    
lw    $t0,   80($s3)   
sub   $s0,   $s0,  $t0

我原来的答案正确吗?输出的结果不一样吗?如果我错了,请解释原因。

最佳答案

When to use temporary and saved registers in MIPS Assembly language?

Peter Cordes 答案的附录。

MIPS 汇编的常见调用约定要求您保留“已保存”寄存器中的值,并让您可以自由修改“临时”寄存器,这些寄存器在您从代码中调用子例程时生效。

由于临时寄存器可以由子例程自由修改,因此如果您需要该值,则必须在子例程调用周围保留/恢复它们,因此临时寄存器通常用于子例程调用之间,以获取可能具有有限生命周期的值.

“保存的”寄存器必须由您的代码保存,以免上面的调用者修改它们,即每当您使用另一个新的保存的寄存器时,您应该将其原始值放在某处(通常放入堆栈内存中),然后恢复返回给调用者之前。这会对性能产生较小的影响,因此您可能希望在代码中完全避免“保存”寄存器,除非您正在调用多个子例程,并且您将通过在保存的寄存器中拥有更长生命周期的值来获得性能,而不必保留/在每次调用时恢复它们(如果它们在临时寄存器中)。

根据经验法则:

  1. 根本不使用寄存器/值(通过更聪明的算法或代码结构消除,更好地重用已经受影响的寄存器)
  2. 对生命周期有限的值使用临时值,特别是在它不与子例程调用冲突的情况下
  3. 使用保存的寄存器来保存在子例程调用期间(尤其是多个子例程调用)期间必须保留的值

(这是“调用约定”定义的,即您可以定义+使用自己的约定,打破临时/保存的寄存器使用规则..这不是CPU内部设计的东西)

关于assembly - 何时在 MIPS 汇编语言中使用临时寄存器和保存寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50319673/

相关文章:

assembly - MIPS - 获取数组值

algorithm - MIPS 中二叉树中的最长路径

assembly - 在VirtualBox上运行操作系统

assembly - 如何使用 assembly(8086) 将 USB 驱动器的扇区加载到内存中?

assembly - MIPS堆栈帧(和 "addiu"指令混淆)

c - 将 C 代码转换为 MIPS 汇编代码

c - 在汇编程序中,为什么寄存器的使用在加法和减法之间有所不同?

macos - OS X Lion 上的 68k 汇编器

8086 中的汇编代码

assembly - 为什么我们在MIPS汇编语言中使用.globl main?