flat assembler
Message board for the users of flat assembler.

Index > DOS > File operations in FASM for dos

Author
Thread Post new topic Reply to topic
igob



Joined: 10 Jul 2019
Posts: 3
igob 30 Jan 2024, 12:42
How I can open file and write to in FASM for dos
Post 30 Jan 2024, 12:42
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1161
Location: Russia
macomics 30 Jan 2024, 13:52
Code:
format MZ
segment text
entry text:$

; Prepare
        mov     ax, rwdata
        mov     ds, ax
        mov     es, ax

; open file and read
        mov     dx, fname1 ; dx = offset fname
        mov     ax, $3D00 ; al = 0 - read only, al = 1 - write only, al = 2 - read write
        int     33        ; ah = $3D - open file (ds:dx - file name; al = mode): out ax = fd or cf = 1
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, fbuff ; dx = buffer
        mov     cx, szbuf ; cx = bytes
        mov     bx, [fd]  ; bx = fd
        mov     ah, $40
        int     33        ; ah = $40 - read fd (bx - fd, cx - bytes to read, ds:dx - memory buffer): out ax - readed bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed], ax ; out ax = readed bytes

        mov     bx, [fd]  ; bx = fd
        mov     ah, $3E
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; create file and write
        mov     dx, fname2 ; dx = offset fname
        mov     cx, $20   ; cx = FILE_ATTRIBUTE_NORMAL
        mov     ah, $3C
        int     33        ; ah = $3C - create new file or truncate (dx:dx - file name; cx - attributes): out ax = fd or cf = 1
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, wdata ; dx = offset wdata
        mov     cx, wsize ; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, wsize
        jc      error_end1 ; out ax < wsize - error

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed]; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, [readed]
        jc      error_end1 ; ax < [readed] - error

        mov     bx, [fd]  ; bx = fd
        mov     ah, $3E
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; create new and write, seek and read
        mov     dx, fname3 ; dx = offset fname3
        mov     cx, $20   ; cx = FILE_ATTRIBUTE_NORMAL
        mov     ah, $5D
        int     33        ; ah = $3C - create new file or fail (dx:dx - file name; cx - attributes): out ax = fd or cf = 1 (DOS 3.x +)
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed]; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, [readed]
        jc      error_end1 ; ax < [readed] - error

        mov     dx, wdata ; dx = offset wdata
        mov     cx, wsize ; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, wsize
        jc      error_end1 ; out ax < wsize - error

        mov     dx, -5
        mov     cx, -1    ; cx:dx = offset (-5)
        mov     bx, [fd]
        mov     ax, $4201 ; al = 0 - from begining; al = 1 - from current; al = 2 - from end
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error

        mov     dx, fbuff ; dx = buffer
        mov     cx, szbuf ; cx = bytes
        mov     bx, [fd]  ; bx = fd
        mov     ah, $40
        int     33        ; ah = $40 - read fd (bx - fd, cx - bytes to read, ds:dx - memory buffer): out ax - readed bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed], ax ; out ax = readed bytes

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed] ; cx = bytes to write
        mov     bx, 1     ; bx = fd (0 - stdin, 1 - stdout, 2 - stderr)
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, wsize
        jc      error_end1 ; out ax < wsize - error

        mov     dx, 0
        mov     cx, 0     ; cx:dx = offset (0)
        mov     bx, [fd]
        mov     ax, $4202 ; al = 0 - from begining; al = 1 - from current; al = 2 - from end
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [fsize.l],ax ; out ax - offset low
        mov     [fsize.h],dx ; out dx - offset high

        mov     dx, 0
        mov     cx, 0     ; cx:dx = offset (0)
        mov     bx, [fd]
        mov     ax, $4200 ; al = 0 - from begining; al = 1 - from current; al = 2 - from end
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error
        or      ax, dx
        jnz     error_end1 ; dx:ax != 0 - error

        cmp     [fsize.h], 0
        jnz     @f
        cmp     [fsize.l], szbuf
        ja      @f
        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [fsize.l]; cx = bytes to write
        mov     bx, [fd]  ; bx = fd (0 - stdin, 1 - stdout, 2 - stderr)
        mov     ah, $3F
        int     33        ; ah = $3F - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed],ax ; out ax = readed bytes
  @@:

        mov     bx, [fd]  ; bx = fd
        mov     ah, $3E
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; End of program
        mov     ax, $4C00
        int     33        ; ah = $4C - exit to DOS (al - exit code): doesn't return

