首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在MIPS 32中的for-循环中使用set < (SLT)语句?

如何在MIPS 32中的for-循环中使用set < (SLT)语句?
EN

Stack Overflow用户
提问于 2021-09-26 21:47:43
回答 1查看 667关注 0票数 0

我正在做一些家庭作业,我的问题是,我应该包括SLT (如果小于)线在这个for-循环程序集中,但我不知道如何做。我发现this question很有用,但我不能使用BLT (分支如果小于)语句,教授确实引入了宏,但这个问题指定使用SLT。最后,我只是在我的作业语句中使用了它,但我觉得这几乎不能满足教授的要求,下面是这样的语句:slt $t2, $t0, $t1 #t2 holds y = 1 if i < x。它根本不符合代码,它没有一个目的,我觉得它应该涉及到for-循环,有什么建议吗?

下面是程序集表示的基本for-循环:

代码语言:javascript
复制
for (i=0; i<x; i++) 
   y = y * 2; 

以下是MIPS 32中的汇编代码:

代码语言:javascript
复制
.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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-26 22:20:41

您说得对,slt并不是用于循环控制,因为它不涉及循环。

条件i<x是循环迭代过程中的一个动态条件,因为i会改变每个迭代。

如果单步调试,您可能已经注意到了这个缺陷。

但有一个问题是,您没有使用很好的伪代码,因为y从来没有初始化过。我们仍然可以使用这个方法,但是请注意,您已经选择以某种方式初始化y,而这并不是给定伪代码的一部分。

您用汇编语言编写的代码具有等效的伪代码:

代码语言:javascript
复制
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与原始代码不同。这个伪代码在逻辑上不是等价的,并且不会运行与原始代码相同的代码。

让我们从更基本的原则和逻辑转换入手,这样您就可以看到其中的一些问题:

代码语言:javascript
复制
for (i=0; i<x; i++) 
   y = y * 2; 

我们首先将这个for-循环转换为等效的while -循环,因为while循环更显式:

代码语言:javascript
复制
i = 0;
while ( i < x ) {
    y = y * 2;
    i++;
}

接下来,我们将这个while-循环转换为汇编语言的if-goto标签样式,因为这是更明确的,并且每一个这样的步骤都使我们更接近汇编语言。您将真正开始看到循环中的是什么,什么不是,即使这仍然是伪代码(fyi,这个if-goto-标签在C中是允许的)。

代码语言:javascript
复制
    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,因为这样一个分支保存了来自slti<x的结果,为了测试这个布尔值是否为假,我们将使用beq $t10 $0 loop1Done,如果$t10等于false ($0总是假的),那么执行退出循环的goto/分支。

留给读者的练习是完成从if-goto标签伪/C代码到汇编代码的逻辑转换。

另外,从上面的讨论中还可以注意到,您的原始伪代码并不是独立的:y的初始化是必要的,因此为了实际运行这个MIPS转换代码,您必须添加这样的初始化(如果y的寄存器恰好是0,因为模拟器会初始化它,那么循环将是最没有意义的,因为y=0*2将不会做什么不同的重复操作)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69339211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档