我正在做一些家庭作业,我的问题是,我应该包括SLT (如果小于)线在这个for-循环程序集中,但我不知道如何做。我发现this question很有用,但我不能使用BLT (分支如果小于)语句,教授确实引入了宏,但这个问题指定使用SLT。最后,我只是在我的作业语句中使用了它,但我觉得这几乎不能满足教授的要求,下面是这样的语句:slt $t2, $t0, $t1 #t2 holds y = 1 if i < x。它根本不符合代码,它没有一个目的,我觉得它应该涉及到for-循环,有什么建议吗?
下面是程序集表示的基本for-循环:
for (i=0; i<x; i++)
y = y * 2; 以下是MIPS 32中的汇编代码:
.text
.globl main
main:
li $t1, 7 #test val num of iterations, x = 7
li $t0, 0 #t0 is our counter i = 0
#li $t2, 1 #another way to assign y = 1
slt $t2, $t0, $t1 #t2 holds y = 1 if i < x
loop:
beq $t0, $t1, end #if (i)t0 == (x)7 end loop
add $t2, $t2, $t2 #body, y = y * 2
addi $t0, $t0, 1 #add 1 to i, t0
j loop #jump back to the top
end:
li $v0, 10
syscall发布于 2021-09-26 22:20:41
您说得对,slt并不是用于循环控制,因为它不涉及循环。
条件i<x是循环迭代过程中的一个动态条件,因为i会改变每个迭代。
如果单步调试,您可能已经注意到了这个缺陷。
但有一个问题是,您没有使用很好的伪代码,因为y从来没有初始化过。我们仍然可以使用这个方法,但是请注意,您已经选择以某种方式初始化y,而这并不是给定伪代码的一部分。
您用汇编语言编写的代码具有等效的伪代码:
y = i < x; // bad: outside the loop and modifying y
for (i=0; i!=x; i++) // bad: using condition i!=x
y = y + y; // good: valid for y = y * 2;您能看到这个伪代码与原始代码不一样的几种方式吗?将y初始化为非原始代码,并且循环退出条件,i!=x与原始代码不同。这个伪代码在逻辑上不是等价的,并且不会运行与原始代码相同的代码。
让我们从更基本的原则和逻辑转换入手,这样您就可以看到其中的一些问题:
for (i=0; i<x; i++)
y = y * 2; 我们首先将这个for-循环转换为等效的while -循环,因为while循环更显式:
i = 0;
while ( i < x ) {
y = y * 2;
i++;
}接下来,我们将这个while-循环转换为汇编语言的if-goto标签样式,因为这是更明确的,并且每一个这样的步骤都使我们更接近汇编语言。您将真正开始看到循环中的是什么,什么不是,即使这仍然是伪代码(fyi,这个if-goto-标签在C中是允许的)。
i = 0;
loop1:
if ( ! (i < x) ) goto loop1Done; // Exit loop when i < x is false
y = y * 2;
i++;
goto loop1;
loop1Done:首先要注意的是,在汇编语言的if-goto标记风格中,如果我们想让程序做其他事情,我们使用if -goto。希望您可以看到,由于if-goto的语义,自然操作是告诉处理器什么时候退出循环--而不是像在C中那样在循环中停留--从而否定条件(MIPS可以通过多种方式处理)。
接下来,我们可以清楚地看到,关系操作i < x (及其否定)在循环中是必需的,因此必须在循环的每次迭代中重复。
操作if ( ! (i < x) ) goto ...是合法的C代码,但可以在伪代码中更多地重声明为:if ( i < x is false ) goto ...。
slt可以像您在$t0中用操作数描述的那样使用,在$t1中可以使用x,所以这个部分很好,但是结果需要转到一个新的临时寄存器中,而不是关闭原始值y (在原始伪代码中没有指定). --让我们想象使用$t10作为这个替代临时的。所以,slt $t10, $t0, $t1,并注意它在循环中的位置。
现在要测试条件测试的条件分支部分。我们要测试i<x比较的结果是假的,如果是这样的话,分支要退出循环。这样的分支需要测试$t10,因为这样一个分支保存了来自slt的i<x的结果,为了测试这个布尔值是否为假,我们将使用beq $t10 $0 loop1Done,如果$t10等于false ($0总是假的),那么执行退出循环的goto/分支。
留给读者的练习是完成从if-goto标签伪/C代码到汇编代码的逻辑转换。
另外,从上面的讨论中还可以注意到,您的原始伪代码并不是独立的:y的初始化是必要的,因此为了实际运行这个MIPS转换代码,您必须添加这样的初始化(如果y的寄存器恰好是0,因为模拟器会初始化它,那么循环将是最没有意义的,因为y=0*2将不会做什么不同的重复操作)。
https://stackoverflow.com/questions/69339211
复制相似问题