从任何文件中读取汇编语言x86,并转义所有特殊字符并获取文件大小(以字节为单位)

3

我有一个学校作业,需要读取大小为128KB的任何文件,并将其内容显示在屏幕上。

我使用3Dh函数打开特定文件,然后使用3Fh函数读取文件。我使用32KB缓冲区来实现它。

我现在遇到了一些问题。

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

当我想获取文件字节数时,它可以正常运行并返回正确结果。
当我想要打印文件内容时,它会输出到出现“$”字符的位置为止的所有内容。因此,我需要以某种方式转义所有特殊字符,例如“$”,以打印整个文件。

  1. 有一个380KB的.csv文件

当我打印它时,它可以完整输出整个文件,共计380KB。
但是,当我想要获取文件大小时,它只返回2186 B。如果我不在过程结尾处关闭文件并再次调用该过程,它将始终以2186 B的倍数(4372、6558等)返回文件大小(字节)。

  1. 我从先前的.csv文件中复制了126KB到另一个文件中

再次打印是可以的(没有“$”字符)。
当我获取大小时,它返回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技术。


可能是dollar-terminated字符串的重复问题。 - nio
1个回答

3
我在您呈现的代码中发现了以下问题:
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

上一行代码不会更新dword变量filesiz!请使用以下代码:

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

提示:您不会检查DOS是否报告错误。访问文件时不应忽视此问题!


1
是的,我知道第一个问题,也知道错误处理。我从这里发布的代码中删除了错误处理。我还使用来自可能重复的问题的代码解决了“转义”$字符的问题。我在字符串的最后一个字节上添加0,除了'$',并逐字节打印缓冲区,直到达到“NULL”。真的很感谢您对DWORD的添加帮助。你让我的一天。 - Gondil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接