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

Posted

技术标签:

【中文标题】汇编 x86 从任何文件读取并转义所有特殊字符并以字节为单位获取文件大小【英文标题】:Assembly x86 read from any file and escape all special characters and get size of file in Bytes 【发布时间】:2015-03-22 10:39:47 【问题描述】:

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

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

我现在面临的问题很少。

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

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

    拥有 380KB 的 .csv 文件

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

    我将 126KB 从以前的 .csv 复制到另一个

再次打印没问题(没有“$”字符)。 当我得到大小时,它返回 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 strings的可能重复 【参考方案1】:

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

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

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

【讨论】:

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

以上是关于汇编 x86 从任何文件读取并转义所有特殊字符并以字节为单位获取文件大小的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQLAlchemy 转义文件路径中的特殊字符

可以在x86汇编中使用IN(以及INS,INSB等)指令块吗?

使用 Jackson/Java 来确保 JSON 的所有序列化在单引号或双引号内分隔不受信任的数据会转义任何特殊字符?

正则中需要转义的特殊字符小结

如何在 x86 汇编中编写自己的 atoi 函数

无需 unicode 转义即可读写 Java 属性