1

我正在为大学课程做一个项目。

首先,我不是要求一个完整的解决方案。我很难找到哪里出错了。当我输入有效的 ISBN 3201541974 时,我的程序会打印“无效”代码块。对于您可以看到的任何逻辑错误,我将不胜感激,并且我也很想知道是否有比一次盯着我的所有代码更好的调试方法。我习惯于依赖简单的打印语句和断点。

编辑:问题就在这里

L1_top:
        mov     al, [esi]               ; get a character
        inc     esi         ; update source pointer
        sub     al, 0
        add     ah, al
        cmp     ah, 11
    .......

我从 al 中减去 0 的原因是因为 al 最初是一个字符。从 al 中减去 '0' 会将其转换为 int 或 w/e。我错误地减去了 0 而不是 '0'

正确的线是

        sub     al, '0'
4

2 回答 2

7

首先,我想说的是,我实际上是这门课程的助教,你只是寻求帮助调试而不是寻求答案,这很好,但我们确实有办公时间,而且我们非常友好。

我先回答比较简单的问题。有一种更简单的方法可以找到代码中的问题,它称为 gdb。它基本上只是一个调试器。以这种方式进行调试非常有帮助,因为它允许您在运行程序时查看寄存器和内存中的实际内容。这是有关如何使用它的一些信息的链接。我建议你阅读它,因为它真的很有帮助。gdb 帮助

现在进入更复杂的部分。

  • 我不明白为什么你有 msg10 或 msg11,当你理解逻辑的设置方式时,你也可以摆脱它们和 msg5。
  • 在您的错误检查中,您可能希望将 eax 与 11 进行比较,如果相等则跳转。这样,如果有正确的位数,它只需要处理逻辑。(10 位数 + 新行)
  • 在您的循环中,您应该检查该值是否在“0”和“9”之间(是的,撇号很重要,它们告诉计算机这些值是 ASCII 而不是数字)或“X”。
  • 完成之后,您应该检查“sum”和“t”是否大于或等于 11,如果是,则减去 11,并通过整个循环 10 次,每个字符一次。
于 2013-02-18T04:12:50.883 回答
2

不幸的是,“打印语句”并不那么容易编写——只需调用“print_debug_out”函数就会改变大部分相关状态(标志、堆栈等)。但是您可以编写它们并且只执行一次。创建一个调试函数和宏的迷你库!

我也打算建议gdb。使用调试信息 (-g) 组装并使用 gdb 进行调试。您可能需要找到教程或 GUI 包装器,但学习使用 gdb(或其他调试器,就此而言)将是非常值得的。

请注意,您可以在源代码以及调试器中设置断点。只需使用int 3orint3说明。

于 2013-02-18T04:24:40.823 回答