【问题标题】:Loop in Intel x86 Assembly going on foreverIntel x86 Assembly 中的循环永远进行
【发布时间】:2013-04-26 07:03:59
【问题描述】:

我目前正在学习 Intel x86 Assembly,在尝试构建一个简单的循环时遇到了问题,该循环循环了 10 次。它应该在 10 次循环之后停止,但它会一直持续下去,直到永远。

这是我正在使用的代码:

    section .data
    msg     db      "Hello, World!", 0x0a
    len     equ     $-msg

    section .text
    global _start

    _start:
            mov     cx, 10  ; loop counter

            _loop_start:
                    mov     ebx, 0x01
                    mov     ecx, msg
                    mov     edx, len
                    mov     eax, 0x04
                    int     0x80

                    dec     cx
                    cmp     cx, 0
                    jge     _loop_start

            _done:
                    mov     ebx, 0x00
                    mov     eax, 0x01
                    int     0x80

在尝试编写此代码之前,我查看了 this tutorial 以进行简单的算术运算。

我是这样编译的:

   nasm -f elf64 test.s -o test.o

还有这样的链接:

   ld -s -o test_exec test.o

提前致谢, 阿尼克

【问题讨论】:

    标签: loops assembly x86 intel


    【解决方案1】:

    cx 是 ecx 的低 16 位部分。您的代码表明您可能认为您的循环将运行 10 次(您在循环之前将 cx 设置为 10)。但是你用 mov ecx, msg 覆盖了带有 msg 地址的值。因此,您将从该数字的低 16 位开始倒数到 0。 但减量甚至没有效果,因为在下一次迭代期间,您再次用 msg 的地址覆盖 ecx。循环再次开始。这是一个无限循环。 您是否在调试器中检查了软件?这很有帮助。

    【讨论】:

    • 啊。谢谢!我感觉有些东西正在覆盖它,但我不知道 cx 和 ecx 是一个(有点)
    • @Anickyan This 图像将让您了解“寄存器层次结构”。
    • @JesusPlusPlus11 不错的图片,但缺少一些 x86-64 寄存器:sildilbplspl。省略这些子寄存器与包含其他 x86-64 通用寄存器不一致。它完全错误地spesp 呈现为rip 的子寄存器!
    • @nrz 我的天啊。我没注意到!
    • @nrz:图像嵌入到 X86 维基百科的主要文章中。我的天:link
    【解决方案2】:

    如果“覆盖”问题得到解决,并且如果我们从 10 的计数器开始减少每个电路的计数器,并且如果计数器的值大于或等于 0 时分支,那么我们就变成了循环11 次。

    我们也可以使用 zeroflag 进行分支(如果 zeroflag 未设置):

                    dec     cl
                    jnz     _loop_start
    

    “dec”指令已经涉及标志寄存器,所以如果我们想检查一个值是否正在减少到零,我们不需要“cmp”指令。

    德克

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多