📄 library.asm
字号:
data segment ;将段前缀的说明部分单独作为一端,并将DS固定指向该段
org 6ah
rec_size dw ?
org 07ch
recno db ?
randlow dw ?
randhi dw ?
org 80h
dta db 200h dup(?)
data ends
sta segment STACK
db 200h dup(?)
top label word
sta ends
PSize equ 3
RSize equ 66
fcb equ 5ch ;利用命令行参数直接初始化FCB的文件名,系统在分析DOS命令行后,
;将参数直接放入FCB的5ch处,因而可以从该处取出参数,进行各种处理
ext segment ;其它数据单元(提示信息等)另设一段,以es固定指向该段,
;在引用该段变量时加上es段前缀即可
names db 10 dup(?) ;记录分为五项
price db 3 dup(?)
bianhao db 10 dup(?)
author db 15 dup(?)
publish db 30 dup(?)
snames db 10 dup(?)
OK db ?
founded db ?
recnum db ?
pcounter db ?
buf db 200h dup(?)
mess_n db 0ah,0dh," name : $"
mess_a db 0ah,0dh," price : $"
mess_s db 0ah,0dh," bianhao: $"
mess_h db 0ah,0dh," author : $"
mess_w db 0ah,0dh," publish: $"
err_fopen db 0ah,0dh," New Doucment opened !$"
err_fcreat db 0ah,0dh," File creat error!$"
err_fread1 db 0ah,0dh," File read error in sequence manner!$"
err_fread2 db 0ah,0dh," File read error in random manner !$"
err_fclose db 0ah,0dh," File close error!$"
prompt0 db 0ah,0dh," * * * * * * * * * * * *$"
prompt1 db 0ah,0dh," * * * i:insert * * *$"
prompt2 db 0ah,0dh," * * * l:list * * *$"
prompt3 db 0ah,0dh," * * * s:search * * *$"
prompt4 db 0ah,0dh," * * * m:modify * * *$"
prompt5 db 0ah,0dh," * * * d:delete * * *$"
prompt6 db 0ah,0dh," * * * q:quit * * *$"
prompt7 db 0ah,0dh," * * * * * * * * * * * *$"
prompt8 db 0ah,0dh,"command#:$"
nfound db 0ah,0dh," Sorry ,this record is not in the list$"
continue db 0ah,0dh," Press space to continue....",0ah,0dh,24h
searchq db 0ah,0dh," Which do you want to search ? : $"
deleteq db 0ah,0dh," Which do you want to delete ? : $"
deleteq2 db 0ah,0dh," Do you really want to delete this record ? : $"
modifyq db 0ah,0dh," Which do you want to modify ? : $"
showp db 0ah,0dh,"[ name ][ price ][ bianhao ][ author ][ publish ]",0ah,0dh,24h
help db 0ah,0dh,"i:insert l:list s:search m :modify d:delete h:command menu q:quit ",0ah,0dh,24h
welcome db 0ah,0dh,"Press h botton for command menu ! ",0ah,0dh,24h
ext ends
show macro addrs ;显示以addrs为起始地址所在的那一行字符
push ds
mov ax,es
mov ds,ax
lea dx,addrs
mov ah,09h
int 21h
pop ds
endm
show_item macro addrs,count1,count2 ; 显示以addrs为起始地址的count1个字符,并后跟count2个空格
local iloop,spacelp
mov bx,0
iloop:
mov dl,es:&addrs&[bx]
mov ah,2
int 21h
inc bx
cmp bx,count1
jl iloop
mov cx,count2
spacelp:
mov dl," "
mov ah,2
int 21h
loop spacelp
endm
getin macro addrs,count ;从键盘上获取count个字符,并把它们存在以addrs为起始地址内存区
local lp,zeroit,input_end,exit
push ds
mov ax,es
mov ds,ax
mov bx,0
zeroit:
mov &addrs&[bx],0
inc bx
cmp bx,count
jl zeroit ;以addrs为起始地址的count个字节初始化为0
mov bx,0
lp: mov ah,1
int 21h
cmp al,0dh
jz input_end
mov &addrs&[bx],al
inc bx
cmp bx,count
jl lp
input_end:
cmp al,0dh
jz exit
cmp al,0ah
jz exit
mov ah,1
int 21h
jmp input_end ;若不是所有键入的字符都已被接收,则重新键入
exit:
pop ds
endm
code segment
assume cs:code,ds:data,es:ext,ss:sta
main proc far
start:
push ds
sub ax,ax
push ax
mov ax,ext
mov es,ax
show welcome
main_loop:
show prompt0
show prompt1
show prompt2
show prompt3
show prompt4
show prompt5
show prompt6
show prompt7
show prompt8
cmd_loop: ;对接收都的l,i s,d,m,h,q进行不同的响应
mov ah,1
int 21h
cmp al,"l"
jnz n1
call list_all
jmp main_loop
n1:
cmp al,"i"
jnz n2
call insert
jmp main_loop
n2: cmp al,"s"
jnz n3
call search
jmp main_loop
n3: cmp al,"d"
jnz n4
call delete
jmp main_loop
n4: cmp al,"m"
jnz n5
call modify
jmp main_loop
n5: cmp al,"h"
jnz n6
show help
jmp main_loop
n6: cmp al,"q"
jnz cmd_loop
ret
main endp
list_all proc near ;显示所有记录功能子程序
push ax
push bx
push cx
push dx
call openf ;打开参数所带的文件名的文件
or al,al
jz l_go_on
jmp l_ext
l_go_on:
mov recno,0
mov rec_size,RSize
call enter
show showp
l_list_loop:
mov dx,fcb
mov ah,14h ;以顺序方式读取记录
int 21h
cmp al,01 ;al返回01时说明已读到文件尾
jne l_n3
jmp l_file_end
l_n3:
cmp al,0 ;al返回为0时读取成功
je l_n4
show err_fread1 ;否则错误
mov dl,"0" ;显示错误号码
add dl,al
mov ah,2
int 21h
jmp l_file_end
l_n4:
mov bx,0
l_moving:
mov al,dta[bx] ;读出的数据放在约定的内存区dta中,课本p171页详解
mov es:names[bx],al
inc bx
cmp bx,RSize
jl l_moving
call enter
call show_rec ;显示记录
call enter
inc es:pcounter
cmp es:pcounter,PSize
jl l_list_loop
mov es:pcounter,0
show continue ;大于页数时停止显示,并提示输入空格,
l_pg_cmd:
mov ah,1
int 21h
cmp al," "
jne l_pg_cmd ;等接收到空格后继续显示
jmp l_list_loop
l_file_end:
call closef
l_ext:
pop dx
pop cx
pop bx
pop ax
ret
list_all endp
insert proc near ;插入新记录功能子程序
push ax
push bx
push cx
push dx
call openf
or al,al
jz getrc
jmp back
getrc:
call get_record ;从键盘获取记录
mov recno,0
mov rec_size,RSize
i_find_end:
mov ah,14h
mov dx,fcb
int 21h
cmp al,01
je i_write_record ;一直读,等读到文件尾时,在文件尾写入记录
cmp al,0
je i_find_end
i_write_record:
mov bx,0
i_to_dta:
mov al,es:names[bx]
mov dta[bx],al
inc bx
cmp bx,RSize
jl i_to_dta
mov ah,15h ;把缓冲区中的记录写入文件中
mov dx,fcb
int 21h
call closef
back:
pop dx
pop cx
pop bx
pop ax
ret
insert endp
search proc near ;查询某项记录功能子程序
push ax
push bx
push cx
push dx
show searchq ;查询你所要查询的记录的人的姓名
getin snames,10 ;输入到snames中
call openf
or al,al
jz s_go_on
jmp s_ext
s_go_on:
mov founded,0 ;将founded初始化为0,若以后查找到有相同项则不为0,
mov recno,0 ;将记录号初始化为0
mov rec_size,RSize ;初始化每条记录的字节数
call enter
show showp
s_list_loop:
mov dx,fcb
mov ah,14h ;将FCB中当前块号和当前记录号指定的记录送磁盘缓冲区
int 21h
cmp al,01 ;若al返回01则表示记录中无数据
jne s_n3
jmp s_file_end
s_n3:
cmp al,0 ;若al返回 0 则表示读成功
je s_n4
show err_fread1
mov dl,"0"
add dl,al
mov ah,2
int 21h
jmp s_file_end
s_n4:
mov bx,0
s_moving:
mov al,dta[bx] ;把小于RSize个缓冲区字节(即一个记录长度)
mov es:names[bx],al ;的内容送到以names为起始地址的内存中
inc bx
cmp bx,RSize
jl s_moving
call find ;调用find子程序,看是否能找到
cmp OK,0
jnz s_loop
call enter ;找到则把它作出相应的处理,在此作出显示
call show_rec
call enter
inc byte ptr founded
s_loop:
jmp s_list_loop
s_file_end:
cmp founded,0 ;找不到则显示错误信息
jnz s_file_c
show nfound
call enter
s_file_c:call closef
s_ext:
pop dx
pop cx
pop bx
pop ax
ret
search endp
modify proc near ;修改某项记录功能子程序
push ax
push bx
push cx
push dx
show modifyq ;查询你所要修改的记录的人的姓名
getin snames,10
call openf
or al,al
jz m_go_on
jmp m_ext
m_go_on:
mov founded,0
mov recno,0
mov rec_size,RSize
call enter
show showp
m_list_loop:
mov dx,fcb
mov ah,14h
int 21h
cmp al,01
jne m_n3
jmp m_file_end
m_n3:
cmp al,0
je m_n4
show err_fread1
mov dl,"0"
add dl,al
mov ah,2
int 21h
jmp m_file_end
m_n4:
mov bx,0
m_moving:
mov al,dta[bx]
mov es:names[bx],al
inc bx
cmp bx,RSize
jl m_moving
call find ;调用find子程序,看是否能找到
cmp OK,0
jnz m_loop
call enter
call show_rec
call enter
inc founded
getrcf: ;找到则调用get_record获取记录
call get_record
write_recordf:
dec byte ptr recno
mov bx,0
m_to_dta:
mov al,es:names[bx] ;把新获取的记录写到原先对应记录中
mov dta[bx],al
inc bx
cmp bx,RSize
jl m_to_dta
mov ah,15h
mov dx,fcb
int 21h
m_loop:
jmp m_list_loop
m_file_end:
cmp founded,0
jnz m_next
show nfound
call enter
m_next:
call closef
call list_all
m_ext:
pop dx
pop cx
pop bx
pop ax
ret
modify endp
delete proc near ;删除某项记录功能子程序
push ax
push bx
push cx
push dx
show deleteq
getin snames,10
call openf
or al,al
jz d_go_ond
jmp d_ext
d_go_ond:
mov founded,0
mov recno,0
mov rec_size,RSize
mov bp,0
d_list_loop:
mov dx,fcb
mov ah,14h
int 21h
cmp al,01
jne d_n3
jmp d_file_end
d_n3:
cmp al,0
je d_n4
show err_fread1
mov dl,"0"
add dl,al
mov ah,2
int 21h
jmp d_file_end
d_n4:
mov bx,0
d_moving:
mov al,dta[bx]
mov es:names[bx],al
inc bx
cmp bx,RSize
jl d_moving
call find
cmp OK,0
jz d_loop
mov bx,0 ;只有与删除项相同的那记录项不写入内存
d_mov:
mov al,dta[bx]
mov es:buf[bp],al
inc bx
inc bp
cmp bx,RSize
jl d_mov
jmp d_loop2
d_loop:inc founded
d_loop2:jmp d_list_loop
d_file_end:
cmp founded,0
jnz d_next
show nfound
call enter
d_next:
mov cx,bp
mov bx,0
p:
mov al,es:buf[bx]
mov dta[bx],al
inc bx
loop p
mov dta[bx],0ah
mov ah,13h
mov dx,fcb
int 21h
mov ah,16h
mov dx,fcb
int 21h
mov recno,0
mov word ptr rec_size,bp
mov dx,offset dta
mov ah,1ah
int 21h
mov dx,fcb ;把内存中的记录写入文件中
mov ah,15h
int 21h
call closef
call list_all
d_ext:
pop dx
pop cx
pop bx
pop ax
ret
delete endp
find proc near ;对比sname与dta前10字节,即姓名段是否相同,相同OK处为0,不相同OK处为1
push ax
push bx
push cx
push dx
mov cx,10
mov di,offset snames
mov si,offset dta
cld
repz cmpsb
jnz unequ
mov al,0
jmp next
unequ:mov al,01h
next: mov OK,al
pop dx
pop cx
pop bx
pop ax
ret
find endp
show_rec proc near ;调用show_item显示记录
push ax
push bx
push cx
push dx
show_item names,8,2
show_item price,3,6
show_item bianhao,10,2
show_item author,15,2
show_item publish,30,2
pop dx
pop cx
pop bx
pop ax
ret
show_rec endp
get_record proc near ;从键盘上获取记录
push ax
push bx
push cx
push dx
show mess_n
getin names,10
show mess_a
getin price,3
show mess_s
getin bianhao,10
show mess_h
getin author,15
show mess_w
getin publish,30
pop dx
pop cx
pop bx
pop ax
ret
get_record endp
enter proc near ;回车与换行
push ax
push bx
push cx
push dx
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
pop dx
pop cx
pop bx
pop ax
ret
enter endp
openf proc near ;从 5ch处得到文件名,打开该文件,若不存在,则建立以该文件名为名的文件
push bx
push cx
push dx
mov ah,0fh
mov dx,fcb
int 21h
or al,al
jz found
show err_fopen
mov ah,16h
mov dx,fcb
int 21h
or al,al
jz found
show err_fcreat
found:
pop dx
pop cx
pop bx
ret
openf endp
closef proc near ;关闭文件
push ax
push dx
mov ah,10h
mov dx,fcb
int 21h
pop dx
pop ax
ret
closef endp
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -