0

在 MIPS 中是否可以在执行期间更改标签的值,或者创建具有特定值的标签?

我问这个是因为在使用指令时,lw $a0, label($s0)我想在每次循环时增加标签 +4 的值,指示数组的新内存地址。我知道我可以做lw $a0, label+4($s0),但标签的新值不会被存储。

有什么建议吗?

4

2 回答 2

5

不可以。在 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。

编辑:您不能更改标签的值。它只是内存中某个位置的别名。在文本部分,它是以下指令位置的别名。在数据部分,它是内存中以下空间位置的别名。

于 2010-11-02T21:47:04.387 回答
0

我确实认为应该澄清答案并重新回答“是”。我认为“地址”和“价值”之间存在沟通不畅和混淆。

我目前有一个要导航以进行冒泡排序的数组。为了知道何时停止,我需要一个索引值来与持久的数组长度进行比较。

我创建了arrayLength标签,在这个答案上看到“否”后,我被困了 4 个小时,试图arrayLength在我记得 store word 之前用用户的值更改值sw

从技术上讲,是的,您无法更改数组的基地址,但您可以读取后面的下一个地址。

以下是获取数组长度以使用读取整数迭代数组的方法:

li $v0, 5
syscall

.data
.word
.assign 2
arrayLength: 0

.text
sw $v0, arrayLength
lw $t0, arrayLength

此时arrayLength, 由用户定义,取自$v0,放入arrayLength,然后存储在$t0fromarrayLength中,可用于比较以迭代数组。

换句话说,为了回答您的问题,0 in 的值arrayLength被覆盖(对于我们的示例,假设为 10)。所以是的,你可以整天覆盖标签。您不能做的是修改该标签的地址。

To my knowledge, once a label is created, it is assigned to an address and the following addresses are allocated depending on how you identify it (.byte, .half, .word, etc.). From there, unless there is some way to delete a label and re-create it, you cannot modify the address. That would cause a LOT of issues with memory management and be very inefficient and complex for no reason.


Now to continue. As a note, if you didn't know, you can predefine an array with .space [number]. I think each value is by default 32 bits, so 4 bytes (a word). So if you wanted, say 5 items(words), you would do 5 x 4, so .space 20 and you can store 5 words into the array.

In this case, we now assume array is already created and filled in from our arrayLength of 10 and we are printing the value at each index, as follows:

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

So address index ($t1) is the literal address location. Each index, i.e: word, is 4 bytes (32 bits) long. So our $t3 is an identifier to say (for example), "Hey, we are at index location 2 of 10," but in reality, we are in address location array + 8 out of array + 40.

You could probably chuck the index identifier and just make $t3 the value of arrayLength x 4 and do blt $t1, $t3, loop.

Hope this helps.

于 2018-03-09T07:47:49.227 回答