程序终止后无限循环

发布于 2024-12-09 00:30:15 字数 2410 浏览 0 评论 0原文

所以这个程序是为了一个作业。截止日期过去了,我交出了自己的成绩,并取得了不错的成绩,但这个错误一直困扰着我。从技术上讲,这不再是一项作业,但我仍然希望您不为我编写代码,因为我想了解为什么会发生这种情况,而不一定要修复它。

所以程序工作正常(本质上是汇编中的 toUpper() ),但在我向程序传递终止字符(句点)后,程序成功调用“end”,但从未真正终止。如果我在逐步调试器中运行它,则会调用“end main”,然后程序会跳转到一些我不认识的预先编写的代码,可能会清理堆栈,调用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.
;----------------------

结束前的两行是由我的一个朋友建议的,他比我更有汇编经验,它使程序在我的 DOS 模拟器上正确终止,但在调试器中仍然出现“结束”的问题,我的教授测试脚本。

任何人都知道这可能是什么原因造成的?

So this program was for an assignment. The due date passed and I turned in what I had and got a good grade, but this bug has been bothering me. It's not technically an assignment anymore, but I'd still prefer if you didn't write code for me, since I want to understand why this is happening, not necessarily to fix it.

So the program works fine (it's essentially toUpper() in Assembly), but after I pass the program the terminating character (a period), the program calls 'end' successfully, but then never actually terminates. If I run it in a step-by-step debugger, the 'end main' is called, then the program jumsp to some prewritten code I don't recognize, could be cleaning the stack, calling DOS, I've no idea. I've tried lots of different things (all without success), and I'm curious if anyone has an insight on what could be causing this.

Code below:

;---------------------------------------------------------------------
;    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.
;----------------------

The 2 lines before the end were suggested by a frind of mine who's more experience with assembler than I am, and it makes the program terminate correctly on my DOS emulator, but the issue with 'end' still occurs in the debugger and my professor testing script.

Anyone have any idea what could be causing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

标点 2024-12-16 00:30:15

当您调用 DOS 退出时,al 包含退出代码(或错误级别)。尝试使用 mov ax, 4c00h 而不是 mov ah, 4ch。这样错误代码将为 0(意味着一切正常)。这使得它能够工作,因为返回码被 DOS 语句 IF ERRORLEVEL ... 使用,这把一切搞砸了。 ;)

When you call DOS for exit, al contains the exit code (or error level). Try mov ax, 4c00h instead of mov ah, 4ch. This way the error code will be 0 (means everything's ok). This makes it work because the return code is used somehow by the DOS statement IF ERRORLEVEL ... which screws everything up. ;)

怂人 2024-12-16 00:30:15

当你说程序“调用end”成功时,你的意思是它传递到了end main吗?

end 不执行任何操作。它只是给汇编器的一条指令,指示代码的结尾。它对代码的执行没有影响。如果没有您朋友建议的最终 int 21h,您的代码将继续执行。如果幸运的话,它将继续执行 nop 指令。

When you say that the program "calls end" successfully, do you mean that it passes to the end main?

end doesn't do anything. It's just an instruction to the assembler indicating the end of your code. It has no effect on the execution of your code. Without the final int 21h suggested by your friend, your code will simply keep executing. If you're lucky, it will keep executing nop instructions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文