2016-09-28 67 views
1

我創建了一個裝配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 

在此代碼我需要實際檢查,如果號碼(由名稱一個上的數據段稱爲)是對稱的或不是,並打印出答案。在這種情況下,答案應該是肯定的,但它打印出號。

+2

如果您的程序在調試器中的行爲與在調試器外運行時不同,它通常表示您沒有正確初始化內存和/或寄存器。我沒有按照你的代碼的邏輯,而是掃描了我看到的代碼,包括'inc di''cmp di,7'。問題是你永遠不會初始化寄存器_DI_。也許你打算在某個時候將它設置爲0? –

+1

@MichaelPetch omgggg它的真實!非常感謝你的男人!哇,我永遠找不到那個錯誤! – Argaman

回答

0

什麼邁克爾說,再加上一些想法如何繼續,如果你擊中今後再發生類似的問題:

當調試器失敗時,可以侵擾你的代碼與日誌記錄,嗶聲,asserting等...

因此,例如:你會每個週期輸出「* \ n」在屏幕上,你很快就會意識到它沒有結束7個週期後,但做了很多。

然後你就可以專注於確認有關可能退出循環所有你的假設,例如打印值ax(提前cmp ah,al)和di(提前cmp di,7)。

這是一個絕望的措施,但有時幫助(時間成本)。

有時甚至更快重新開始,並從零開始編寫特定功能。使用本地的git存儲庫,並經常提交,只要你有一些小任務完成,然後在調試和工作,所以你可以輕鬆地返回到一些工作版本,並再次開始修改。或者至少可以輕鬆地比較一下,您對舊的工作代碼做了哪些更改。或者爲了避免錯誤的假設,有意在你的應用程序的開始時將所有寄存器中的值設置爲0xDEADBEEF,並且在堆棧/內存緩衝區或分配內存之後,或者在釋放內存之前,有意將諸如0xDEADBEEF之類的值放入代碼中僅用於一些定義宏的調試構建)。 C++調試版本經常使用各種各樣的內存標記來填充未初始化/釋放的內存,所以如果代碼執行某些不正確的操作,代碼會碰到「奇怪」的值。