【问题标题】:Initialising the index of an array in MIPS?在 MIPS 中初始化数组的索引?
【发布时间】:2014-02-19 01:50:46
【问题描述】:

我是 MIPS 的新手,我有一个家庭作业问题。

有人问我: 在开始循环之前,您应该初始化 $s0 来保存数组的基地址,并初始化 $s1 来保存数组的索引。索引应该从零开始,这意味着第十个元素的数组索引从零开始为 9。

老实说,我不知道这意味着什么。我想我已经初始化了基地址,但我根本不知道数组的索引是什么。这是我得到/已经处理过的代码:

.data  #by default, the "data segment" starts at address 0x10010000
.word 1
.word 2
.word 3
.word 4
.word 5
.word 6
.word 7
.word 8
.word 9
.word 0

.text #instructions start below

lui $s0,0x1001

我已经添加了底线,其余的都给了我。任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 第一个索引是0。当前元素总是$s0 + $s1 * 4
  • “我真的不知道这意味着什么。” 那么你应该咨询你的课程材料和/或老师。甚至不理解任务就继续进行是没有意义的。

标签: arrays memory mips


【解决方案1】:

好的,如果“我真的不知道这意味着什么”是一个准确的陈述,那么我们一次只说一个“这个”。

我是 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"

【讨论】:

  • 嘿。非常感谢您的评论。我确实了解我在提出问题时感到恐慌的所有基础知识。抱歉 :) 这就是我的代码现在的样子lui $s0,0x1001 addi $s1,$zero,1 loop: add $t1,$s0,$t2 lw $t0,0($t1) beq $t0,$zero,end addi $t0,$t0,2 sw $t0,0($t1) addi $s1,$s1,1 sll $t2,$s1,2 j loop 它只是永远循环,我不知道该怎么做才能修复它。非常感谢您的回答!真的很有帮助。
  • 这不能是你的全部代码——我假设你在某处定义了一个end 标签。我看到的另一件事是 $t2 未初始化。可能还有更多——这就是跳出来的。您是否单步执行了代码(可以在 MARS 中完成)?
猜你喜欢
  • 2011-11-24
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 2018-09-02
  • 2010-09-10
相关资源
最近更新 更多