【问题标题】:Using Nested For Loops and an Array in MIPS在 MIPS 中使用嵌套的 For 循环和数组
【发布时间】:2015-02-12 07:21:20
【问题描述】:

这是一个家庭作业,我自己编写了整个程序,在调试器中运行它,一切都按照我的意思进行,除了这一行:

sw $t1, counter($a3)

任务是把这个C代码的sn-p转换成MIPS

    for(i = 0; i < a; i++) {
       for(j = 0; j < b; j++) {
          C[2 * i] = i – j; } }

除了 $a3 之外,所有寄存器都按照它们在我的程序中应有的方式改变值 - 它永远不会改变。

变化:一个数组需要被寄存器声明和“指向”,而一个标签不能像我开始那样用于偏移量

编辑:这是完成的工作代码

【问题讨论】:

  • 你为什么期望 $a3 改变?它应该是你的数组的地址,因此它不应该改变。其实我不明白你的问题是什么。
  • @ElderBug 我尝试将 i - j 的结果存储在 $a3 的每个索引中,所以我不应该看到 $ 中出现一些值a3 寄存器值空间?我不确定如何更好地解释自己,我的火星编译器的屏幕截图会有所帮助吗?我可以告诉你我在看什么
  • 如果你有 x=8 的sw $t1, x($a3) 行,t1 的值将存储在 $a3[2](数组的第 3 个整数,由 $a3 指向)。如果不是这种情况,则永远不会执行该行。
  • 我不确定 MIPS 的语法,但声明它应该像 myarray: .space 40 10 个字。如果我没记错的话,你必须将地址加载到 $a3 中,使用la $a3, myarray
  • 其实这点你说的对,我忘了你后面用i-1。无论如何,你的循环仍然是错误的。尝试翻译while,这真的很简单。只需逐步翻译while 所做的事情。唯一不直接的一点是,当您需要“退出”条件时,条件是“继续”条件(但恰恰相反)。并且一次翻译一个循环,即使你有重复的标签也没关系。

标签: c arrays assembly mips


【解决方案1】:

回顾来自 cmets 的回答

您的 $a3 寄存器应该加载了在 .data 部分中定义的数组的地址。

您的代码的一个大问题是您如何构建循环。最好的方法是一步一步地翻译你的循环,一次一个循环。另外,请记住:

for( i = 0; i < a; i++ )
{
    loop_content;
}

相当于:

i = 0;
while( i < a )
{
    loop_content;
    i++;
}

在汇编中更容易翻译。该条件必须被否定,您是否需要“退出”条件,而不是while 循环中的“继续”条件。您的代码会更清晰、更容易理解(并且更不容易出错)。

您的“超出范围”错误来自这里:sw $t1, counter($a3)。这里counter 是一个标签,因此是一个地址。因此counter($a3) 正在执行“$a3 (=0x10010008) + 计数器地址 (=0x100100f8)”,得到 0x20020100,这显然不是您想要的(而且毫无意义)。

哦,在sw $r, offset($a) MIPS 指令中,offset 必须是 16 位常量。在这里,您使用的是 32 位地址,但只是汇编器将sw $t1, counter($a3) 转换为$x = $a3 + counter; sw $t1, 0($x),这就是为什么您可能会看到sw 的偏移量为0。

【讨论】:

  • 你就是那个人,这是有道理的,我对正在发生的事情有了更好的理解。稍后将发布经过修改、完善的代码以供参考,如果有什么我可以做的以使其更高效或“更清洁”,请告诉我。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 2020-03-25
  • 2021-10-23
  • 1970-01-01
  • 2021-12-11
相关资源
最近更新 更多