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: 1042
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: 1042
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: 1042
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
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.