mips - 访问数组的方法不同
mips - difference in methods for accessing arrays
我目前正在尝试学习 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
指令 assemble 变成 lw
指令。
如果距离更大——这很可能是你的情况,因为 array
和 lw
指令位于不同的部分——assembler 可能会将 lw
视为伪指令并将其转换为 2、3 或 4 条实际指令。有些 assemble 回复者可能不支持这一点,而是将其视为错误。
翻译的示例:
# 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)
我目前正在尝试学习 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
指令 assemble 变成 lw
指令。
如果距离更大——这很可能是你的情况,因为 array
和 lw
指令位于不同的部分——assembler 可能会将 lw
视为伪指令并将其转换为 2、3 或 4 条实际指令。有些 assemble 回复者可能不支持这一点,而是将其视为错误。
翻译的示例:
# 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)