MIPS是否可以在执行期间更改标签的值,或创建具有特定值的标签?
我问这个是因为当使用指令lw $a0, label($s0)
时我想在每次循环时递增label +4的值,表示数组的新内存地址。我知道我可以lw $a0, label+4($s0)
,但不会存储标签的新值。
有什么建议吗?
答案 0 :(得分:4)
没有。在MIPS中,取消引用时,括号外必须有一个常量(不良措辞)。如果可以更改标签的值,那么它将不再是常量。为了解决这个问题,你可以做一些像
这样的事情la $t1, label #t1 holds address of label
add $t1, $t1, $s0 #t1 now holds address of label + s0 offset
lw $a0, 0($t1) #load word from t1's location
addi $t1, $t1, 4 #t1 was incremented by 4 bytes now
lw $a0, 0($t1) #load the next word
如果s0始终为非负数,则建议使用addu。
编辑:您无法更改标签的值。它只是内存中某个位置的别名。在文本部分中,它是以下指令位置的别名。在数据部分中,它是以下空间的内存位置的别名。
答案 1 :(得分:0)
我确实认为答案应该澄清并回复到"是"。我认为"地址"之间存在误传和混淆。和"价值"。
我目前有一个数组,我想导航进行冒泡排序。为了知道何时停止,我需要一个索引值来与持久的数组长度进行比较。
我创建了arrayLength
标签,在看到" no"关于这个答案,在我记得商店字arrayLength
之前,我被困4个小时试图用用户的值更改sw
的值。
从技术上讲,是的,您无法更改数组的基址,但您可以阅读下一个地址。
以下是使用读取整数来获取数组长度以迭代数组的方法:
li $v0, 5
syscall
.data
.word
.assign 2
arrayLength: 0
.text
sw $v0, arrayLength
lw $t0, arrayLength
此时,由用户定义的arrayLength
取自$v0
,放入arrayLength
,然后存储在$t0
的{{1}}中,并且可用于比较迭代数组。
换句话说,回答你的问题,arrayLength
中的0值被覆盖了(对于我们的例子,假设为10)。所以是的,你可以整天覆盖标签。你不能做的是修改那个标签的地址。
据我所知,创建标签后,会将其分配到某个地址,并根据您识别的方式分配以下地址(arrayLength
,.byte
,.half
,等等。)。从那里,除非有某种方法删除标签并重新创建它,否则无法修改地址。这将导致很多内存管理问题,并且无缘无故地效率非常低且复杂。
现在继续。请注意,如果您不知道,可以使用.word
预定义数组。我认为每个值默认为32位,所以4个字节(一个字)。所以,如果你想要,说5个项目(单词),你会做5 x 4,所以.space [number]
你可以在数组中存储5个单词。
在这种情况下,我们现在假设.space 20
已经创建并从我们的array
arrayLength
填写,我们将在每个索引处打印值,如下所示:
10
因此地址索引(add $t1, $zero, $zero #index value 0, our base address index
loop:
li $v0, 1
lw $a0, array($t1)
syscall
addi $t1, $t1, 4 #increase the address index by 4 (each index is 4 bytes long)
addi $t3, 1, $zero #increase the index identifier by 1
blt $t3, arrayLength, loop
#exit
)是文字地址位置。每个索引,即:字,长度为4个字节(32位)。所以我们的$ t3是一个标识符(例如),"嘿,我们在索引位置2的10,"但实际上,我们位于$t1
的地址位置array + 8
。
您可能会丢弃索引标识符,只需将$ t3设为array + 40
的值并执行arrayLength x 4
。
希望这有帮助。