Search code examples
assemblytasm

assembly prints out not the same answer as the debugger says


I've created an assembly 8086 program as an assignment from my academy, that simply prints out as a result yes or no, and the TASM assembler shows the wrong answer, when i've checked out the debugger to see how it happens, it actually doing the right thing! what do you say the problem is? the code is below:

.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

in this code i needed actually to check if the number(called by the name a on the data segment) is symmetric or not, and to print out the answer. and in this case the answer should be yes but it prints out no..


Solution

  • What Michael said, plus some ideas how to proceed if you hit similar problem in the future:

    When debugger fails, you can infest your code with logging, beeping, asserting, etc...

    So for example: would you every cycle output "*\n" on screen, you would soon realise it's not ending after 7 cycles, but doing lot more.

    Then you can focus on validating all your assumptions about possible loop exits, like printing values in ax (ahead of cmp ah,al) and di (ahead of cmp di,7).

    It's a desperate measure, but sometimes helps (for the cost of time).

    Sometimes it's even faster to start again, and write particular function completely from scratch. Use local git repository, and commit often, whenever you have some small task finished, then when debugged and works, so you can easily go back to some working version, and start the modification again. Or at least easily compare, what changes you did to the old working code.

    Or to avoid false assumptions, intentionally put values like 0xDEADBEEF into all registers at the start of your app and few more on stack/memory buffers or after memory is allocated, or before it is freed, etc (make the code optional for debug build only by some define-macro). C++ debug builds often use various CCCC.../DDDD.../FDFD../... memory markers to fill up uninitialized/freed memory, so the code hits "weird" values in case it's doing something incorrect.