Reputation: 31
I've written a simple program, in which one I press
These three buttons work perfectly fine, now I what I want is this: when I press "4" the program reads that text file (that I made before by pressing "1"). Now I've also written the code that opens the text file and it works normal as an stand alone. Here it is:
org 100h ; .com memory layout
mov dx, offset file ; address of file to dx
mov al,0 ; open file (read-only)
mov ah,3dh
int 21h ; call the interupt
jc terminate ; if error occurs, terminate program
mov bx,ax ; put handler to file in bx
mov cx,1 ; read one character at a time
print:
lea dx, BUF
mov ah,3fh ; read from the opened file (its handler in bx)
int 21h
CMP AX, 0 ; how many bytes transfered?
JZ terminate
mov al, BUF
mov ah,0eh ; print character (teletype).
int 10h
jmp print ; repeat if not end of file.
terminate:
mov ah, 0 ; wait for any key...
int 16h
ret
file db "c:\finaltest.txt", 0
BUF db ?
END
But when I import these codes into my main program, it can't open the file. Here's the full program, I want the program to read that text file when I press "4", but instead the program just gets reloaded:
.model small
.stack 100h
.data
msg1 db 10, 13, 10, 13, "Please select an item:",0Dh,0Ah,0Dh,0Ah,09h
db "1- Create File",0Dh,0Ah,09h
db "2- About",0Dh,0Ah,09h
db "3- Exit",0Dh,0Ah,09h
db "4- Open File",0dh,0ah,09h
db "Enter item number: "
db '$'
About db 10, 13, 10, 13, "Blank Text About the Program$"
handle dw ?
file1 db "c:\finaltest.txt", 0
text db "Contains Message",0
text_size equ $ - text
.code
main proc
mov ax,@data
mov ds,ax
ShowMenu:
lea dx, msg1
mov ah, 09h
int 21h
getnum:
mov ah, 1
int 21h
cmp al, '1'
jl ShowMenu
cmp al, '3'
jg ShowMenu
cmp al, "1"
je CreateFile
cmp al, "2"
je ShowAbout
cmp al, "3"
jmp Quit
cmp al, "4"
jmp OpenFile
Quit:
mov ah,4ch
int 21h
Showabout:
lea dx, About
mov ah, 09h
int 21h
jmp ShowMenu
CreateFile:
jmp new
text_size = $ - offset text
new:
mov ah, 3ch
mov dx, offset file1
int 21h
mov handle, ax
mov ah, 40h
mov bx, handle
mov dx, offset text
mov cx, text_size
int 21h
int 21h
ret
OpenFile:
jmp print
mov dx, offset file
mov al,0
mov ah,3dh
int 21h
jc terminate
mov bx,ax
mov cx,1
print:
lea dx, BUF
mov ah,3fh
int 21h
CMP AX, 0
JZ terminate
mov al, BUF
mov ah,0eh
int 10h
jmp print
terminate:
mov ah, 0
int 16h
ret
file db "c:\finaltest.txt", 0
BUF db ?
END
jmp ShowMenu
main endp
end main
Upvotes: 3
Views: 9133
Reputation: 39166
My answer to this old question is written solely for the benefit of the 1k or so users that view this Q/A every year.
Now I've also written the code that opens the text file and it works normal as an stand alone.
The new code was developed as a DOS .COM file (see the org 100h
). You cannot just copy it into your .EXE program without proper modifications!
.data
section.ret
instruction (provided the stack was kept balanced), but once you incorporated the code in your final .EXE, this ret
made no sense anymore!END
directive, but it has no purpose anymore in the context of your final .EXE program.The new code has a few issues of its own:
"c:\finaltest.txt", 0
does not obey the format as there are 9 characters in the name portion.I want the program to read that text file when I press "4", but instead the program just gets reloaded:
cmp al, '1' jl ShowMenu cmp al, '3' jg ShowMenu
Here, you are limiting the allowed selection to just 1, 2, and 3. Any other key will show the menu again.
cmp al, "1" je CreateFile cmp al, "2" je ShowAbout cmp al, "3" jmp Quit cmp al, "4" jmp OpenFile Quit:
Because of the unconditional jump jmp Quit
, you are not responding to the result of comparing AL to the ASCII "3", moreover the check for ASCII "4" is now unreachable.
CreateFile: jmp new text_size = $ - offset text new:
A construct that calculates the length of a text message belongs directly below the corresponding message. It looks insane to want to jump over it! It would be much cleaner if you just removed it.
mov ah, 3ch mov dx, offset file1 int 21h mov handle, ax
The DOS.CreateFile function 3Ch expects to receive the desired fileattribute in the CX register. For a normal file use xor cx, cx
.
And DOS will inform you about any problems that could occur, through the carry flag and the AX register. Don't neglect this possibility. At the very least have something like jc Abort
before saving the handle and continuing the program.
mov ah, 40h mov bx, handle mov dx, offset text mov cx, text_size int 21h
Again a case of neglecting the possibility of an error occuring.
int 21h
It is very probable that repeating this int 21h
is going to terminate the program immediately. At the conclusion of the DOS.WriteFile function 40h, the AH register would have been set to 0, and that happens to be the function number for one of the program termination functions in DOS. What would make sense here is specifying mov ah, 3Eh
so that the file gets closed with DOS.
ret
Because you reached the CreateFile procedure through a conditional jump je CreateFile
, you can not use ret
to continue the program. Either use jmp ShowMenu
(much preferred), or learn something new and write mov ax, offset ShowMenu
push ax
ret
.
OpenFile: jmp print mov dx, offset file mov al,0 mov ah,3dh int 21h jc terminate mov bx,ax mov cx,1 print:
Even if the program execution should arrive at OpenFile (see 'About ShowMenu'), there's no hope to effectively open a file given that you are skipping the necessary instructions!
lea dx, BUF ...
You can load the address with the mov dx, offset BUF
instruction. A few extra keys to press but the reward is a 3-byte instruction instead of the 4 bytes that lea
produces.
The other problems in OpenFile were already discussed in the top paragraph of this answer.
Upvotes: 1
Reputation: 11018
Looking at your code, I see multiple issues:
OpenFile
does not open the file; there's a weird jmp print
that skips the first part of the function.CreateFile
nor OpenFile
closes the file after writing/reading. I'm not sure about an emulated environment, but in production, you'd be creating an empty file.int 21h
at the end of CreateFile
; a copy/paste error?ret
without any call
, as already pointed out by Michael.file
and BUF
are in .code
segment, should be in .data
(though this may not be a problem in the emulator you are using).Solutions:
jmp print
that's at the start of OpenFile
.int 21h
.ret
by jmp ShowMenu
..data
above the definition of file
and BUF
.After that, you may need to do more debugging to get everything to work.
Code sample to close a file:
mov ah, 3Eh
mov bx, handle
int 21h
Upvotes: 2