本人是菜鸟 ,希望高手不要讥讽我
;编写一个类似于dos内部命令type的小型使用程序。通过命令行选项(空格+more),可以指示是否进行分屏显示
;格式 : 路径+type+空格(无论几个)+路径+显示文件名(可以+空格【随便几个】+more)
;DOS命令 Type 能:显示ASCII码文件的内容。
; 类型:内部命令。
; 格式:Type[盘符:][路径]〈文件名〉
; 使用说明:
; (1)显示由ASCII码组成的文本文件,对。EXE.COM等为扩展名的文件;,其显示的内容是无法阅读的,没有实际意义2;
; (2)该命令一次只可以显示一个文件的内容,不能使用通配符;
; (3)如果文件有扩展名,则必须将扩展名写上;
; (4)当文件较长,一屏显示不下时,可以按以下格式显示;TYPE[盘;符:][路径]〈文件名〉|MORE,MORE为分屏显示命令,使用些参数后当满;;屏时会暂停,按任意键会继续显示。
eof =1ah
data segment
mess1 db 'Required parameter missing!!$'
mess2 db 'The file can not open!!$'
mess3 db 'Read error!!$'
mess4 db '-- more --$'
file_buff db 128 dup (0);命令行参数最长为127,最后还需要加0,以构成dos功能调用所需的文件名
file_num dw ?
file_read db ?
page_num db ?
line_num db ?
data ends
stack segment
stack_buff db 256 dup (0)
stack ends
code segment
assume cs:code,ds:data,ss:stack
main: mov ax,stack
mov ss,ax
mov sp,size stack_buff;设置全局堆栈
call get_ready
jc go_read1
call read_file2
jmp mainover
go_read1: call read_file1
mainover: mov ax,4c00h
int 21h
;读取文件,file_buff存放的文件名的文件,并以带分屏命令显示出来文件内容
read_file1 proc
push ax
push bx
push cx
push dx
push ds
mov ax,data
mov ds,ax
mov ah,0fh
int 10h ;取显示模式
mov page_num,bh ;保存当前页号
mov line_num,ah;保存最大列号
mov ah,3dh
mov dx,offset file_buff
mov al,0 ;读方式打开文件
int 21h
jnc open_suc1 ;cf=0则打开成功
mov dx,offset mess2
mov ah,9
int 21h ;显示文件打开失败提示信息
jmp read1_over
open_suc1: mov file_num,ax ;保存文件号
mov ah,6 ;清屏
mov al,0
mov bh,7
xor cx,cx
mov dh,24
mov dl,line_num
int 10h
mov ah,2 ;光标置左上角
mov bh,page_num
xor dx,dx
int 10h
read1_again: mov bx,file_num
mov cx,1
mov dx,offset file_read
mov ah,3fh
int 21h
jc read1_error ;cf等于1表示读取文件失败
cmp ax,0 ;判断是否读取结束
je file_close1
mov ah,3
mov bh,page_num
int 10h;读光标位置
cmp dh,24 ;看是否显示显示到了最后行
je upmov_dis
goon_dis: mov dl,file_read
mov ah,2
int 21h ;显示
jmp read1_again
upmov_dis: mov ah,9
mov dx,offset mess4
int 21h ;显示 more
mov ah,1
int 16h ;判断键盘缓冲区有无字符
jz dis_begin
mov ah,0
int 16h
jmp upmov_dis ;取走一个字符继续查看
dis_begin: mov ah,0
int 16h ;等待读入字符
cmp al,0dh ;判断是否为回车
jne dis_begin ;不是继续判断
mov ah,6
mov al,1
mov bh,7
xor cx,cx
mov dh,23
mov dl,line_num
int 10h ;滚屏
mov ah,2
mov bh,page_num
mov dh,23
mov dl,0
int 10h ;置光标到倒数第二行第一列
jmp goon_dis
read1_error: mov dx,offset mess3
mov ah,9
int 21h ;显示提示信息
file_close1: mov bx,file_num
mov ah,3eh
int 21h ;关闭文件
read1_over: pop ds
pop dx
pop cx
pop bx
pop ax
ret
read_file1 endp
;读取文件,file_buff存放的文件名的文件,并直接显示出来文件内容
read_file2 proc
push ax
push bx
push cx
push dx
push ds
mov ax,data
mov ds,ax
mov ah,3dh
mov dx,offset file_buff
mov al,0 ;读方式打开文件
int 21h
jnc open_suc2 ;cf=0则打开成功
mov dx,offset mess2
mov ah,9
int 21h ;显示文件打开失败提示信息
jmp read2_over
open_suc2: mov file_num,ax ;保存文件号
mov bx,ax
mov cx,1
read2_again: mov dx,offset file_read
mov ah,3fh
int 21h ;读一个字节
jc read_error ;cf等于1表示读取文件失败
cmp ax,0 ;判断是否读取结束
je file_close2
mov dl,file_read
mov ah,2
int 21h ;显示
jmp read2_again
read_error: mov dx,offset mess3
mov ah,9
int 21h ;显示提示信息
file_close2: mov bx,file_num
mov ah,3eh
int 21h ;关闭文件
read2_over: pop ds
pop dx
pop cx
pop bx
pop ax
ret
read_file2 endp
;取出命令行参数的文件 名,判断是否有分屏命令(more)有则cf=1
get_ready proc
push si
push di
push ax
push cx
push dx
push es
cld
mov si,80h ;psp中存放参数的长度
lodsb
mov cl,al
or cl,cl
jz getover ;如果无命令行参数 则结束程序
mov di,si
mov al,' '
repz scasb
cmp al,[di-1] ;判断程序名字 是否全为空格
jz getover
dec di ;不是,则恢复di指向程序命令行第一个不是空格的字符
mov si,di
inc cx ;恢复指针与计数器到第一个不是空格的字符状态
mov ax,data
mov es,ax
mov di,offset file_buff
lod_again: dec cx
lodsb
cmp al,' '
je lod_over ;如果取到了空格表示文件名输入结束
stosb
loop lod_again
lod_over: mov byte ptr es:[di],0;在文件名最后添0
call cmp_para
pop es
pop dx
pop cx
pop ax
pop di
pop si
ret
getover: mov ah,9
mov ax,data
mov ds,ax
mov dx,offset mess1
int 21h ;显示提示信息
pop es
pop dx
pop cx
pop ax
pop di
pop si
ret
get_ready endp
;判断是否有 more参数,有则将cf置1,无则cf清零
cmp_para proc
push ax
cld
push ds
pop es
xchg si,di
mov al,' '
repz scasb ;检查命令行是否还有空格
cmp al,byte ptr es:[di-1]
je cmp_over1 ;全空格参数则结束
inc cx
dec di
xchg si,di
dec cx
lodsb
or al,20h ;转换成小写
cmp al,'m'
jne cmp_over1
jcxz cmp_over1
dec cx
lodsb
or al,20h
cmp al,'o'
jne cmp_over1
jcxz cmp_over1
dec cx
lodsb
or al,20h ;转换成小写
cmp al,'r'
jne cmp_over1
jcxz cmp_over1
dec cx
lodsb
or al,20h ;转换成小写
cmp al,'e'
jne cmp_over1
jmp cmp_over2
cmp_over1: pop ax
clc
ret
cmp_over2: pop ax
stc
ret
cmp_para endp
code ends
end main
[课程]FART 脱壳王!加量不加价!FART作者讲授!