Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 程序集打印出的答案与调试器所说的不同_Assembly_Tasm - Fatal编程技术网

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

Assembly 程序集打印出的答案与调试器所说的不同,assembly,tasm,Assembly,Tasm,我已经创建了一个汇编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 loo

我已经创建了一个汇编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)是否对称,并打印出答案。在这种情况下,答案应该是肯定的,但打印出来的是否定的。

Michael所说的,以及一些在将来遇到类似问题时如何处理的想法:

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

例如:如果您在屏幕上每个周期都输出“*\n”,您很快就会意识到它不是在7个周期后结束,而是在做更多的事情

然后,您可以专注于验证关于可能的循环出口的所有假设,例如在
ax
(在
cmp-ah,al
之前)和
di
(在
cmp-di,7
之前)中打印值

这是一个绝望的措施,但有时会有所帮助(以时间为代价)

有时重新开始,完全从头开始编写特定函数会更快。使用本地
git
repository,并经常提交,每当您完成一些小任务时,然后在调试和工作时提交,这样您就可以轻松地返回到某个工作版本,并再次开始修改。或者至少可以很容易地比较一下您对旧工作代码所做的更改


或者,为了避免错误的假设,有意在应用程序开始时将
0xDEADBEEF
等值放入所有寄存器,在堆栈/内存缓冲区上或内存分配后,或释放前,等等(仅通过某些define宏将代码设为调试生成的可选代码)。C++调试构建经常使用各种<代码> cccc.<代码> >代码> DDDD…<代码> >代码> FDFD…<代码>…内存标记来填充未初始化/释放的内存,这样代码在出错时会出现“奇怪”的值。

Michael所说的,以及在将来遇到类似问题时如何处理的一些想法:

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

例如:如果您在屏幕上每个周期都输出“*\n”,您很快就会意识到它不是在7个周期后结束,而是在做更多的事情

然后,您可以专注于验证关于可能的循环出口的所有假设,例如在
ax
(在
cmp-ah,al
之前)和
di
(在
cmp-di,7
之前)中打印值

这是一个绝望的措施,但有时会有所帮助(以时间为代价)

有时重新开始,完全从头开始编写特定函数会更快。使用本地
git
repository,并经常提交,每当您完成一些小任务时,然后在调试和工作时提交,这样您就可以轻松地返回到某个工作版本,并再次开始修改。或者至少可以很容易地比较一下您对旧工作代码所做的更改


或者,为了避免错误的假设,有意在应用程序开始时将
0xDEADBEEF
等值放入所有寄存器,在堆栈/内存缓冲区上或内存分配后,或释放前,等等(仅通过某些define宏将代码设为调试生成的可选代码)。C++调试构建经常使用各种<代码> cccc.<代码> >代码> DDDD…<代码> >代码> FDFD…<代码>…内存标记,用于填充未初始化/释放的内存,以便代码在执行错误操作时命中“奇怪”值。

如果程序在调试器中的行为与在调试器外部运行时的行为不同,则通常表示未正确初始化内存和/或寄存器。我没有遵循您代码的逻辑,而是向下扫描代码,我看到
inc di
cmp di,7
。问题是您从未初始化寄存器DI。也许你想在某个时候把它设为0?@MichaelPetch omgggg这是真的!!非常感谢你,伙计!哇,我再也找不到那个虫子了!如果您的程序在调试器中的行为与在调试器外部运行时不同,则通常表明您没有正确初始化内存和/或寄存器。我没有遵循您代码的逻辑,而是向下扫描代码,我看到
inc di
cmp di,7
。问题是您从未初始化寄存器DI。也许你想在某个时候把它设为0?@MichaelPetch omgggg这是真的!!非常感谢你,伙计!哇,我再也找不到那个虫子了!