; close fd when error
error_end1:
        mov     bx, [fd]  ; bx = fd
        mov     ah, $3E
        int     33        ; ah = $3E - close fd (bx - fd)

error_end:
        mov     ax, $4C01
        int     33        ; ah = $4C - exit to DOS (al - exit code): doesn't return

segment rwdata
fname1  db 'read.txt', 0
fname2  db 'write.txt', 0
fname3  db 'new.txt', 0
wdata   db 'Hello world!'
align 4
label fsize dword
.l      dw ?
.h      dw ?
fd      dw ?
readed  dw ?
wsize   = $ - wdata
szbuf   = 512
fbuff   rb szbuf    
Post 30 Jan 2024, 13:52
View user's profile Send private message Reply with quote
igob



Joined: 10 Jul 2019
Posts: 3
igob 30 Jan 2024, 14:46
Where I can see the created files. I work with dosbox-x and fasm 1.73.32 for dos
Post 30 Jan 2024, 14:46
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1161
Location: Russia
macomics 30 Jan 2024, 15:45
Code:
format MZ
segment text
entry text:$

PRINT_STR = $09
EXIT_SUCCESS = $4C00
EXIT_FAILED = $4C01
FILE_CREATE_OR_TRUNCATE = $3C
FILE_OPEN_READ = $3D00
FILE_OPEN_WRITE = $3D01
FILE_OPEN_READ_WRITE = $3D02
FILE_CLOSE = $3E
FILE_READ = $3F
FILE_WRITE = $40
FILE_SEEK_FROM_BEGINING = $4200
FILE_SEEK_FROM_CURRENT = $4201
FILE_SEEK_FROM_END = $4202
FILE_ONLY_CREATE_NEW = $5B

; Prepare
        mov     ax, rwdata
        mov     ds, ax
        mov     es, ax

