如何在 x86 汇编语言中创建嵌套循环

Posted

技术标签:

【中文标题】如何在 x86 汇编语言中创建嵌套循环【英文标题】:How to create nested loops in x86 assembly language 【发布时间】:2013-04-14 04:10:19 【问题描述】:

是否可以在 x86 汇编语言中创建嵌套循环?

我想将此psedocode 转换为正确的x86 汇编代码(使用MASM 语法),但我不确定如何在此处初始化每个循环计数器。甚至可以在 x86 汇编中声明局部变量(就像在大多数其他编程语言中一样)?

for (var i = 0; i < 10; i++)
    for(var j = 0; j < 10; j++)
        for(var k = 0; k < 10; k++)
            mov eax, i + j + k;
        
    

【问题讨论】:

这个问题与这个问题有一个看似相似的标题,但它几乎不相关:***.com/questions/15398672/… 另外,这个问题可能是相关的(即使它没有明显的原因得到大量的反对票):***.com/questions/10890648/… 鉴于您的 C 代码最终会被翻译成机器代码,这两个问题的答案都是肯定的,不需要问。 我觉得没有付出足够的努力。 不要贬低自己。做更多的研究。 【参考方案1】:

当然,这是可能的。由于每个计算机程序最终都归结为汇编 - 它自然是最强大的语言(不包括直接位操作)。

实际代码取决于您的系统、编译器和应用的优化,但基本上应该是这样的(例如 2 个嵌套循环,而不是 3 个):

           mov ecx, 0

outerLoop:

           cmp ecx, 10
           je done
           mov ebx, 0

innerLoop:
           mov eax, ecx        ; do your thing here
           add eax, ebx

           cmp ebx, 10
           je innerLoopDone
           inc ebx
           jmp innerLoop

innerLoopDone:

           inc ecx
           jmp outerLoop
done:

请注意,您不需要局部变量,您可以使用通用寄存器来满足您的需要。如果您坚持使用变量,则可以为此使用内存地址并使用寄存器指针进行读/写。

【讨论】:

我只会在内部循环之前将 CX 推入,然后在之后弹出。 @MartinJames 有很多很多方法可以做到这一点。如果担心的话,特别是 push/pop 会更慢 这些循环可以工作,但它们看起来像未优化的编译器输出(C 结构的直接音译)。这对于 asm 来说不是惯用的,通常在底部有 jcc,而根本没有 jmp。所以你跌倒退出循环。不过,它确实很好地展示了为单独的循环计数器使用单独的寄存器。 (并且回复:Martin 的观点:push/pop CX 和使用慢速 loop 指令是一个不再有用或相关的 16 位惯用语。)总的来说,值得一票,尤其是最后一段。 当局部变量存储在堆栈中时,嵌套不是通过enterleave 完成的吗?当然这样做是相当未经优化的,但我认为这应该是一般概念 @christopherwestburry:你的意思是在 x86 机器上申请函数调用。嵌套循环不需要接触堆栈帧。

以上是关于如何在 x86 汇编语言中创建嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中创建多个嵌套文件夹?

如何在另一个函数中使用嵌套函数作为球拍语言的参数?

如何在树枝模板中创建语言选择

在 Visual Studio Code 中创建自定义语言

如何在C中创建连续循环,其中循环的每次迭代在其内部循环的每次迭代中发生一次

如何在 C 语言的 windows 的 %appdata% 路径中创建目录并创建文件