2011-10-07 92 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