MIPS组装 - 标签值修改

时间:2010-11-02 21:41:14

标签: assembly label mips post-increment

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

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

有什么建议吗?

2 个答案:

答案 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

希望这有帮助。