Files and how to use them

Files can be opened, read and written to. DOS has some ways of doing this which save us the trouble of writing our own routines. Yes, more interrupts. Here is a list of helpful functions of interrupt 21h that deal with files.

Note: Bits are numbered from right to left.

Function 3Dh: open file
Opens an existing file for reading, writing or appending on the specified drive and filename.

INPUT:

AH = 3Dh
AL = bits 0-2 Access mode

bits 4-6 Sharing mode (DOS 3+) DS:DX = segment:offset of ASCIIZ pathname

OUTPUT:

CF = 0 function is succesful
AX = handle
CF = 1 error has occured
AX = error code

What does ASCIIZ mean? An ASCIIZ string like a ASCII string with a zero on the end instead of a dollar sign.

Important: Remember to save the file handle it is needed for later.

How to save the file handle

It is important to save the file handle because this is needed to do anything with the file. Well how is this done? There are two methods we could use: copy the file handle into another register and don't use that register or copy it to a variable in memory.

The disadvantages with the first method is that you will have to remember not to use the register you saved it in and it wastes a register that can be used for something more useful. We are going to use the second. This is how it is done:

FileHandle DW 0 	; use this for saving the file handle

.

.

.

mov FileHandle,ax 	; save the file handle

Function 3Eh: close file
Closes a file that has been opened.

INPUT:

AX = 3Eh
BX = file handle

OUTPUT:

CF = 0 function is successful
AX = destroyed
CF = 1 function not successful
AX = error code - 06h file not opened or unauthorised handle.

Important: Don't call this function with a zero handle because that will close the standard input (the keyboard) and you won't be able to enter anything.

Function 3Fh: read file/device

Reads bytes from a file or device to a buffer.

INPUT:

AH = 3Fh
BX = handle
CX = number of bytes to be read
DS:DX = segment:offset of a buffer

OUTPUT:

CF = 0 function is successful
AX = number of bytes read
CF = 1 an error has occurred

If CF = 0 and AX = 0 then the file pointer was already at the end of the file and no more can be read. If CF = 0 and AX is smaller than CX then only part was read because the end of the file was reached or an error occurred.

This function can also be used to get input from the keyboard. Use a handle of 0, and it stops reading after the first carriage return, or once a specified number of characters have been read. This is a good and easy method to use to only let the user enter a certain amount of characters.

Listing 7: READFILE.ASM



; a program to demonstrate creating a file and then reading from

; it



.model small

.stack

.code 



mov ax,@data 		; base address of data segment

mov ds,ax 		; put this in ds



mov dx,OFFSET FileName 	; put address of filename in dx 

mov al,2 		; access mode - read and write

mov ah,3Dh 		; function 3Dh -open a file

int 21h 		; call DOS service



mov Handle,ax 		; save file handle for later

jc ErrorOpening 	; jump if carry flag set - error!



mov dx,offset Buffer 	; address of buffer in dx

mov bx,Handle 		; handle in bx

mov cx,100 		; amount of bytes to be read

mov ah,3Fh 		; function 3Fh - read from file

int 21h 		; call dos service



jc ErrorReading 	; jump if carry flag set - error! 



mov bx,Handle 		; put file handle in bx 

mov ah,3Eh 		; function 3Eh - close a file

int 21h 		; call DOS service



mov cx,100 		; length of string

mov si,OFFSET Buffer 	; DS:SI - address of string

xor bh,bh 		; video page - 0

mov ah,0Eh 		; function 0Eh - write character



NextChar:



lodsb 			; AL = next character in string

int 10h 		; call BIOS service

loop NextChar



mov ax,4C00h 		; terminate program 

int 21h 



ErrorOpening:



mov dx,offset OpenError ; display an error 

mov ah,09h 		; using function 09h

int 21h 		; call DOS service

mov ax,4C01h 		; end program with an errorlevel =1 

int 21h 



ErrorReading:

mov dx,offset ReadError ; display an error 

