|
主题 : : 用汇编实现的简单拷贝文件的代码 [待解决] |
回复[ 2次 ]
点击[ 488次 ] | |
荣誉值:0
信誉值:0
注册日期:2007-10-22 14:47 |
该程序用16位汇编实现简单的文件拷贝,代码及说明如下:
; filename: cp.asm
; function: copy file from src to dst
; usage: cp.exe src dst
; 源文件和目标文件的长度都不得超过15个字符,包括路径
data segment
fname1 db 16 dup(0) ; 源文件缓冲区
fname2 db 16 dup(0) ; 目标文件缓冲区
buffer db 32 dup(0) ; 文件内容缓冲区
handle1 dw ? ; 源文件句柄
handle2 dw ? ; 目标文件句柄
msg1 db 'Error !!!', 0dh, 0ah, 24h ; 拷贝失败提示
msg2 db 'OK!!!', 0dh, 0ah, 24h ; 拷贝成功提示
data ends
code segment
assume cs:code, ds:data
main proc far
mov ax, data
mov ds, ax
call getparam ; 获取命令行参数,将源文件和目标文件的名称
mov dx, offset fname1 ; 分别保存在fname1和fname2中
mov ax, 3d00h ; 打开源文件
int 21h
jc abort ; 打开失败,放弃
mov handle1, ax
mov dx, offset fname2
mov ah, 3ch ; 创建目标文件, ds:dx -> filename, cx -> file attribute
xor cx, cx
int 21h
jc abort ; 创建失败,放弃
mov handle2, ax
dup_loop:
mov ah, 3fh ; 读文件
mov cx, 32 ; 一次读32个字节
mov dx, offset buffer ; read 32 bytes to data buffer
mov bx, handle1
int 21h
jc abort ; 读源文件失败,放弃
mov cx, ax ; 将实际读出的字节数放入cx
mov ah, 40h ; 将读出来的内容写入目标文件
mov bx, handle2
int 21h
jc abort ; 写入文件失败,放弃
cmp cx, 32 ; 本次写入的够32个字节吗
jz dup_loop ; 够32个字节,文件还未结束,继续拷贝下面的32个字节
; 不够32个字节,说明已经到了文件末尾
mov ah, 3eh ;
mov bx, handle1 ; 关闭源文件句柄
int 21h
mov bx, handle2 ; 关闭目标文件句柄
int 21h
mov dx, offset msg2 ; 显示拷贝成功信息
mov ah, 9
int 21h
jmp exit
abort:
mov dx, offset msg1 ; 显示拷贝失败信息
mov ah, 9
int 21h
exit:
mov ax, 4c00h
int 21h
main endp
; dos 可执行文件被加载到内存之后, ds, es 均指向256个字节的psp
; psp 是 program segment prefix, 程序段前缀,
; psp 的前2个字节是cd 20, 即 int 20h
; 第80h个字节是命令行参数的个数,从81h开始就是命令行参数
; getparam 过程获取命令行参数,把获得的源文件名称和目标文件名称分别保存在
; 缓冲区fname1和fname2中
getparam proc near
push cx
push si
push di
mov si, 80h
xor ch, ch
mov cl, es:[si] ; 将命令行参数的长度送入cx寄存器
add cx, 80h ; cx保存命令行参数结束的偏移地址
trim_space: ; 压缩源文件名称的前导空格
inc si
mov al, es:[si] ; 命令行参数的下一个字符送入al
cmp al, 20h ; 看看是不是空格
jz trim_space ; 如果是空格,则继续压缩空格
mov di, offset fname1
first_param:
mov al, es:[si]
cmp al, 20h ; 源文件名称和目标文件名称以空格隔开
jz sec_param ; 如果遇到空格,则表明源文件名称拷贝完毕,则准备处理目标文件名称
mov [di], al
inc di
inc si
jmp short first_param
sec_param:
mov di, offset fname2
trim_sp:
inc si
cmp byte ptr es:[si], 20h
jz trim_sp ; 压缩目标文件名称的前导空格
sec_param_loop:
mov al, es:[si]
mov [di], al
cmp si, cx ; 是否到了命令行参数的结尾
jz exit_param ; 到了结尾,则拷贝完毕,退出
cmp byte ptr es:[si], 20h
jz exit_param
inc si
inc di
jmp short sec_param_loop
exit_param:
pop di
pop si
pop cx
ret
getparam endp
code ends
end main
该程序编译成cp.exe,你可以使用cp.exe srcfile dstfile 实现文件的拷贝,比如
cp.exe a.txt b.txt
cp.exe c:\c.txt d:\f.txt
源文件名称和目标文件名称都必须明确指定,可以带路径,也可以不带路径,不带路径时默认当前目录, 文件的路径和名称总长度不得超过15个字符。源文件和目标文件之间以空格分开。
该程序写的比较简单,功能也比较弱,主要是展示了如何利用psp来获得命令行参数以及21h号中断文件操作功能调用。 | | |