Handle File-Access Skeleton

The following is a typical program sequence to access a file using the handle family of functions (Figure 8-7):

1.Get the filename from the user by means of the buffered input service (Int 21H Function 0AH) or from the command tail supplied by MS-DOS in the PSP.

2.Put a zero at the end of the file specification in order to create an ASCIIZ string.

3.Open the file using Int 21H Function 3DH and mode 2 (read/write access), or create the file using Int 21H Function 3CH. (Be sure to set the CX register to zero, so that you don't accidentally make a file with special attributes.) Save the handle that is returned.

4.Set the file pointer using Int 21H Function 42H. You may set the file-pointer position relative to one of three different locations: the start of the file, the current pointer position, or the end of the file. If you are performing sequential record I/O, you can usually skip this step because MS-DOS will maintain the file pointer for you automatically.

5.Read from the file (Int 21H Function 3FH) or write to the file (Int 21H Function 40H). Both of these functions require that the BX register contain the file's handle, the CX register contain the length of the record, and the DS:DX registers point to the data being transferred. Both return the actual number of bytes transferred in the AX register.

In a read operation, if the number of bytes read is less than the number requested, the end of the file has been reached. In a write operation, if the number of bytes written is less than the number requested, the disk containing the file is full. Neither of these conditions is returned as an error code; that is, the carry flag is not set.

6.If the program is not finished processing the file, go to step 4; otherwise, close the file (Int 21H Function 3EH). Any normal exit from the program will also close all active handles.

recsize equ 1024 ; file record size

.

.

.

mov ah,3dh ; open input file

mov al,0 ; mode = read only

mov dx,offset fname1 ; name of input file

int 21h

jc no_file ; jump if no file

mov handle1,ax ; save token for file

.

.

.

mov ah,3ch ; create output file

mov cx,0 ; attribute = normal

mov dx,offset fname2 ; name of output file

int 21h

jc disk_full ; jump if create fails

mov handle2,ax ; save token for file

.

next: . ; process next record

.

mov ah,3fh ; sequential read from

mov bx,handle1 ; input file

mov cx,recsize

mov dx,offset buffer

int 21h

jc bad_read ; jump if read error

or ax,ax ; check bytes transferred

jz file_end ; jump if end of file

.

.

.

mov ah,40h ; sequential write to

mov bx,handle2 ; output file

mov cx,recsize

mov dx,offset buffer

int 21h

jc bad_write ; jump if write error

cmp ax,recsize ; whole record written?

jne disk_full ; jump if disk is full

.

.

.

jmp next ; process next record

.

file_end: . ; reached end of input

.

mov ah,3eh ; close input file

mov bx,handle1

int 21h

.

.

.

mov ah,3eh ; close output file

mov bx,handle2

int 21h

.

.

.

mov ax,4c00h ; exit with return

int 21h ; code of zero

.

.

.

fname1 db 'OLDFILE.DAT',0 ; name of input file

fname2 db 'NEWFILE.DAT',0 ; name of output file

handle1 dw 0 ; token for input file

handle2 dw 0 ; token for output file

buffer db recsize dup (?) ; buffer for file I/O

Figure 8-7. Skeleton of an assembly-language program that performs sequential processing on an input file and writes the results to an output file using the handle file and record functions. This code assumes that the DS and ES registers have already been set to point to the segment containing the buffers and filenames.