21,458
社区成员
发帖
与我相关
我的任务
分享
THEDATA segment
g_mainbuf db 20 dup (0)
g_mainUI db 'Welcome to contact record system',0dh,0ah
db '1.Add 2.Delete 3.Update 4.Query 5.Quit$'
g_inputname db 'Input Name:$'
g_inputtel db 'Input Tel:$'
g_filename db 'contact.dat',0
g_delname db 'Input Name:$'
g_cmpbuf db 20 dup (0) ;用于比较的buf
g_notfound db 'Not found!$'
;g_length db 14h ;文件指针偏移量
g_hiptr dw 0 ;文件指针 高位
g_loptr dw 0 ;文件指针 低位
g_delsuccess db 'Delete sucess!$'
g_displayname db 8 dup ('$')
g_displaytel db 12 dup ('$')
g_name db 'Name:$'
g_tel db 'Tel:$'
THEDATA ends
THESTACK segment stack
db 160 dup (0)
THESTACK ends
MAINFUNCTION segment
QUERYPROC proc
mov ax,ds
mov es,ax
mov di,0
mov al,0
mov cx,14h
mov bx,offset g_mainbuf ;存放用户输入的数据
QUERYINIT:
stosb
loop QUERYINIT ;BUF清0
QUERYWELCOME:
mov dx,offset g_inputname
mov ah,09
int 21h
mov cl,0dh ;cl 检测是否第一次就输入回车
QUERYNAME: ;DEL子程序的循环接收NAME功能
mov ah,01
int 21h
cmp al,0dh ;输入回车就跳出循环
jz ADJUSTQUERYNAME ;跳到ADJUSTTEL将输入的字串设置一下
mov cl,al
mov [bx],al
inc bx
JMP QUERYNAME
ADJUSTQUERYNAME:
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
cmp cl,0dh
jz QUERYWELCOME
mov byte ptr [bx],'$' ;上一组字串补上$
;打开文件
mov al,3 ;可读可写 g 003c
mov dx,offset g_filename ;打开文件
mov ah,3dh
int 21h
mov bx,ax ; 获得文件代号
push bx
mov bx,offset g_loptr
mov word ptr [bx],0
mov bx,offset g_hiptr
mov word ptr [bx],0
QUERYSEARCH:
mov bx,offset g_loptr
mov dx,[bx]
add byte ptr [bx],14h
mov bx,offset g_hiptr
mov cx,[bx]
adc byte ptr [bx],0
pop bx
push bx
;mov cx,0
;mov dx,0
mov al,0
mov ah,42h ;定位文件指针
int 21h
jc QUERYNOTFOUND ;指针指向文件尾部,判定为没有找到p
mov cx,14h ;读定长数据
mov ax,offset g_cmpbuf ;拿比较缓冲区偏移地址,存放读自文件的数据
mov dx,ax
mov ah,3fh
int 21h ;g 005d
mov cx,0
mov ax,ds
mov es,ax
mov di,offset g_mainbuf ;源数据 == 用户输入的数据
QUERYCOUNT:
mov al,'$'
scasb
jz QUERYCOMPARE
inc cx
jmp QUERYCOUNT
QUERYCOMPARE:
mov ax,ds ;g 0088
mov es,ax
mov si,offset g_mainbuf ;用户输入的数据
mov di,offset g_cmpbuf ;读取自文件的数据
repe cmpsb
jcxz QUERYFOUND ;找到就跳转到FOUND
jmp QUERYSEARCH ;没找到就再次设置文件指针向后查找
QUERYNOTFOUND:
mov dx,offset g_notfound
mov ah,09
int 21h
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
jmp QUERYEXIT
QUERYFOUND:
;显示文件数据
mov di,offset g_displayname ; 存放名字的缓冲作为目的地
mov si,offset g_cmpbuf ;读取自文件的内容,源
LOOP1:
cmp byte ptr [si],'$'
jz GETTEL
mov al,[si]
mov [di],al
inc si
inc di
jmp LOOP1
GETTEL:
inc si
mov di,offset g_displaytel
LOOP2:
cmp byte ptr [si],'$'
jz PREPAREDISPLAY
mov al,[si]
mov [di],al
inc si
inc di
jmp LOOP2
PREPAREDISPLAY:
mov dx,offset g_name
mov ah,09
int 21h
mov dx,offset g_displayname
int 21h
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
mov dx,offset g_tel
mov ah,09
int 21h
mov dx,offset g_displaytel
int 21h
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
QUERYEXIT:
mov ah,3eh ;关闭文件
int 21h;
pop bx
ret
QUERYPROC endp
DELPROC proc
mov ax,ds
mov es,ax
mov di,0
mov al,0
mov cx,14h
mov bx,offset g_mainbuf ;存放用户输入的数据
INIT:
stosb
loop INIT ;BUF清0
DELWELCOME:
mov dx,offset g_inputname
mov ah,09
int 21h
mov cl,0dh ;cl 检测是否第一次就输入回车
DELNAME: ;DEL子程序的循环接收NAME功能
mov ah,01
int 21h
cmp al,0dh ;输入回车就跳出循环
jz ADJUSTDELNAME ;跳到ADJUSTTEL将输入的字串设置一下
mov cl,al
mov [bx],al
inc bx
JMP DELNAME
ADJUSTDELNAME:
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
cmp cl,0dh
jz DELWELCOME
mov byte ptr [bx],'$' ;上一组字串补上$
;打开文件
mov al,3 ;可读可写 g 003c
mov dx,offset g_filename ;打开文件
mov ah,3dh
int 21h
mov bx,ax ; 获得文件代号
push bx
mov bx,offset g_loptr
mov word ptr [bx],0
mov bx,offset g_hiptr
mov word ptr [bx],0
SEARCH:
mov bx,offset g_loptr
mov dx,[bx]
add byte ptr [bx],14h
mov bx,offset g_hiptr
mov cx,[bx]
adc byte ptr [bx],0
pop bx
push bx
;mov cx,0
;mov dx,0
mov al,0
mov ah,42h ;定位文件指针
int 21h
jc NOTFOUND ;指针指向文件尾部,判定为没有找到p
mov cx,14h ;读定长数据
mov ax,offset g_cmpbuf ;拿比较缓冲区偏移地址,存放读自文件的数据
mov dx,ax
mov ah,3fh
int 21h ;g 005d
mov cx,0
mov ax,ds
mov es,ax
mov di,offset g_mainbuf ;源数据 == 用户输入的数据
COUNT:
mov al,'$'
scasb
jz COMPARE
inc cx
jmp COUNT
COMPARE:
mov ax,ds
mov es,ax
mov si,offset g_mainbuf ;用户输入的数据
mov di,offset g_cmpbuf ;读取自文件的数据
repe cmpsb
jcxz FOUND ;找到就跳转到FOUND
jmp SEARCH ;没找到就再次设置文件指针向后查找
NOTFOUND:
mov dx,offset g_notfound
mov ah,09
int 21h
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
jmp DELEXIT
FOUND:
;删掉文件数据
mov ax,ds
mov es,ax
mov di,0 ;g 96
mov al,0
mov cx,14h
;push bx ;文件代号入栈保存
mov bx,offset g_mainbuf ;将mainbuf清0,写入文件中,等价于清空文件数据
INITBUF:
stosb
loop INITBUF ;BUF清0
;将文件指针回溯20个字节,就可以开始反填数据
mov bx,offset g_loptr
mov dx,[bx]
sub dx,14h
mov bx,offset g_hiptr
mov cx,[bx]
sbb cx,0
pop bx ;文件代号出栈
mov al,0
mov ah,42h ;定位文件指针
int 21h
mov ah,40h ;调用40h功能准备写入文件 ;
mov dx,0
;pop cx
;inc cx ;+1因为文件中不是0下标开始算
mov cx,14h ;固定写20个字节
int 21h
mov dx,offset g_delsuccess ;打印删除成功提示
mov ah,09
int 21h
mov ah,3eh ;关闭文件
int 21h;
DELEXIT:
ret
DELPROC endp
ADDPROC proc
push bp
mov bp,sp
push cx
push di
push dx
push bx
mov di,0
mov al,0
mov cx,14h
INIT:
stosb
loop INIT
mov dx,[bp+8]
mov ah,09
int 21h
mov bx,0 ;bx当作下标使用
ADDINPUTNAME: ;ADD子程序的循环接收功能
mov ah,01
int 21h
cmp al,0dh ;输入回车就跳出循环
jz ADJUSTNAME ;跳到ADJUST 将输入的字串设置一下,以备接收下一个字串
mov [bx],al
inc bx
JMP ADDINPUTNAME
ADJUSTNAME: ;ADJUSTNAME的作用,将上一组字串补上$ 并换行
;inc bx
mov byte ptr [bx],'$' ;上一组字串补上$
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
mov dx,[bp+6] ;提示输入电话
mov ah,09
int 21h
inc bx ;bx自增1,准备接受tel
ADDINPUTTEL: ;ADD子程序的循环接收功能
mov ah,01
int 21h
cmp al,0dh ;输入回车就跳出循环
jz ADJUSTTEL ;跳到ADJUSTTEL将输入的字串设置一下
mov [bx],al
inc bx
JMP ADDINPUTTEL
ADJUSTTEL:
;inc bx
mov byte ptr [bx],'$' ;上一组字串补上$
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
mov al,3 ;可读可写 ;g a9
mov dx,offset g_filename ;打开文件
mov ah,3dh
int 21h
jc CREATENEWFILE ;如果cf=1,文件不存在 则创建文件
push ax ;成功,将文件代码压栈
jmp NEXT
CREATENEWFILE:
mov cx,20h ;指定创建的文件属性,
mov ah,3ch
int 21h
push ax ;成功,将文件代码压栈
NEXT:
mov ah,42h ;g 005d
mov al,2 ;移动文件指针到尾部
mov cx,0
mov dx,0
pop bx ;拿到文件代号
int 21h
mov ah,40h ;调用40h功能准备写入文件 ;
mov dx,0
mov cx,14h ;固定写20个字节
int 21h
mov ah,3eh ;关闭文件 g d6
int 21h;
pop bx
pop dx
pop di
pop cx
mov sp,bp
pop bp
ret 6
ADDPROC endp
MAINUI proc
@strWelcome = +4
push bp
mov bp,sp
push dx
push bx
WELCOME:
mov dx,[bp+@strWelcome]
mov ah,09
int 21h
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
mov bl,0dh ;bl初始为0d,防止第一次就输入回车,可供selectfun标号用,让程序返回到UI
INPUT: ;循环接受输入
mov ah,01
int 21h
cmp al,0dh ;输入回车就跳出循环
jz SELECTFUN
mov bl,al ;输入项由bl保存,
JMP INPUT
SELECTFUN:
mov dl,0dh ;== /r
mov ah,02
int 21h
mov dl,0ah ;== /n
int 21h
cmp bl,0dh
jz WELCOME
cmp bl,'1' ;比较操作,确定分支
jnz ELSEIF_BEGIN1 ;增加子程序
IF_BEGIN:
mov ax,offset g_inputname
push ax
mov ax,offset g_inputtel
push ax
mov ax,offset g_filename
push ax ;g 02cb
call ADDPROC
jmp WELCOME
IF_END:
ELSEIF_BEGIN1:
cmp bl,'2'
jnz ELSEIF_BEGIN2
call DELPROC
jmp WELCOME
ELSEIF_END1:
ELSEIF_BEGIN2:
cmp bl,'3'
jnz ELSEIF_BEGIN3
CALL DELPROC
CALL ADDPROC
jmp WELCOME
ELSEIF_END2:
ELSEIF_BEGIN3:
cmp bl,'4'
jnz ELSEIF_BEGIN4
CALL QUERYPROC
JMP WELCOME
ELSEIF_END3:
ELSEIF_BEGIN4:
cmp bl,'5' ;g02f2
jnz ELSE_BEGIN ;quit
SAFEEXIT:
pop bx
pop dx
mov sp,bp
pop bp
ret 2
ELSEIF_END4:
ELSE_BEGIN:
jmp WELCOME
ELSE_END:
MAINUI endp
start:
mov ax,THESTACK
mov ss,ax
mov ax,THEDATA
mov ds,ax
mov si,0
mov ax,offset g_mainUI
push ax
call MAINUI
mov ax,4c00h
int 21h
MAINFUNCTION ends
end start