Search code examples
assemblytasm16-bit

Assembler (asm) cannot read file


When I run that code:

;-------------------MACRO-----------------
println MACRO info
    push ax
    push dx

    mov ah, 09h
    mov dx, offset info
    int 21h

    ;print new line
    mov dl, 10
    mov ah, 02h
    int 21h

    mov dl, 13
    mov ah, 02h
    int 21h

    pop dx
    pop ax
ENDM
;-----------------end macro----------------
.model small

.stack 100h

.data
sourcePath db "C:\Files\lab5\text.txt"

sourceID dw 0

maxWordSize equ 50
buffer db maxWordSize + 2 dup(0)

startText db "Program is started", '$'
badSourceText db "Cannot open source file", '$'
fileNotFoundText db "File not found", '$'
errorClosingSource db "Cannot close source file", '$'
errorClosingDest db "Cannot close destination file", '$'
endText db "Program is ended", '$'
errorReadSourceText db "Error reading from source file", '$'
errorWritingDestText db "Error writing to destination file", '$'

.code

main:
    mov ax, @data
    mov es, ax
    mov ds, ax

    println startText

    call openFiles
    cmp ax, 0
    jne endMain             ;we have some error

    call processingFile
    cmp ax, 0
    jne endMain             ;we have some error

    call closeFiles
    cmp ax, 0
    jne endMain             ;we have some error

endMain:
    ;exit
    println endText

    mov ah, 4Ch
    int 21h

;Result in ax: 0 if all is good, else not
openFiles PROC
    push bx dx

    ;open source
    mov ah, 3Dh         ;open source file
    mov al, 21h         ;readonly, block write, other cannot write
    mov dx, offset sourcePath
    mov cx, 01h
    int 21h

    jb badOpenSource    ;works when cf = 1

    mov sourceID, ax    ;save file ID

    mov ax, 0           ;return value
    jmp endOpenProc     ;all is good

badOpenSource:
    println badSourceText
    cmp ax, 02h
    jne errorFound

    println fileNotFoundText

errorFound:
    mov ax, 1
endOpenProc:
    pop dx bx
    ret
ENDP

;macro help processing

;bx - file ID
resetPosInFileToStart MACRO
    push ax bx cx dx

    mov ah, 42h
    xor al ,al          ;mov al, 0 - from file start
    xor cx, cx
    xor dx, dx
    int 21h

    pop dx cx bx ax
ENDM
;end macro help

processingFile PROC
    push ax bx cx dx si di

    mov bx, sourceID
    resetPosInFileToStart

    call readFromFile
    cmp ax, 0
    je finishProcessing

    mov si, offset buffer
    mov di, offset buffer
    mov cx, ax                  ;save num of symbols in buffer
    xor dx, dx

finishProcessing:
    pop di si dx cx bx ax
    ret
ENDP

;Result in ax: 0 if all is good, else not
closeFiles PROC
    push bx cx

    xor cx, cx

    mov ah, 3Eh
    mov bx, sourceID
    int 21h

    jnb goodCloseOfSource       ;cf = 0

    println errorClosingSource
    inc cx          ;now it is a counter of errors

goodCloseOfSource:
    mov ax, cx      ;save number of errors

    pop cx bx
    ret
ENDP

;reads to buffer maxWordSize symbols
;RES: ax - how much symbols we read
readFromFile PROC
    push bx cx dx

    mov ah, 3Fh
    mov bx, sourceID
    mov cx, maxWordSize
    mov dx, offset buffer
    int 21h

    jnb goodRead                    ;cf = 0 - we read file

    println errorReadSourceText
    mov ax, 0

goodRead:
    pop dx cx bx
    ret
ENDP

end main

I have that output:

Program is started
Error reading from source file
Program is ended

text.txt contents:

Aenean ut scelerisque lacus, at aliquam ipsum. Aenean et tincidunt felis. Suspendisse volutpat aliquam odio at blandit. Integer vitae ligula consequat, interdum metus nec, venenatis arcu. Integer rhoncus quis felis et maximus. Praesent ac condimentum elit. Nullam a molestie ligula.

I olny want to read this file.
Compiler: TASM 16 bit with DOSBox (and FreeDOS with TASM).
OS: Windows 10 x64 (FreeDOS v1.2 on VirtualBox).

Why it doesn't works?

Update
Error code: I have an error in DOS 3Fh (int 21h)
CF = 1, AL = 05h (access denied). But file is free.


Solution

  • As Jose Manuel Abarca Rodríguez said and then delete answer:

    There are three possible values when opening a file :

    0 = read only.
    1 = write only.
    2 = read/write.
    

    But in your code you are opening the file with the value 21h

    ;Result in ax: 0 if all is good, else not openFiles PROC push bx push dx

    ;open source
    mov ah, 3Dh         ;open source file
    mov al, 21h         ;readonly, block write, other cannot write ◄■■██ As !!!
    mov dx, offset sourcePath
    mov cx, 01h
    int 21h
    
    jb badOpenSource    ;works when cf = 1
    

    Replace that 21h with 0, 1 or 2 :

    mov al, 0

    It's really works. Thank you