汇编 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 从任何文件读取并转义所有特殊字符并以字节为单位获取文件大小的主要内容,如果未能解决你的问题,请参考以下文章
可以在x86汇编中使用IN(以及INS,INSB等)指令块吗?