; open file and read
        mov     dx, fname1 ; dx = offset fname
        mov     ax, FILE_OPEN_READ ; al = 0 - read only, al = 1 - write only, al = 2 - read write
        int     33        ; ah = $3D - open file (ds:dx - file name; al = mode): out ax = fd or cf = 1
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, fbuff ; dx = buffer
        mov     cx, szbuf ; cx = bytes
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_READ
        int     33        ; ah = $3F - read fd (bx - fd, cx - bytes to read, ds:dx - memory buffer): out ax - readed bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed], ax ; out ax = readed bytes

        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_CLOSE
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; create file and write
        mov     dx, fname2 ; dx = offset fname
        mov     cx, $20   ; cx = FILE_ATTRIBUTE_NORMAL
        mov     ah, FILE_CREATE_OR_TRUNCATE
        int     33        ; ah = $3C - create new file or truncate (dx:dx - file name; cx - attributes): out ax = fd or cf = 1
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, wdata ; dx = offset wdata
        mov     cx, wsize ; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_WRITE
        int     33        ; ah = $40 - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, wsize
        jc      error_end1 ; out ax < wsize - error

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed]; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_WRITE
        int     33        ; ah = $40 - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, [readed]
        jc      error_end1 ; ax < [readed] - error

        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_CLOSE
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; create new and write, seek and read
        mov     dx, fname3 ; dx = offset fname3
        mov     cx, $20   ; cx = FILE_ATTRIBUTE_NORMAL
        mov     ah, FILE_ONLY_CREATE_NEW
        int     33        ; ah = $5B - create new file or fail (dx:dx - file name; cx - attributes): out ax = fd or cf = 1 (DOS 3.x +)
        jc      error_end ; cf = 1 - error
        mov     [fd], ax  ; out ax = fd

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed]; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_WRITE
        int     33        ; ah = $40 - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, [readed]
        jc      error_end1 ; ax < [readed] - error

        mov     dx, wdata ; dx = offset wdata
        mov     cx, wsize ; cx = bytes to write
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_WRITE
        int     33        ; ah = $40 - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, wsize
        jc      error_end1 ; out ax < wsize - error

        mov     dx, -5
        mov     cx, -1    ; cx:dx = offset (-5)
        mov     bx, [fd]
        mov     ax, FILE_SEEK_FROM_CURRENT
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode: 0 - from begining, 1 - from current, 2 - from end): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error

        mov     dx, fbuff ; dx = buffer
        mov     cx, szbuf ; cx = bytes
        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_READ
        int     33        ; ah = $3F - read fd (bx - fd, cx - bytes to read, ds:dx - memory buffer): out ax - readed bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed], ax ; out ax = readed bytes

        mov     dx, fbuff ; dx = offset wdata
        mov     cx, [readed] ; cx = bytes to write
        mov     bx, 1     ; bx = fd (0 - stdin, 1 - stdout, 2 - stderr)
        mov     ah, FILE_WRITE
        int     33        ; ah = $40 - write fd (bx - fd, cx - bytes to write, ds:dx - memory block): out ax = writen bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        cmp     ax, [readed]
        jc      error_end1 ; out ax < wsize - error

        mov     dx, 0
        mov     cx, 0     ; cx:dx = offset (0)
        mov     bx, [fd]
        mov     ax, FILE_SEEK_FROM_END
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode: 0 - from begining, 1 - from current, 2 - from end): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [fsize.l],ax ; out ax - offset low
        mov     [fsize.h],dx ; out dx - offset high

        mov     dx, 0
        mov     cx, 0     ; cx:dx = offset (0)
        mov     bx, [fd]
        mov     ax, FILE_SEEK_FROM_BEGINING
        int     33        ; ah = $42 - seek fd (bx - fd, cx:dx - offset. al - seek mode: 0 - from begining, 1 - from current, 2 - from end): out dx:ax = offset or cf = 1
        jc      error_end1 ; cf = 1 - error
        or      ax, dx
        jnz     error_end1 ; dx:ax != 0 - error

        cmp     [fsize.h], 0
        jnz     @f
        cmp     [fsize.l], szbuf
        ja      @f
        mov     dx, fbuff ; dx = offset fbuff
        mov     cx, szbuf; cx = bytes
        mov     bx, [fd]  ; bx = fd (0 - stdin, 1 - stdout, 2 - stderr)
        mov     ah, FILE_READ
        int     33        ; ah = $3F - read fd (bx - fd, cx - bytes to read, ds:dx - memory buffer): out ax - readed bytes or cf = 1
        jc      error_end1 ; cf = 1 - error
        mov     [readed],ax ; out ax = readed bytes
  @@:

        mov     bx, [fd]  ; bx = fd
        mov     ah, FILE_CLOSE
        int     33        ; ah = $3E - close fd (bx - fd)
        jc      error_end ; cf = 1 - error

; End of program
        mov     dx, exitok
        mov     ah, PRINT_STR
        int     33
        mov     ax, EXIT_SUCCESS
        int     33

; close fd when error
error_end1:
        mov     bx, [fd]
        mov     ah, FILE_CLOSE
        int     33

error_end:
        mov     dx, errort
        mov     ah, PRINT_STR
        int     33
        mov     ax, EXIT_FAILED
        int     33

segment rwdata
fname1  db 'READ.TXT', 0
fname2  db 'WRITE.TXT', 0
fname3  db 'NEW.TXT', 0
exitok  db 13, 10, 'Done: EXIT_SUCCESS$'
errort  db 13, 10, 13, 10, 'Bad end: EXIT_FAILED$'
wdata   db 'Hello world!'
wsize   = $ - wdata
align 4
label fsize dword
.l      dw ?
.h      dw ?
fd      dw ?
readed  dw ?
szbuf   = 512
fbuff   rb szbuf    
Fixed errors in the function numbers.

