程序集打印出与调试器所说的不同的答案

assembly prints out not the same answer as the debugger says

我创建了一个 assembly 8086 程序作为我学院的作业,结果简单地打印出是或否,以及 TASM 汇编程序显示了错误的答案,当我检查了调试器以查看它是如何发生的时,它实际上做了正确的事情!你说问题是什么? 代码如下:

.model small
.stack 100h
.data
  a dw 1101001001001011b
  b db 'yes$'
  d db 'no$'
.code
  mov ax, @data
  mov ds, ax
  mov dx,0
  mov cl ,1
  loop1:
    mov ah,0
    mov al,0
    rol a,cl
    adc ah,0
    rcr a,cl
    rcr a,cl
    adc al,0
    rol a,cl
    cmp ah,al
    jne outloop
    inc cl
    inc di 
    cmp di,7
    jne loop1
    mov dx ,offset b
    mov ah,9
    int 21h
    jmp outt
    outloop:
      mov dx ,offset d
      mov ah,9
      int 21h
      jmp outt
  outt:
.exit
  end

在这段代码中,我实际上需要检查数字(在数据段上以名称 a 调用)是否对称或不,并打印出答案。在这种情况下,答案应该是肯定的,但它打印出 no..

Michael 所说的内容,以及以后遇到类似问题时如何处理的一些想法:

当调试器失败时,您可以通过日志记录、蜂鸣声、断言等方式感染您的代码...

所以举个例子:如果你每个循环都在屏幕上输出“*\n”,你很快就会意识到它在 7 个循环后并没有结束,而是做了更多。

然后你可以专注于验证所有关于可能的循环退出的假设,比如打印 ax 中的值(在 cmp ah,al 之前)和 di(在 [=13= 之前) ]).

这是一个孤注一掷的措施,但有时会有所帮助(为了时间成本)。

有时重新开始甚至从头开始编写特定功能会更快。使用本地 git 存储库,并经常提交,只要你完成了一些小任务,然后在调试和工作时,你就可以轻松地回到某个工作版本,并再次开始修改。或者至少轻松地比较一下,您对旧的工作代码做了哪些更改。

或者为了避免错误的假设,在应用程序开始时有意将 0xDEADBEEF 之类的值放入所有寄存器中,并在 stack/memory 缓冲区或分配内存之后或释放之前将更多的值放入等(仅通过某些定义宏使代码对于调试构建是可选的)。 C++ 调试版本经常使用各种 CCCC.../DDDD.../FDFD../... 内存标记来填充 uninitialized/freed 内存,因此代码命中 "weird" 中的值万一它做错了什么。