2011-10-07 131 views
0

所以這個程序是一個任務。截止日期過去了,我轉入了我的所得,並取得了好成績,但是這個bug一直困擾着我。這在技術上不再是一項任務,但如果您不爲我編寫代碼,我仍然會更喜歡,因爲我想了解爲什麼會發生這種情況,而不一定要解決它。程序終止後無限循環

所以程序工作正常(在本質上它基本上是toUpper()),但是當我通過程序終止字符(句號)後,程序成功調用'end',但從未實際終止。如果我在分步調試器中運行它,調用'end main',那麼程序jumsp到一些我不認識的預先編寫的代碼,可能會清理堆棧,調用DOS,我不知道。我已經嘗試了很多不同的東西(都沒有成功),我很好奇,如果有人有什麼可能造成這種情況的洞察力。下面

代碼:

;--------------------------------------------------------------------- 
; program:  Key 
; function: Reads in specific characters from input and displays them. 
; owner:  ---------- 
; date:  9/29/11 
; 09/22/2011 Original Version 
;---------------------- 
    .model small 
    .8086 
;---------------------- 
    .data    ; Start the data segment 
;---------------------- 
    ; No variables 

;---------------------- 
    .code    ; Start the code segment 
;---------------------- 
main:     ; Reading in values 
    mov ah, 8h   ; Request input without echo 
    int 21h   ; Read character into al 

    cmp al, 20h  ; Is it a space? 
    je print   ; If so, print with no changes 
    cmp al, 2Eh  ; Is it a period? 
    je print   ; If so, go to exit. 
    cmp al, 41h  ; Is it below the floor of uppercase? 
    jl main   ; Then it's useless, throw it out and read in new. 
    cmp al, 7Ah  ; Is it above lower ceiling? 
    jg main   ; Then it's useless, throw it out and read in new. 
    cmp al, 5Ah  ; Is it smaller than upper ceiling? 
    jle print   ; If it's equal or smaller, then it's an upper. 
    cmp al, 61h  ; Is it above lower floor? 
    jl main   ; If it is lower, back to main. 
         ; If we're here it's a lowercase letter 
    sub al, 20h  ; Subtract 20h to make lowercase 

print:     ; Print characters 
    mov dl, al   ; Copy character to output register 
    mov ah, 2h   ; Load character output subroutine 
    int 21h   ; Print character 
    cmp dl, 2Eh  ; Check if it was a period. 
    jne main   ; If not a period, go to main. 

    mov ah, 4Ch  ; Place Exit Code for DOS service 
    int 21h   ; call DOS service 
    end main   ; If it was a period, exit program. 
;---------------------- 

結束前2號線是由我的FRIND誰與彙編更多的經驗比我的建議,它使程序正確終止我的DOS模擬器,但問題與'結束'仍然發生在調試器和我的教授測試腳本。

任何人都有任何想法可能導致這種情況?

+2

當您調用DOS退出時,al包含退出代碼(或錯誤級別)。嘗試mov ax,4c00h而不是mov ah,4ch。這樣的錯誤代碼將是0(意味着一切正常) – BlackBear

+0

哇,以便修復它,真棒。 所以我猜在al中有一個剩餘的數字,那肯定會把它拋出去嗎? 如果您願意,可以將其作爲答案提交,以便我可以將其標記爲已解決。 – Charles

+0

'sub al,20h'行中的註釋應該是「減去20h以使* upper * case」,而不是* lower * case。 –

回答

3

當您調用DOS退出時,al包含退出代碼(或錯誤級別)。嘗試mov ax, 4c00h而不是mov ah, 4ch。這樣的錯誤代碼將是0(意味着一切正常)。這使得它的工作,因爲返回代碼是由DOS語句IF ERRORLEVEL ...以某種方式使用,它將所有東西擰緊。 ;)

+0

這解決了它,真棒。 謝謝。 – Charles

+0

@Charles:沒問題。大會充滿了這個奇特的頭破血流的東西;) – BlackBear

3

當你說程序「調用結束」成功,你的意思是它傳遞給end main

end什麼也沒做。這只是彙編程序指示代碼結束的指示。它對你的代碼執行沒有影響。沒有你的朋友建議的最終int 21h,你的代碼將會繼續執行。如果幸運的話,它會繼續執行nop指示。

+0

是的,我認爲這是我誤解。 我沒有意識到,它本質上是一個編譯指令,而int 21h/mox ax,4c00h是實際的退出命令。 我基本上是等同於Java的System.exit()和int/mov命令到括號中的數字,當它實際上或多或少倒退。 – Charles

+0

儘管看到學生仍然被教會了彙編語言,但它讓我感到好笑,他們正在教導你在MS-DOS環境下運行x86彙編程序。它提醒我必須參加在OS/360上運行的IBM BAL(基本彙編語言)課程,這已經遠遠落後於我學習的時間。它花了很大力氣讓教練讓我用最新的機器和操作系統來完成最後的三個任務。再次看到「int 21h」真的很古怪。 –

+0

我完全理解爲什麼它是從一個歷史的,內在的角度講授的,儘管我真的希望我們有更多的類是這樣的,但對於其他語言:Ruby,PHP等;我會從這些中獲得更多的用途。 – Charles