mov ah,09h 		; using function 09h

int 21h 		; call DOS service

mov ax,4C02h 		; end program with an errorlevel =2 

int 21h



.data

Handle DW ? 			; to store file handle 

FileName DB "C:\test.txt",0 	; file to be opened

OpenError DB "An error has occured(opening)!$"

ReadError DB "An error has occured(reading)!$"

Buffer DB 100 dup (?) 	; buffer to store data



END

Function 3Ch: Create file

Creates a new empty file on a specified drive with a specified pathname.

INPUT:

AH = 3Ch
CX = file attribute

bit 0 = 1 read-only file
bit 1 = 1 hidden file
bit 2 = 1 system file
bit 3 = 1 volume (ignored)
bit 4 = 1 reserved (0) - directory
bit 5 = 1 archive bit
bits 6-15 reserved (0)
DS:DX = segment:offset of ASCIIZ pathname

OUTPUT:

CF = 0 function is successful
AX = handle
CF = 1 an error has occurred

03h path not found
04h no available handle
05h access denied

Important: If a file of the same name exists then it will be lost. Make sure that there is no file of the same name. This can be done with the function below.

Function 4Eh: find first matching file

Searches for the first file that matches the filename given.

INPUT:

AH = 4Eh CX = file attribute mask (bits can be combined)

bit 0 = 1 read only
bit 1 = 1 hidden
bit 2 = 1 system
bit 3 = 1 volume label
bit 4 = 1 directory
bit 5 = 1 archive
bit 6-15 reserved
DS:DX = segment:offset of ASCIIZ pathname

OUTPUT:

CF = 0 function is successful
[DTA] Disk Transfer Area = FindFirst data block

The DTA block:

Offset   Size in bytes   Meaning



0        21              Reserved

21       1               File attributes

22       2               Time last modified

24       2               Date last modified

26       4               Size of file (in bytes)

30       13              File name (ASCIIZ)



An example of checking if file exists:
File DB "C:\file.txt",0	  ; name of file that we want

mov dx,OFFSET File 	  ; address of filename

mov cx,3Fh 		  ; file mask 3Fh - any file

mov ah,4Eh 		  ; function 4Eh - find first file

int 21h 		  ; call DOS service



jc NoFile



; print message saying file exists



NoFile:



; continue with creating file

This is an example of creating a file and then writing to it.
Listing 8: CREATE.ASM

; This example program creates a file and then writes to it.

.model small

.stack

.code 



mov ax,@data 	; base address of data segment

mov ds,ax 	; put it in ds

mov dx,offset StartMessage 

mov ah,09h 

int 21h 



mov dx,offset FileName 	; put offset of filename in dx 

xor cx,cx 		; clear cx - make ordinary file

mov ah,3Ch 		; function 3Ch - create a file

int 21h 		; call DOS service



jc CreateError 		; jump if there is an error



mov dx,offset FileName 	; put offset of filename in dx

mov al,2 		; access mode -read and write

mov ah,3Dh 		; function 3Dh - open the file

int 21h 		; call dos service



jc OpenError 		; jump if there is an error

mov Handle,ax 		; save value of handle 



mov dx,offset WriteMe 	; address of information to write 

mov bx,Handle 		; file handle for file

mov cx,38 		; 38 bytes to be written

mov ah,40h 		; function 40h - write to file

int 21h 		; call dos service



jc WriteError 		; jump if there is an error

cmp ax,cx 		; was all the data written?

jne WriteError 		; no it wasn't - error!



mov bx,Handle 		; put file handle in bx 

mov ah,3Eh 		; function 3Eh - close a file

int 21h 		; call dos service



mov dx,offset EndMessage 

mov ah,09h 

int 21h 



ReturnToDOS:



mov ax,4C00h 		; terminate program 

int 21h 



WriteError:

mov dx,offset WriteMessage 

jmp EndError



OpenError:

mov dx,offset OpenMessage 

jmp EndError



