指令不正确的MIPS分配



作业的呐喊CS一年级学生,教授根本不在教学。有人能帮我开始下面的作业吗?

您的第一项任务是编写MIPS汇编语言程序它在spim上运行,并打印一个正方形和立方体的表格。你的程序将提示用户输入表中的最大值。如果用户输入值5,然后您的程序将打印表格:(有正方形和立方体数字的表格(。

程序的控制流应该遵循代码片段:

for(i = 1; i <= max; i++)
printf("%dt%dn", i, i*i, i*i*i);

非常感谢您的帮助。

首先,也是最重要的一点,获得可工作的C代码。将损坏的C代码进行汇编是徒劳和令人沮丧的。

你所拥有的就是:

  • printf只打印两个项目,但在格式字符串之外有三个项目,所以这是不匹配的
  • 代码段中没有ii变量
  • 使用C代码意味着可以编译&测试运行(许多在线C编译器/调试器(——并且C编译器将只接受完整的声明,在这里,这将是具有任何所需变量或参数声明的整个函数,而不仅仅是具有假定变量声明的一行代码片段

一旦您有了可工作的C代码,就可以分解结构,同时保留在C编程语言中。

for ( i = 1; i <= max; i++ ) 
printf ( "%dt%dn", i, i*i );

因此,我们几乎可以在任何地方开始分解——但让我们从顶部开始,使用for循环。

for循环可以转换为while循环,这更简单,当然,这会导致扩展几行:

i = 1;
while ( i <= max ) {
printf ( "%dt%dn", i, i*i );
i++;
}

while构造比for更简单,因为初始化器和增量在该分解中是显式分离的。

接下来,将while循环转换为程序集的if-gto-label样式。这种机械模式转换需要引入标签。

i = 1;
loop1:
if ( i > max ) goto loop1Exit;
printf ( "%dt%dn", i, i*i );
i++;
goto loop1;
loop1Exit:

上面是if-goto标签形式,它恰好也是有效的C代码。尽管现在仍然使用C语言,但我们有更简单的控制流代码行,而且这些代码可以很容易地转换为汇编。

然而,接下来的工作是printf。它打印了多少东西?首先是一个整数,然后是一个制表符,然后是另一个整数和一个换行符。因此,将printf分解为这些。

i = 1;
loop1:
if ( i > max ) goto loop1Exit;
// printf ( "%dt%dn", i, i*i );
printf ( "%d", i );
printf ( "t" );
int temp = i*i;
printf ( "%d", temp );
printf ( "n" );
i++;
goto loop1;
loop1Exit:

这4个简化的printfs中的每一个都可以用spim上的一个syscall来完成。

有了它简单的代码行,上面的分解,仍然是C代码,已经准备好翻译成汇编了!


从分解但有效的C代码开始,转换变量:为imax选择物理存储位置——CPU寄存器是合适的,只需避免$a0$v0,因为syscalls需要它们,这样的使用会擦除存储在那里的任何变量。

之后,大多数每一行都将作为单个指令转换为MIPS(简单的syscalls通常需要大约3行(。

这种方法是从C代码到简化/分解的C,再到汇编代码的简单、逻辑但相当机械的转换。在C语言中分解代码具有一些可读性、可测试性和指导性优势。(顺便说一句,这种分解会导致同样简单的代码以任何顺序进行。(

希望您能看到这些小步骤,每个步骤都是应用众所周知的模式转换的逻辑进展,它们一起完成了分解。这有点像数学或证明中的工作问题,在每一步我们都可以应用一些已知的规则,通过一步接一步的组合,我们到达了想要的地方。

最新更新