下面是一个完整的.SYS的源程序,用中文详细注释,用途在其中有清楚说明。
title ECHO - 通过设备驱动程序完成简单任务
; (c)2005 版权所有
; 罗明安(本是)
;
lmayylxt@pub.sz.jsinfo.net
; 本MS-DOS设备驱动程序用于 CONFIG.SYS:
; device=echo.sys 参数
; MS-DOS 5以上的版本在用户设备驱动程序收到参数之前已经将其大写
; 所以本程序的任务就是:
; 1.将" "内的参数小写
; 2.临时需要的单个大写字母用^引导,如:
; device=echo.sys H"I. ^T"HIS IS A SAMPLE STRING FOR" MS-DOS CONFIG.SYS.
; 上一行将显示为:
; Hi. This is a sample string for MS-DOS CONFIG.SYS.
CR equ 13 ; 回车
LF equ 10 ; 换行
; MS-DOS 请求定义
Request struc
Rlength db ? ;+0 长度
Unit db ? ; 1 单元
Command db ? ; 2 命令
Status dw ? ; 3 状态
Reserve db 8 dup(?) ; 5 保留
Media db ? ; 0D 介质
Addroff dw ? ; 0E 偏移地址
Addrseg dw ? ; 10 段地址
Nameoff dw ? ; 12 名称偏移地址/计数器
Nameseg dw ? ; 14 名称段地址/扇区
Request ends
DevD segment word
header label word
dw -1,-1
dw 0000h ;空设备;/字符/块设备
dw offset init ;/策略=初始化而不安装任何东西
dw offset interrupt ;/命令
db 1,7 dup(0) ; /'设备名称'
; 总是最先执行
interrupt proc far
xor ax,ax
ret
interrupt endp
init_msg:
db CR, LF, 'ECHO v1.0', CR, LF
db ' (C)2005 版权所有 罗明安(本是)'
db ' e-mail:
lmayylxt@pub.sz.jsinfo.net', CR, LF, '$'
; 执行部分从此开始
; es:bx 指向请求头
init proc far
assume cs: DevD, ds: DevD
mov dx, offset init_msg
mov ah, 9
int 21h
mov di, bx
push di
push es
mov si, es: ; config.sys中设备名称偏移址
mov ds, es: ; config.sys中设备名称段地址
; 跳过设备名称前的空格
trim_beginning:
lodsb
cmp al, ' '
jbe trim_beginning
; 跳过设备名(转成大写)
find_driver:
lodsb
cmp al, ' '
ja find_driver
; 跳过尾随的空格
trim_end:
lodsb
cmp al, ' '
jbe trim_end
dec si ; si 已经越过第一个字符
; ds:si 现在指向命令行参数或回车符如果无参数
;;用户任务在此!
echo_: ;大小写=UPPER"lo^Wer"UPPER
xor bx,bx ;清引号标志
lodsb
cmp al,' '
jnz cmpOthers
jmp short echo_1
echo_1:
lodsb ;如为回车, 退出
cmpOthers:
cmp al,0Dh
jbe echo_4
cmp al,'"' ;测双引号
jne echo_2
not bl ;开引号标志
cmp byte ptr ds:,'"'
jne echo_1
inc si ;跳过多余引号
not bl ;关引号标志
jmp echo_3
echo_2:
or bl,bl ;看是否在引号内
je echo_3
cmp al,"^" ;是暂时的单个大写吗?
jnz ifUpper
lodsb
cmp al,0Dh
jbe echo_4
and al,0DFh ;转大写
jmp short echo_3
ifUpper:
cmp al,'A' ;比'A'?
jb echo_3 ;小,直接显示
cmp al,'Z' ;比'Z'?
ja echo_3 ;大,直接显示
or al,20h ;转小写
echo_3:
mov ah,2 ;字符显示
mov dl,al
int 21h
jmp short echo_1
echo_4:
mov ah,2 ;字符显示
mov dl,0dh ;换行回车
int 21h
mov dl,0ah
int 21h
echo_exit:
mov ax,0100h ;完成
jmp short done
quit:
mov ax,8103h ;出错
done:
pop es
pop di
mov byte ptr es:, 0 ; 安装0个单元
mov word ptr es:, 0 ; 空闲内存偏移址 = 0
mov es:, cs ; 空闲内存段地址
mov word ptr es:, ax ; 返回代码 = 8000h : 设置出错码
ret ; + 100h : 完成
; + 3h : 未知错
init endp
DevD ends
end