CreateError:

mov dx,offset CreateMessage 



EndError:

mov ah,09h 

int 21h 

mov ax,4C01h 

int 21h 



.data 

CR equ 13

LF equ 10



StartMessage DB "This program creates a file called NEW.TXT"

	     DB ,"on the C drive.$"



EndMessage DB CR,LF,"File create OK, look at file to"

	   DB ,"be sure.$"



WriteMessage  DB "An error has occurred (WRITING)$"

OpenMessage   DB "An error has occurred (OPENING)$"

CreateMessage DB "An error has occurred (CREATING)$"



WriteMe  DB "HELLO, THIS IS A TEST, HAS IT WORKED?",0

FileName DB "C:\new.txt",0 ; name of file to open 

Handle   DW ? 	; to store file handle 



END

This is an example of how to delete a file after checking it exists:
Listing 9: DELFILE.ASM ; a demonstration of how to delete a file. The file new.txt on ; c: is deleted (this file is created by create.exe). We also ; check if the file exits before trying to delete it .model small .stack .data CR equ 13 LF equ 10 File db "C:\new.txt",0 Deleted db "Deleted file c:\new.txt$" NoFile db "c:\new.txt doesn't exits - exiting$" ErrDel db "Can't delete file - probably write protected$" .code mov ax,@data mov ds,ax mov dx,OFFSET File ; address of filename to look for mov cx,3Fh ; file mask 3Fh - any file mov ah,4Eh ; function 4Eh - find first file int 21h ; call dos service jc FileDontExist mov dx,OFFSET File ; DS:DX points to file to be killed mov ah,41h ; function 41h - delete file int 21h ; call DOS service jc ErrorDeleting ; jump if there was an error mov dx,OFFSET Deleted ; display message jmp Endit ErrorDeleting: mov dx,OFFSET ErrDel jmp Endit FileDontExist: mov dx,OFFSET NoFile EndIt: mov ah,9 int 21h mov ax,4C00h ; terminate program and exit to DOS int 21h ; call DOS service end

Using the FindFirst and FindNext Functions

Listing 10: DIRC.ASM



; this program demonstrates how to look for files. It prints

; out the names of all the files in the c:\drive and names of

; the sub-directories



.model small

.stack

.data



FileName db "c:\*.*",0 ;file name

DTA 	 db 128 dup(?) ;buffer to store the DTA 

ErrorMsg db "An Error has occurred - exiting.$"



.code



mov ax,@data 	; set up ds to be equal to the 

mov ds,a 	; data segment

mov es,ax 	; also es



mov dx,OFFSET DTA 	; DS:DX points to DTA 

mov ah,1AH 		; function 1Ah - set DTA

int 21h 		; call DOS service



mov cx,3Fh 		; attribute mask - all files

mov dx,OFFSET FileName 	; DS:DX points ASCIZ filename

mov ah,4Eh 		; function 4Eh - find first

int 21h 		; call DOS service



jc error 	; jump if carry flag is set



LoopCycle:



mov dx,OFFSET FileName 	; DS:DX points to file name

mov ah,4Fh 		; function 4fh - find next

int 21h 		; call DOS service



jc exit 	; exit if carry flag is set



mov cx,13 		; length of filename

mov si,OFFSET DTA+30 	; DS:SI points to filename in DTA

xor bh,bh 		; video page - 0

mov ah,0Eh 		; function 0Eh - write character



NextChar:



lodsb 		; AL = next character in string

int 10h 	; call BIOS service



loop NextChar



mov di,OFFSET DTA+30 	; ES:DI points to DTA

mov cx,13 		; length of filename

xor al,al 		; fill with zeros

rep stosb 		; erase DTA



jmp LoopCycle 	; continue searching



error: 



mov dx,OFFSET ErrorMsg 	; display error message

mov ah,9

int 21h



exit:



mov ax,4C00h 	; exit to DOS

int 21h



end

Return to Table of Contents