In this section, we will discuss a group of INT 21h functions called file handle functions,
for file processing. We will describe what is meant by a file handle, file errors,
opening and closing a file, reading from a file and writing to a file.
File Handle
When a file is opened or created in a program, DOS assigns it a unique number
called the
file handle. This number is used to identify the file, so the program
must save it. There are five predefined file handles as shown in the following table:
File Handle | Device |
|
0 | keyboard
|
1 | screen
|
2 | error output -- screen
|
3 | auxiliary device
|
4 | printer
|
File Errors
There are many opportunities for errors in INT 21h file handling. DOS
identifies each error by a code number. In the functions we describe here,
if an error occurs then the CF is set and the code number appears in AX.
The following table contains the most common file-handling errors:
Hex Error Code | Meaning |
|
1 | invalid function number
|
2 | file not found
|
3 | path not found
|
4 | all available handles in use
|
5 | access denied
|
6 | invalid file handle
|
C | invalid access code
|
F | invalid drive specified
|
10 | attempt to remove current directory
|
11 | not the same device
|
12 | no more files to be found
|
Opening a New File
Before a file can be used, it must be opened. To create a new file or rewrite
an existing file, the user provides a filename and an attribute and DOS
returns a file handle.
Open a New File/Rewrite a File: INT 21h, function 3Ch
Input: AH = 3Ch
DS:DX = address of file name, which is an ASCII string
(a string ending with a 0 byte)
CL = attribute
Output: if successful, AX = file handle
Error if CF = 1, error code in AX (3, 4, or 5)
|
The file name may include a path; for example C:\COE205\EX.ASM.
Possible errors for this function are 3 (path does not exist),
4 (all file handles in use), or 5 (access denied, which means either that
the directory is full or the file is read-only file).
A file attribute is a byte that specifies some attributes for files as shown below:
Bit | Meaning if Set |
|
0 | Read-only file
|
1 | Hidden file
|
2 | DOS system file
|
3 | Volume label
|
4 | Subdirectory
|
5 | Archive bit
|
6 | Not used
|
7 | Not used
|
Example: Write a program to open a new read-only file called FILE1. |
.model small
.stack 100h
.data
FNAME DB 'FILE1', 0
HANDLE DB ?
.code
.startup
MOV AH, 3Ch ; open file function
LEA DX, FNAME ; DX has filename address
MOV CL, 1 ; read-only attribute
INT 21H ; open file
MOV HANDLE, AX ; save handle or error code
JC OPEN_ERROR ; jump if error
...
.exit
END
|
Opening an Existing File
To open an existing file, there is another function:
Open an Existing File: INT 21h, function 3Dh
Input: AH = 3Dh
DS:DX = address of file name, which is an ASCII string
(a string ending with a 0 byte)
AL = access code: 0 means open for reading
1 means open for writing
2 means open for both
Output: if successful, AX = file handle
Error if CF = 1, error code in AX (2, 4, 5 or 12)
|
Closing a File
After a file is processed, it should be closed. This frees the file handle for use
with another file.
Close a File: INT 21h, function 3Eh
Input: BX = file handle
Output: if CF = 1, error code in AX (6)
|
Example: Write some code to close a file whose handle is stored in variable HANDLE. |
MOV AX, 3Eh ; close file function
MOV BX, HANDLE ; get handle
INT 21H ; close file
JC CLOSE_ERROR ; jump if error
...
|
Reading from a File
The following function reads a specified number of bytes from a file
and stores them in memory.
Read from a File: INT 21h, function 3Fh
Input: AH = 3Fh
BX = file handle
CX = number of bytes to read
DS:DX = memory buffer address
Output: AX = number of bytes actually read
if AX=0 or AX < CX, end of file encountered
Error if CF = 1, error code in AX (5, 6)
|
Example: Write some code to read a 512-byte from a file. Assume file handle is stored in variable HANDLE, and BUFFER is a 512 byte buffer. |
.data
HANDLE DW ?
BUFFER DB 512 DUP(0)
...
.code
...
MOV AX, 3Fh ; read file function
MOV BX, HANDLE ; get handle
MOV CX, 512 ; read 512 bytes
INT 21H ; read file, AX = bytes read
JC READ_ERROR ; jump if error
...
|
Writing to a File
Function 40h writes a specified number of bytes to a file.
Write to a File: INT 21h, function 40h
Input: AH = 40h
BX = file handle
CX = number of bytes to write
DS:DX = data address
Output: AX = number of bytes written
if AX=0 or AX < CX, error (full disk)
Error if CF = 1, error code in AX (5, 6)
|
Function 40h writes data to a file, but it can also be used to send data
to the screen or printer (handles 1 and 4 respectively).
Example: Use function 40h to display a message on the screen. |
.data
MSG DB 'Display This Message'
...
.code
...
MOV AX, 40h ; write file function
MOV BX, 1 ; screen file handle
MOV CX, 20 ; length of message
LEA DX, MSG ; get address of MSG
INT 21H ; display MSG
...
|