程序集 x86 从任何文件读取并转义所有特殊字符并获取文件大小(以字节为单位)

Assembly x86 read from any file and escape all special characters and get size of file in Bytes

我有学校布置的作业。我必须读取任何大小为 128KB 的文件并将其内容写在屏幕上。

我使用函数 3Dh 打开特定文件,然后使用函数 3Fh 读取文件。我为此使用了 32KB 缓冲区。

我现在遇到的问题很少。

  1. 有 59KB 的 .txt 文件,其中包含书中的一些文本以及我的一些代码。

当我想要以字节为单位获取文件大小时,它运行良好并且结果是正确的。
当我想打印文件的内容时,它会将所有内容打印到文件中出现“$”字符的位置。所以我需要以某种方式转义所有特殊字符,因为“$”是打印整个文件和任何文件。

  1. 有 380KB .csv 文件

当我打印它时,它打印得很好,整个文件,全部 380KB。
但是,当我想获得大小时,它 returns 只是 2186 B。当我不在过程结束时关闭文件并一次又一次地调用这个过程时,它 returns 总是以字节为单位大小2186 B 的倍数(4372、6558 等)。

  1. 我从之前的 .csv 复制了 126KB 到另一个

再次打印正常(没有“$”字符)。
当我得到尺寸时 returns 64063 B 所以又是错误的结果。

这是我的程序。

buffsiz equ 32768                   ;buffer size =32KB
fnsize  equ 255                     ;filename size =255

data    segment
maxlen  db  fnsize                  ;max length of file name
len     db  ?                       ;length of filename
file    db  fnsize  dup (?)         ;file name
filesiz dd  ?                       ;dword variable of file size
buffer  db  buffsiz dup ('$')       ;32KB buffer
        ;...
data    ends

getcont proc                        ;get content of file procedure
        mov ah,3dh                  ;open file function
        mov al,0                    ;read-access bit
        call forout                 ;just bring 0 char on the end of filename
        mov dx,offset file          ;"move filename" to dx
        int 21h

        mov bx,ax                   ;move filehandler from ax to bx
buffIn: prntstr buffer              ;print content of buffer (in first iteration it is whole set to '$'
        mov ah,3fh                  ;read from file
        mov cx,buffsiz              ;how much bytes it should read from file (32768)
        mov dx,offset buffer
        int 21h

output: xchg ax,bx                  ;exchange values in ax and bx
        mov buffer[bx],'$'          ;after last read byte put '$' into buffer
        xchg ax,bx                  ;exchange registers back for next iteration
        cmp ax,0                    ;if there was no read byte stop loop
        jnz buffIn                  ;if was go to next iteration

        mov ah,3Eh                  ;close file
        int 21h

        ret
getcont endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

getsize proc
        mov word ptr[filesiz],0      ;put zero into filesize variable (dword)
        mov word ptr[filesiz]+2,0

        mov ah,3dh                  ;same as in getcont procedure
        mov al,0                    
        call forout
        mov dx,offset file          
        int 21h     

        mov bx,ax                   
bufflp: mov ah,3fh                  
        mov cx,buffsiz              
        mov dx,offset buffer
        int 21h

        add word ptr[filesiz],ax    ;add number of bytes read into filesiz variable - not certain in this
        cmp ax,0                    ;if there was no byte read end loop
        jnz bufflp                  ;if was go to next iteration

        prntstr nl                  ;new line
        prntstr velkost             ;print string about file size operation
        xor dx,dx                   ;clear ax and dx registers
        xor ax,ax
        mov ax,word ptr[filesiz]    ;move low word from filesiz(dword) variable to ax
        mov dx,word ptr[filesiz]+2  ;move high word from filesiz to dx to get filesiz=dx:ax
        call prntint                ;call procedure to print decimal number on output
        prntchr ' '                 ;print space
        prntchr 'B'                 ; print Byte unit char

        mov ah,3Eh                  ;close file
        int 21h

        ret
getsize endp

使用 TASM 程序集 x86。

我在您提供的代码中发现了这些问题:

mov buffer[bx],'$'          ;after last read byte put '$' into buffer

您应该将缓冲区扩大 1 个字节。现在,当读取了 32768 个字节时,您正在将此 $ 写入缓冲区!

add word ptr[filesiz],ax    ;add number of bytes read into filesiz variable

上一行不会更新双字变量filesiz!使用以下

add word ptr[filesiz],ax
adc word ptr[filesiz]+2,0

ps。您永远不会检查 DOS 是否报告错误。访问文件时不要忽视这一点!