【问题标题】:Array loop variable ecx(-1)数组循环变量 ecx(-1)
【发布时间】:2018-12-02 15:54:49
【问题描述】:

我想数数为 0 的数字。
MASM 错误:

循环变量ecx(-1)。

使用 ollydb。

请帮忙。为什么它不起作用?

.586
        .model flat, stdcall

        extern ExitProcess@4:near

        includelib c:\masm32\lib\user32.lib
        includelib C:\masm32\lib\kernel32.lib


        data segment
            mas db 1,0,9,8,0,7,8,0,2,0
            rez db 0
        data ends


        text segment
        start:
            mov cx, 10
            xor ax, ax
            xor si, si
            jcxz exit

            cycl:
                cmp mas[si], 0
                jne m1
                inc al

                m1:
                    inc si
                    loop cycl

                mov rez,al

            exit:
                push 0
                call ExitProcess@4
        text ends
        end start

【问题讨论】:

  • 从那个 includelib 我猜你是在 Windows 上运行它。在 32 位或 64 位模式下使用 16 位寄存器总是不好的主意,请阅读 32 位模式下循环指令的文档 -> 它使用 ecx 而不是 cx,从 [si] 读取可能会生成 PME,除非您在环 0
  • 这是一个 32 位程序。不要在没有充分理由的情况下使用 16 位寄存器。因此,至少将所有 cx 更改为 ecx,将所有 si 更改为 esi。
  • loop 在 32 位模式下使用 ECX(不是 CX),但这不应该阻止它组装。 (不过,这段代码在 32 位模式下似乎是个糟糕的主意。16 位寻址模式可能无法寻址静态数据。而且您不会将 ECX 的高 16 位归零,因此循环可以运行很多次迭代)。但听起来你是在说你在尝试汇编时收到了来自 MASM 的错误消息,所以在 ollydbg 下没有可运行的可执行文件。没有行号吗?

标签: arrays loops assembly


【解决方案1】:

您正在为 32 位编程!
LOOP 指令将使用ECX 寄存器,但您只初始化了CX 寄存器。这会产生错误。

start:
    mov ecx, 10
    mov al, 0
    xor esi, esi
cycl:
    cmp mas[esi], 0
    jne m1
    inc al
m1:
    inc esi
    loop cycl
    mov rez,al

【讨论】:

  • 但是为什么这会阻止它与 MASM 组装? OP 程序中的所有指令在 32 位模式下均有效。他们没有创建一个整体有用的程序,但这是程序员的问题。汇编程序通常不会阻止您发出您编写的机器代码,或者最多发出警告。
  • @PeterCordes 我不认为这是装配时间错误。我将其归咎于 OP 的措辞不佳。可能 ollydb 显示了ECX==-1
  • 那是不可能的。从ECX = 0x????000a 开始,循环将在 0 处停止(如果它没有首先出错)。如果您使用 ECX=0 运行 loop,则只能获得 ECX = -1。
  • 是的。但是我们能确定是loop 指令停止了程序吗?如果它因调试器显示ECX == 0x????FFFF 而停止,并且考虑到OP 不太关心CXECX,它可能暗示OP 为什么写“ecx(-1)”。真的不知道...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
  • 2012-06-08
  • 2020-01-19
相关资源
最近更新 更多