首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lc3汇编语言嵌套循环

lc3汇编语言嵌套循环
EN

Stack Overflow用户
提问于 2021-10-14 02:01:38
回答 1查看 95关注 0票数 0

我正在尝试使用lc3汇编语言中的嵌套循环打印一块x,例如一个3x4矩形,但在将逻辑从简单的python嵌套循环转换为lc3汇编语言时遇到了麻烦。我是第一次接触这门语言。

例如,这里的伪代码,我想使用严格嵌套的循环在lc3汇编中创建相同的输出。我浏览了网页,并亲自尝试了一下,但我能找到的唯一类似的程序是一个“hello world”单循环。

下面是(类似Python的)伪代码:

代码语言:javascript
复制
x = 'x'
width = 3
length = 4
for i in range(length):
    for j in range(width):
        print(x, end='')
    print()

#output is 
# xxx
# xxx
# xxx
# xxx

非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2021-10-14 15:30:24

结构化语句允许简单的嵌套。例如,for循环可以有一个if-then-else作为主体,或者在你的例子中是一个嵌套循环。

汇编语言遵循if-goto-label样式,我们也可以在C语言b/c中这样做,它有goto和label。

汇编语言中的每个结构化语句都有一个模式。

尽管与嵌套相关的明显的复杂性,汇编语言翻译应该简单地遵循每个单独的结构化语句的模式。

我强烈主张一种简单、合乎逻辑的翻译方法。

给定Python代码,我会首先将其翻译成C。Python有许多简单的功能,可以隐藏复杂性,这需要在汇编语言中公开。幸运的是,您的示例足够简单,但循环变量增量是隐藏的。

接下来,我提倡运行C代码以确保它能正常工作。翻译C或伪代码中的错误会带来糟糕的体验!此外,C代码中微小的算法更改或错误修复都会对汇编代码产生巨大的影响(可能需要重做翻译而不是应用相同的错误修复),因此有可用的代码来翻译是很重要的。

给定一个for循环,我要做的第一件事就是把它转换成while循环。

代码语言:javascript
复制
for ( int i = 0; i < N; i++ )
    <i-loop-body>

这会变成:

代码语言:javascript
复制
int i = 0;
while ( i < N ) {
    <i-loop-body>
    i++;
}

接下来,我们将while循环转换为汇编语言的if-goto-label样式:

代码语言:javascript
复制
    int i = 0;
Loop1:
    if ( i >= N ) goto EndLoop1;
    <i-loop-body>
    i++;
    goto Loop1;
EndLoop1:

让我们注意几件事:

  • 条件测试在if-goto-label中颠倒过来,因为if-goto语句(在汇编语言中也称为条件分支)告诉我们何时停止循环,而不是我们在C中所说的,即何时继续循环。

  • 循环以标签结束,这是结构化语句的自然转换。重要的是,在循环完成后,机器代码将移动到之后的下一条语句,通过这种模式转换,这将自然发生:任何成功完成此循环的语句都将在循环结束时运行,就像在C语言中一样。我在结构化语句转换之后命名标签,而不是通过恰好跟随的任何代码命名。

  • 处理器看不到标签,因为在将汇编文本转换为机器码的过程中,汇编程序会删除标签。*处理器只看到机器代码指令,而标签不是机器代码。标签会影响使用它们的指令(即goto),但它们本身不是生成的机器代码程序的一部分。

要转换多个循环,无论是连续的还是嵌套的,每个模式转换都必须使用一组新的数字:因此,要转换另一个循环,请在整个模式转换过程中使用新标签Loop2和EndLoop2。

如果有多个while循环要翻译,请严格遵循模式。嵌套不会改变模式。*只要按字面意思遵循模式,汇编代码的行为将与C代码相同。

你可以先翻译一个内部循环,也可以先翻译一个外部循环。这并不重要。你也可以按程序顺序翻译,但这更难,因为你必须在多个模式和它们的片断部分之间来回转换。

在上面的示例中,如果i- loop -body本身有另一个循环,则只需将该循环的平移放在i-loop-body出现的位置。

因此,假设我们从以下内容开始:

代码语言:javascript
复制
for ( int i = 0; i < N; i++ ) 
    for ( int j = 0; j < M; j++ )
        <j-loop-body>

在上面的代码中,i- loop -body是整个for-j循环。

代码语言:javascript
复制
int i = 0;
while ( i < N ) {
    int j = 0;
    while ( j < M ) {
        <j-loop-body>
        j++;
    }
    i++;
}

在部分if-goto-label中,仅转换了外部循环:

代码语言:javascript
复制
    int i = 0;
Loop1:
    if ( i >= N ) goto EndLoop1;
    int j = 0;
    while ( j < M ) {
        <j-loop-body>
        j++;
    }
    i++;
    goto Loop1;
EndLoop1:

在部分if-goto-label中,只转换了内部循环:

代码语言:javascript
复制
    int i = 0;
    while ( i < N ) {
        int j = 0;
Loop2:
        if ( j >= M ) goto EndLoop2;
        <j-loop-body>
        j++;
        goto Loop2;
EndLoop2:
        i++;
    }

然后将两者转换为:

代码语言:javascript
复制
    int i = 0;
Loop1:
    if ( i >= N ) goto EndLoop1;
    int j = 0;                                 i-loop-body, j-loop start
Loop2:                                          "
    if ( j >= M ) goto EndLoop2;                "
    <j-loop-body>                               "
    j++;                                        "
    goto Loop2;                                 "
EndLoop2:                                      i-loop body, j-loop completed 
    i++;
    goto Loop1;
EndLoop1:

通过简单的模式替换,Loop2的翻译,包括j的初始化,完全属于i-loop-body所在的位置。

许多开始使用汇编语言而没有模式方法的人会在他们的控制结构中犯简单的错误。例如,错误地将int j = 0;部分移动到代码段的最顶端,靠近int i = 0;,在那里它将在嵌套循环的第一次执行中工作,但在之后就不会工作。另一个例子是忘记顺序语句,在这里,这可能意味着在循环2中使用goto Loop1; (退出内部循环),意外地跳过了在循环2完成后每次都应该执行的i++;

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

https://stackoverflow.com/questions/69564252

复制
相关文章

相似问题

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