la 和 addi 在 MIPS asm 中复制寄存器的区别
Difference in la and addi to copy a register in MIPS asm
我是 MIPS 的新手,对一个概念感到困惑。
我有一个值 5
存储在 $s5
中,我想将它复制到 $a0
以便我可以使用 li $v0, 1
打印它。我有两种复制方式。
addi $a0, $s5, 0
la $a0, 0($s5)
如果我在其后执行 li $v0, 1
/ syscall
(MARS's print-integer syscall).
,则 1. 或 2. 可以打印值 5
但为什么它适用于 2.? 2. 将 $s5
的地址存储在 $a0
,但我们需要一个值,而不是地址。
这会由 print_integer 自动处理吗?
首先,la
不是MIPS硬件指令,只是assembler实现的伪指令,如li
。 (通常用 lui
/ addiu
在寄存器中构造一个 32 位符号地址,如果你像 la $reg, symbol
一样正常使用它)。查看反汇编/机器代码输出,例如就像 MARS 在您 assemble.
时显示的那样
您可以将 la
滥用为 move
,方法是使用寄存器寻址模式而不是符号名称。 (move
是另一个伪指令;MIPS 没有硬件移动,您只需添加 $zero
或立即数 0
。)
如果 assembler 选择 ,la
可以 assemble 准确地达到 addi $a0, $s5, 0
。 (尽管它更有可能选择 addiu;除 0 以外的立即数必须不陷入有符号溢出。一般来说,你永远不需要 add/addi,只需要 addu/addiu。)
2 is storing the address of $s5 at $a0, but we need a value, not an address.
Will this be automatically handled by print_integer?
不,$a0
中的值无论哪种方式都是相同的,就像您像普通人一样 move $a0, $s5
一样。所以print_integer整理的最终结果没有区别。
你不能获取寄存器的地址。一个寄存器可以保存一个内存地址,但是你不能取寄存器的地址。
是其源操作数的la
"takes the address",但请注意0($s5)
不是寄存器,它是内存寻址模式的语法,它指的是内存$s5
中的地址,就像您可以使用 lw
一样。 内存的地址就是$s5
.
C 等价物是 int *a0 = &*s5;
,其中 & 取消了一元 *
取消引用。
我是 MIPS 的新手,对一个概念感到困惑。
我有一个值 5
存储在 $s5
中,我想将它复制到 $a0
以便我可以使用 li $v0, 1
打印它。我有两种复制方式。
addi $a0, $s5, 0
la $a0, 0($s5)
如果我在其后执行 li $v0, 1
/ syscall
(MARS's print-integer syscall).
5
但为什么它适用于 2.? 2. 将 $s5
的地址存储在 $a0
,但我们需要一个值,而不是地址。
这会由 print_integer 自动处理吗?
首先,la
不是MIPS硬件指令,只是assembler实现的伪指令,如li
。 (通常用 lui
/ addiu
在寄存器中构造一个 32 位符号地址,如果你像 la $reg, symbol
一样正常使用它)。查看反汇编/机器代码输出,例如就像 MARS 在您 assemble.
您可以将 la
滥用为 move
,方法是使用寄存器寻址模式而不是符号名称。 (move
是另一个伪指令;MIPS 没有硬件移动,您只需添加 $zero
或立即数 0
。)
如果 assembler 选择 ,la
可以 assemble 准确地达到 addi $a0, $s5, 0
。 (尽管它更有可能选择 addiu;除 0 以外的立即数必须不陷入有符号溢出。一般来说,你永远不需要 add/addi,只需要 addu/addiu。)
2 is storing the address of $s5 at $a0, but we need a value, not an address. Will this be automatically handled by print_integer?
不,$a0
中的值无论哪种方式都是相同的,就像您像普通人一样 move $a0, $s5
一样。所以print_integer整理的最终结果没有区别。
你不能获取寄存器的地址。一个寄存器可以保存一个内存地址,但是你不能取寄存器的地址。
是其源操作数的la
"takes the address",但请注意0($s5)
不是寄存器,它是内存寻址模式的语法,它指的是内存$s5
中的地址,就像您可以使用 lw
一样。 内存的地址就是$s5
.
C 等价物是 int *a0 = &*s5;
,其中 & 取消了一元 *
取消引用。