简体   繁体   English

la 和 addi 在 MIPS asm 中复制寄存器的区别

[英]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.我有两种复制方式。

  1. addi $a0, $s5, 0
  2. 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 / syscallMARS 的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM