. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->汇编语言学习交流区
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  用汇编实现的简单拷贝文件的代码  [待解决] 回复[ 2次 ]   点击[ 488次 ]  
cnhnyu
[帖 主]   [ 发表时间:2007-11-19 15:05 ]   [引用]   [回复]   [ top ] 
荣誉值: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号中断文件操作功能调用。
fishboy
[第1楼]   [ 回复时间:2007-11-20 09:52 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
不错。
mouse
[第2楼]   [ 回复时间:2007-12-03 10:55 ]   [引用]   [回复]   [ top ] 
荣誉值:472
信誉值:12
注册日期:2007-10-16 15:34
顶下,厉害
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved