[英]Difference in la and addi to copy a register in MIPS asm
I'm new to MIPS and confused by a concept.我是 MIPS 的新手,对一个概念感到困惑。
I have a value 5
stored in $s5
, and I want to copy it to $a0
so that I can use li $v0, 1
to print it.我有一个值
5
存储在$s5
中,我想将它复制到$a0
以便我可以使用li $v0, 1
来打印它。 I have two ways to copy.我有两种复制方式。
addi $a0, $s5, 0
la $a0, 0($s5)
Either 1. or 2. can print the value 5
if I do li $v0, 1
/ syscall
after it ( MARS's print-integer syscall ).如果我在它之后执行
li $v0, 1
/ syscall
( MARS 的 print-integer syscall ),1. 或 2. 都可以打印值5
。
But why does it work for 2.?但为什么它适用于 2.? 2. is storing the address of
$s5
at $a0
, but we need a value, not an address. 2. 将
$s5
的地址存储在$a0
,但我们需要一个值,而不是地址。
Will this be automatically handled by print_integer?这会由 print_integer 自动处理吗?
First of all, la
isn't a MIPS hardware instruction, just a pseudo-instruction implemented by the assembler, like li
.首先,
la
不是 MIPS 硬件指令,只是汇编器实现的伪指令,如li
。 (Usually with lui
/ addiu
to construct a 32-bit symbol address in a register, if you use it the normal way as la $reg, symbol
). (通常使用
lui
/ addiu
在寄存器中构造一个 32 位符号地址,如果您按照常规方式使用它,如la $reg, symbol
)。 Look at disassembly / machine code output, eg like MARS shows you when you assemble.查看反汇编/机器代码 output,例如 MARS 在您组装时向您显示。
You can abuse la
as a move
by using a register addressing mode instead of a symbol name.您可以通过使用寄存器寻址模式而不是符号名称来滥用
la
作为move
。 ( move
is another pseudo-instruction; MIPS doesn't have a hardware move, you just add with $zero
or an immediate 0
.) (
move
是另一个伪指令;MIPS 没有硬件移动,您只需添加$zero
或立即0
。)
That la
could assemble to exactly that addi $a0, $s5, 0
if the assembler chose that .如果汇编程序选择了那个
la
可以精确地组装到addi $a0, $s5, 0
。 (Although more likely it would pick addiu; with an immediate other than 0 is has to not trap on signed overflow. In general you never want add/addi, only addu/addiu.) (虽然它更有可能选择 addiu;立即数不是 0 必须不捕获有符号溢出。一般来说,你永远不需要 add/addi,只需要 addu/addiu。)
2 is storing the address of $s5 at $a0, but we need a value, not an address.
2 将 $s5 的地址存储在 $a0 中,但我们需要一个值,而不是地址。 Will this be automatically handled by print_integer?
这会由 print_integer 自动处理吗?
No, the value in $a0
is identical either way, just like if you did move $a0, $s5
like a normal person.不,无论哪种方式,
$a0
中的值都是相同的,就像您像正常人一样move $a0, $s5
一样。 So there's no difference in the end result for print_integer to sort out.所以 print_integer 整理出来的最终结果没有区别。
You can't take the address of a register.您不能获取寄存器的地址。 A register can hold a memory address, but you can't take the register's address.
寄存器可以保存memory 地址,但您不能获取寄存器的地址。
Yes la
"takes the address" of its source operand, but note that 0($s5)
isn't a register, it's the syntax for a memory addressing mode that refers to the memory at the address in $s5
, like you could use with lw
.是的,它的源操作数“获取地址”,但请注意
0($s5)
不是寄存器,它是la
寻址模式的语法,它指的是$s5
地址处的 memory ,就像你可以使用与lw
。 The address of that memory is just $s5
.该memory的地址只是
$s5
。
The C equivalent is int *a0 = &*s5;
C 等效项是
int *a0 = &*s5;
where the & cancels out the unary *
dereference.其中 & 取消一元
*
取消引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.