【问题标题】:Stepping Through the Stack with MASM使用 MASM 单步执行堆栈
【发布时间】:2012-11-16 03:01:02
【问题描述】:

我正在尝试编写一个简单的汇编应用程序,它从用户那里读取字符,然后检查输入的字符串是否可以被视为整数。

mov       ebx,esp
input:
get_ch    eax
cmp       eax,0dh
je        continue
push      eax
jmp       input

continue:
put_str    0ah

xor       edx,edx
output:

这就是我迷路的地方......

put_ch    dword ptr [ebx-4][edx]
dec       edx
jmp       output

...使用 [ebx-4] 和 edx = 0,我可以输出第一个字符。之后它似乎正在输出空格或空字符。

任何帮助或参考链接将不胜感激,我很难找到可以查找 MASM 的内容。

【问题讨论】:

    标签: masm


    【解决方案1】:

    1) 我不熟悉 put_ch 或 get_ch,但我认为 put_ch dword ptr [ebx-4][edx] 在 EBX 和 EDX 调用之间需要一个 ','。

    2) 每次迭代都将 EDX 更改为 -1,但指针 (EBX) 始终位于 ebx-4。如果我错了,请纠正我,但你不应该改变EBX吗?我不认为 -4 实际上在每次迭代运行中都会从 EBX 中减去。

    3) 我认为如果你从 0 中减去,就像在 EBX 中所做的那样,在汇编中你只设置溢出标志 (OF),或者至少设置 SF(符号标志)。检查您正在使用的 ASM 实现的标志,并查看哪些命令设置了哪些标志。

    【讨论】:

    • 恐怕你在三点上都错了。首先,[ebx-4][edx] 不需要“在 EBX 和 EDX 调用之间”,因为它使用基于索引的寻址,这就是该代码可以成功组装的原因。 put_ch 在这种情况下是一个宏。其次,循环递减 EDX,在我看来,它试图将 [ebx-4][edx] 的有效地址从第一个到最后一个指向列表中推送的项目。第三,仅当带符号的二进制补码结果不适合用于操作的位数时才设置 OF。 SF将从 0 递减后设置。
    【解决方案2】:

    在我看来,您不必要地从输出循环的有效地址中减去 4。也许您认为括号用于乘法。不是这种情况; IA-32 不支持这种类型的寻址。在你的代码中,你把...

    put_ch    dword ptr [ebx-4][edx]
    dec       edx
    jmp       output
    

    在循环的第一次迭代的第一条指令中,作为 *put_ch* 宏的有效地址,相对于堆栈帧的顶部 (EBX),结果为 -4。这个数字,代表堆栈上的地址,将被传递给宏以成功打印 ASCII 代码。但是,由于 dec edx 指令,第二次迭代将失败,因为程序将调用 *put_ch* 并使用参数 -5。由于这个地址的双字几乎毫无疑问会包含 0,*put_ch* 会将它注册为 NULL 字符,表示字符串的结束。 试试这个:

    dec       edx
    put_ch    dword ptr [ebx][edx*4]
    jmp       output
    

    这里,EDX 被递减首先,并在宏中用作要乘以四的索引。因此,传递给 *put_ch* 的第一个地址将是 -4。传递的第二个地址是-8。第三个是 -12,依此类推...

    最后,我强烈建议,在比较 get_ch 的返回值和 0dh(回车)时,请使用 AL(1 字节)而不是 EAX(4 字节)以防上EAX 的 3 个字节包含任意数据。

    祝你好运。

    【讨论】:

      猜你喜欢
      • 2012-01-28
      • 2021-11-02
      • 2016-02-07
      • 1970-01-01
      • 2021-06-29
      • 2020-05-16
      • 2017-04-01
      • 2022-01-13
      • 2019-04-15
      相关资源
      最近更新 更多