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 a开发者_开发百科ssignment 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?
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. ;)
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.
精彩评论