【问题标题】:Difference in la and addi to copy a register in MIPS asmla 和 addi 在 MIPS asm 中复制寄存器的区别
【发布时间】:2020-04-03 08:16:41
【问题描述】:

我是 MIPS 的新手,对一个概念感到困惑。

我有一个值5 存储在$s5 中,我想将它复制到$a0 以便我可以使用li $v0, 1 打印它。我有两种复制方式。

  1. addi $a0, $s5, 0
  2. la $a0, 0($s5)

如果我在其后执行li $v0, 1 / syscall (MARS's print-integer syscall),则 1. 或 2. 都可以打印值 5

但为什么它适用于 2.? 2.将$s5的地址存储在$a0,但我们需要一个值,而不是地址。

这会由 print_integer 自动处理吗?

【问题讨论】:

标签: assembly mips


【解决方案1】:

首先,la 不是 MIPS 硬件指令,只是汇编器实现的伪指令,如 li。 (通常用lui/addiu在寄存器中构造一个32位的符号地址,如果按正常方式使用la $reg, symbol)。查看反汇编/机器代码输出,例如就像火星在你组装时向你展示的那样。

您可以通过使用寄存器寻址模式而不是符号名称来滥用la 作为move。 (move 是另一个伪指令;MIPS 没有硬件移动,您只需添加 $zero 或立即添加 0。)

如果汇编器选择了,la 可以完全组装成addi $a0, $s5, 0。 (虽然它更有可能选择 addiu;立即数不是 0 时,必须不捕获有符号溢出。一般来说,您永远不需要 add/addi,只需要 addu/addiu。)

2 将 $s5 的地址存储在 $a0 中,但我们需要一个值,而不是地址。 这会由 print_integer 自动处理吗?

不,$a0 中的值无论哪种方式都是相同的,就像您像普通人一样使用move $a0, $s5。所以 print_integer 整理出来的最终结果没有区别。

您不能获取寄存器的地址。一个寄存器可以保存一个内存地址,但你不能获取寄存器的地址。

是的la“获取源操作数的地址”,但请注意0($s5)不是寄存器,它是内存寻址模式的语法,它引用$s5中地址处的内存,就像您可以与lw 一起使用。那个内存的地址就是$s5

C 等效项是 int *a0 = &*s5;,其中 & 取消一元 * 取消引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多