To run it, you need to have file "READ.TXT" next to the program and there was some data in this file. The program consistently uses some functions:

  • Opens the file (fname1 = "READ.TXT") to reads, reads a certain number of bytes from it, and then closes it.
  • Creates (or truncates an existing file to zero length) (fname2 = "WRITE.TXT") file, writes a constant string to it, then the block read from the first file and closes it.
  • Creates a new (fname3 = "NEW.TXT") file, but if it exists, it just exited with an error. Write it down, read from READ.TXT, block to file NEW.TXT and then a constant string from the program.
    After that, we step back from the current position by 5 bytes, read them from the file and display them on the screen (using the same file function).
    Then we calculate the length of the file and go to the beginning of it. Close file and exit to DOS without an error code (ExitCode = 0).


Function calls in program text are separated from each other by an empty line. Error handling is added at the end of each call (after int 33). If an error occurs in any of functions, program immediately terminates with an error (ExitCode = 1).

I added the output of two messages before exiting the program accordingly and now it will not leave an empty console when exiting with an error.
Post 30 Jan 2024, 15:45
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1161
Location: Russia
macomics 30 Jan 2024, 17:01
This is how the program works in DOSBox
Post 30 Jan 2024, 17:01
View user's profile Send private message Reply with quote
bitdog2u



Joined: 31 Jan 2023
Posts: 30
Location: Ketchikan, Alaska
bitdog2u 04 Jun 2025, 22:22
Code:
FNAME DB "OUTfile.txt",0 ; nul ending ASCIZ file name

        FCREATAOm FNAME         ; Create+Overwrite Archive
        JC      ERROR
        MOV     [FHAND],AX      ; save File handle
        FWRITE3m AX,[BUF2size],[BUF2adr]
        JC      ERROR
        FCLOSEm [FHAND]

        FOPENRm FNAME
        JC  ERROR                ; File doesn't exist
        MOV   [FHAND],AX         ; Save file handle
        FREAD3m AX,BUF1size,BUF1adr
        JC  ERROR                ; this never happens. If AX=0 File is read to EOF already, move file ptr?
        MOV [BUF1data],AX        ; bytes read in
        CMP AX,BUF1size          ; if data read = data request, there is more data in the file to read
        JZ @F                    ; Not read to EOF yet?
        FCLOSEm [FHAND]          ; got the data at BUF1adr: sizeOF [BUF1data]
        MOV word [FHAND],0       ; zero out file handle marks it as closed
@@:

    

Using macro's you can have clean looking code.
The downside of .ASM programming is all the clutter ones mind has to sift through to have a working overview of the code,
and these macro's kinda clean that up, and makes the writing simplified since they are their own comment.
Well, I hope this helps.


Description: FASM macro's for USE16 file OPEN,CLOSE,CREATE, READ,WRITE.
Download
Filename: AFILE.ZIP
Filesize: 2.48 KB
Downloaded: 59 Time(s)



Last edited by bitdog2u on 12 Jun 2025, 02:49; edited 2 times in total
Post 04 Jun 2025, 22:22
View user's profile Send private message Reply with quote
bitdog2u



Joined: 31 Jan 2023
Posts: 30
Location: Ketchikan, Alaska
bitdog2u 12 Jun 2025, 02:02
WOW, I didn't know that little aFILE.ZIP would be so popular so quick.
So here is what I could find for file manipulation macros in my
c:\FASM\inc16\ directory.
Sorry I didn't clean it up and check it all out first, so
post your complaints here and I'll try to get you all fixed up.

bitdog2u

PS, if I remember correctly,
I checked out and used them all at one point in time.
But, to use them you have to have a clue as to what you are doing.
But #2, just viewing them can give you an idea of what is possible,
and what info to start looking for.


Description: All my FASM FILE macro's for USE16
Download
Filename: FILEMACS.ZIP
Filesize: 15.63 KB
Downloaded: 11 Time(s)

Post 12 Jun 2025, 02:02
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.