好的,如果“我真的不知道这意味着什么”是一个准确的陈述,那么我们一次只说一个“这个”。
我是 MIPS 的新手,我有一个作业问题。
这意味着,您正在考虑依靠 Stack Overflow 来完成作业。也许它会,也许它不会,但它不会在考试中出现。 :)
在开始你的循环之前,你应该初始化 $s0 来保存数组的基地址
你知道“初始化变量”是什么意思吗?如果没有,您需要回到“编程入门”。假设这不是问题,我们要定义“在寄存器中设置值”和“数组地址”。
您的指令确实设置了寄存器的所有 32 位,并且您似乎已经收集到它清除了低 16 位,给您 0x10010000:
lui $s0,0x1001
但这是一个非常糟糕的主意。您不希望您的代码被锁定在特定的内存位置。不同的汇编程序可能会将您置于不同的内存段中,或者(更有可能)您可能希望将该内存块(我们称之为“数组”,即使这没有意义)移动到不同的位置。相反,你应该让汇编器为你做一些工作,使用标签和伪操作。
.data # I don't know or care where the data segment starts
myArray:
.word 0x00000001 # aka 0x01 or just 1, but this shows what's really happening
.word 0x00000002
# etc etc
.text # Instructions do indeed start below
la $s0 myArray # magic pseudo-op
汇编器会将la(加载地址)伪操作转换为lui,地址的上半部分为高位,然后ori,地址的下半部分为低位。当你这样做时,这些代码仍然可以工作:
.data
somethingElse:
.word 0xDEADBEEF # I want anyone decompiling my code to see "DEAD BEEF" at the top of the dump
myArray:
.word 0x00000001
.word 0x00000002
# etc etc
.text # Instructions do indeed start below
la $s0 myArray # I still have a pointer to the first word in myArray!
好的,现在让我们来看看你不知道的下一件事:
$s1 保存数组的索引。索引应该从零开始,这意味着第十个元素的数组索引从零开始为 9...我根本不知道数组的索引是什么。
同样,如果您不知道 A[0] 到 A[9] 在高级语言中的含义,请询问您的顾问您是如何在没有适当先决条件的情况下进入这门课程的。我假设你已经记下了那部分......因为你要做的第一件事就是完全忘记它。
MIPS 没有数组。它只是具有内存位置,可以是您决定的任何位置。如果我将地址 myArray 发送到一个需要 ASCII 字符字符串的函数,它将读取内存位置,就好像它们包含 ASCII 字符一样。没有类型(只有 Zuul)。你要做的就是“指针运算”。
正如@Konrad 所指出的,“数组”(您打算将其视为一系列单词的一堆内存位置)中的第一个单词(您打算将其视为整数的四个字节)位于内存地址 @987654330 @(可能但不明确位于 0x10010000)。因此,如果您想获取存储在第一个“数组元素”中的值,您可以执行以下操作:
lw $t0, 0($s0) # load word into $t0, from address pointed to by $s0, offset by 0
然后,您可以像这样得到下一个单词,它将获取内存地址$s0+4 中的数据。 (为什么是 +4?因为每个字都是 4 个字节长。)
lw $t0, 4($s0) # load word into $t0, from address pointed to by $s0, offset by 4
嗯,这对于访问随机数组元素不是很有帮助。在 MIPS 中,不能只用数组索引 $s1 替换 4。您必须自己进行添加。但不是这样的!
add $t1, $s0, $s1 # Base address + oops!
如果 $s1 = 1,那会给你$s0+1,这不是你想要的。你需要$s0+(4*$s1)。本着不为你做所有你的作业的精神,我将向你抛出一个你可能不知道的操作码,并强迫你参考谷歌的精神来找出为什么这样做。
sll $t2, $s1, 2 # Look it up!
add $t1, $s0, $s1 # address of "array element"
lw $t0, 0($t1) # value of "array element"