我目前正在尝试学习MIPS汇编语言,并且在使用数组时遇到了两种不同的方式,并且想知道两者之间的差异,如果有的话。
第一个方法
.data
array: .word 0, 1, 2, 3
.text
main:
li $t0, 0
lw $t1, array($t0) #t1 = array[0], t1 = 0
addi $t0, $t0, 4 #increment
lw $t2, array($t0) #t2 = array[1], t2 = 1
第二种方法
.data
array: .word 0, 1, 2, 3
.text
main:
la $t0, array
lw $t1, ($t0) #t1 = 0
addi $t0, t0, 4 #increment
lw $t2, ($t0) #t2 = 1
那有什么区别呢?
一个区别是,根据array
相对于lw
指令在内存中的位置,lw
可能是一个伪指令,被翻译成多个实际指令。
lw
指令(lw rt, offset(base)
)的编码为:
-------------------------------
| 100011 | base | rt | offset |
-------------------------------
偏移量部分是16位,将被符号扩展到32位,所以它的范围是-32768..+32767。这是array
和lw
指令之间的最大可能距离,并且仍然可以将lw
指令组装成lw
指令。
如果距离更大——在您的情况下很可能是这样,因为array
和lw
指令位于不同的部分——汇编程序可能会将lw
视为伪指令,并将其转换为2、3或4条实际指令。有些汇编程序可能不支持此操作,而只是将其视为错误。
一个翻译的例子:
# array located at 0x10010000
# lw $t1,array($t0) located at 0x00400018
lui $at,0x1001 # $at = 0x10010000
addu $at,$at,$t0 # $at = 0x10010000 + $t0
lw $t1,($t0)