?? 1.asm
字號:
stack segment stack
db 256 dup(0)
stack ends
;-------------------------------------------------
DATA SEGMENT
maxpl equ 10 ;密碼最大長度
maxnl equ 20 ;名字最大長度
namepar label byte ;name parameter list
db maxnl
namelen db ?
namerec db maxnl dup(' ') ;entered name
pwdpar label byte ;password parameter list
db maxpl
pwdlen db ?
pwdrec db maxpl dup(' ') ;entered password
buf db maxnl+maxpl dup(' '),0ah,0dh ;讀取一個記錄的緩沖
newone db 0 ;是否創建新賬號
handle dw ? ;文件句柄
pathnam db 'd:/users.dat',0 ;文件存取目錄
row db 01 ;光標所在的行
id db 0 ;當前用戶名的序號,修改密碼時用
msgname db 'please enter login name:(enter <new> to create a new account)','$'
msgpwd db 'please enter password:','$'
newname db 'login name? ','$'
newpwd db 'passeord? ','$'
menumsg db '* * * 1:modify password * * *',0ah,0dh
db '* * * 2:list all users * * *',0ah,0dh
db '* * * 3:quit * * *','$'
crtmsg db '* * * fail to create file * * *','$'
newmsg db '* * * fail to create new account * * *','$'
opnmsg db '* * * open file error * * *','$'
wrtmsg db '* * * write file error * * *','$'
redmsg db '* * * read file error * * *','$'
clsmsg db '* * * close file error * * *','$'
logmsg db '* * * name or password is wrong * * *','$'
renmsg db '* * * this name is used,please enter again * * *','$'
gdbmsg db 0ah,0dh,'Goodbye!!!','$'
tilmsg db 'username password','$'
modmsg db '* * * success! * * *','$'
mermsg db '* * * fail,retry! * * *','$'
errcde db 0 ;0:正常, 1:出錯, 2:測試打開
;3:用戶名重復 4:已讀到文件末尾
data ends
;-------------------------------------------------
code segment
main proc far
assume cs:code,ds:data,ss:stack,es:data
start:
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov es,ax
goback: mov row,01
mov ax,0600h
call scren ;clear screen
call curs ;set cursor
gb1: mov errcde,0
call inname ;input name
cmp errcde,01
jz done3
call isinnew ;檢查輸入密碼時輸入的是否是new,是則創建新賬號
cmp newone,1
je co
lea dx,msgpwd
mov ah,09
int 21h
call inpwd ;input password
call login ;檢查用戶名和密碼是否正確
cmp errcde,0
jz conti1
lea dx,logmsg
mov ah,09
int 21h
call scrl
jmp gb1
conti1: call showmenu ;顯示選擇菜單
jmp done3
co: call createone ;添加新賬號
cmp errcde,0
jz goback
done3: ret
main endp
;-------------------------------------------------
inname proc near ;輸入的用戶名存在namerec里
lea dx,msgname ;顯示輸入用戶名提示
mov ah,09
int 21h
call scrl
lea dx,namepar
mov ah,10
int 21h
call scrl
cmp namelen,0
jne don
mov errcde,01
don: ret
inname endp
;-------------------------------------------------
inpwd proc near ;輸入的密碼存在pwdrec里
lea bx,pwdrec
mov cl,maxpl
lp0: mov ah,07
int 21h
cmp al,0dh ;回車結束
je done0
cmp al,08 ;backspace
je backspace0
mov [bx],al
mov dl,'*'
mov ah,02h
int 21h
inc bx
dec cl
jnz lp0
jmp done0
backspace0:
cmp cl,maxpl ;如果沒有輸入字符或已經退到頂,則不執行一下代碼
je lp0
mov dl,08h ;先退格
mov ah,02h
int 21h
mov dl,00h ;輸出NUL
int 21h
mov dl,08h ;再退格,達到鍵盤上Backspace的效果
int 21h
inc cl
dec bx
mov byte ptr [bx],' '
jmp lp0
done0: mov ch,maxpl
sub ch,cl
mov pwdlen,ch
call scrl
ret
inpwd endp
;-------------------------------------------------
isinnew proc near ;檢查namerec里輸入的是否是new
cmp namelen,03
jne not0
lea bx,namerec
cmp byte ptr [bx],'n'
jne not0
inc bx
cmp byte ptr [bx],'e'
jne not0
inc bx
cmp byte ptr [bx],'w'
jne not0
mov newone,1
jmp done2
not0: mov newone,0
done2: ret
isinnew endp
;-------------------------------------------------
createone proc near ;創建新賬號
rein: lea dx,newname
mov ah,09
int 21h
lea dx,namepar ;輸入新的用戶名
mov ah,10
int 21h
cmp namelen,0
jne continue2
ret
continue2:
call scrl
mov errcde,02 ;用戶測試打開
call openf
cmp errcde,0 ;打開失敗,無須檢查用戶名是否重復
jnz continue1
call findnam
mov id,0
call closef
cmp errcde,03 ;用戶名重復
jnz continue1
lea dx,renmsg
mov ah,09
int 21h
call scrl
jmp rein
continue1:
mov errcde,0
lea dx,newpwd
mov ah,09
int 21h
call inpwd
call scrl
call tranc
mov errcde,02 ;用戶測試打開
call openf
cmp errcde,0 ;打開失敗,嘗試創建新文件
jz addone
mov errcde,0
call createf
cmp errcde,0 ;創建失敗
jnz done4
call writef
jmp done4
addone: mov ah,42h ;把文件指針移到末尾
mov al,2 ;絕對倒移方式2
mov bx,handle
mov cx,0 ;offset
mov dx,0
int 21h ;將文件指針移到文件尾,返回dx:ax=文件長度
jc err
call writef
jmp done4
err: lea dx,newmsg
call error
done4: call closef
ret
createone endp
;-------------------------------------------------
tranc proc near
mov al,20h ;blank for storing
sub ch,ch
mov cl,namelen ;length
lea di,namerec
add di,cx ;address+length
neg cx ;calculate remaining
add cx,20 ;length
rep stosb ;set to blank
mov al,20h
sub ch,ch
mov cl,pwdlen
lea di,pwdrec
add di,cx
neg cx
add cx,10
rep stosb
ret
tranc endp
;-------------------------------------------------
login proc near
mov id,0
mov errcde,0 ;清楚錯誤碼
call openf
cmp errcde,0
jnz done5
call findnam
cmp errcde,03 ;找到名字
jnz done5
call checkpwd
cmp errcde,0 ;密碼正確?
jnz done5
mov errcde,0
call closef
ret
done5: mov errcde,01
ret
login endp
;-------------------------------------------------
createf proc near
mov ah,3ch ;request create
mov cx,0 ;normal attribute
lea dx,pathnam
int 21h
jc a1 ;error
mov handle,ax ;no,save handle
ret
a1: lea dx,crtmsg ;error message
call error
ret
createf endp
;-------------------------------------------------
showmenu proc near
conti2: mov row,02
mov ax,0600h
call scren ;clear screen
call curs ;set cursor
lea dx,menumsg
mov ah,09
int 21h
call scrl
call scrl
mov dl,'?'
mov ah,02
int 21h
mov ah,01
int 21h
sub al,'0' ;ASCII to number
cmp al,1
jz mod1 ;modify password
cmp al,2
jz list1 ;list all users
lea dx,gdbmsg
mov ah,09
int 21h
call scrl
done7: ret
mod1: call modpwd
jmp conti2
list1: call lstall
jmp conti2
showmenu endp
;-------------------------------------------------
openf proc near ;用于測試文件存在而打開時,給errcde賦值2
mov ah,3dh ;request create
mov al,02 ;read and write
lea dx,pathnam
int 21h
jc b1 ;error
mov handle,ax ;no,save handle
mov errcde,0
ret
b1: cmp errcde,02 ;是測試打開
jz b2
lea dx,opnmsg ;error message
call error
jmp b3
b2: mov errcde,01
b3: ret
openf endp
;-------------------------------------------------
readf proc near
mov ah,3fh ;request read
mov bx,handle
mov cx,maxnl+maxpl ;for name,password and CR/LF
lea dx,buf
int 21h
jc c1 ;error no read?
cmp ax,0 ;end of file?讀取了0字節
je c2
ret
c1: lea dx,redmsg
call error
ret
c2: mov errcde,04 ;標示已經讀到文件末尾
ret
readf endp
;-------------------------------------------------
writef proc near
cld ;DF=0,增量方向
lea si,namerec ;復制namerec到buf
lea di,buf
mov cx,maxnl
rep movsb
lea si,pwdrec ;復制pwdrec到buf+maxnl
lea di,buf+maxnl
mov cx,maxpl
rep movsb
mov ah,40h ;request write
mov bx,handle
mov cx,maxnl+maxpl ;for buf
lea dx,buf
int 21h
jc d1 ;valid write?
;mov namelen,0
;mov pwdlen,0
;lea di,buf ;清空buf
;mov al,' '
;mov cx,maxnl+maxpl
;rep stosb
ret
d1: lea dx,wrtmsg ;no
call error ;call error routine
ret
writef endp
;-------------------------------------------------
closef proc near
mov ah,3eh ;request close
mov bx,handle
int 21h
ret
d2: lea dx,clsmsg ;no
call error ;call error routine
ret
closef endp
;-------------------------------------------------
findnam proc near
call tranc
next1: inc id ;用戶序號加一
call readf
cmp errcde,04 ;是否已讀到文件末尾
jz f1
lea si,buf
lea di,namerec
xor cx,cx
mov cl,maxnl
repe cmpsb ;相同時ZF=1,repe繼續執行
jnz next1 ;CX為0,說明比較到最后都相同
mov errcde,03 ;找到相同的名字
jmp f2
f1: mov errcde,0 ;未找到相同的名字
f2: ret
findnam endp
;-------------------------------------------------
checkpwd proc near
mov errcde,0
lea si,buf+maxnl
lea di,pwdrec
xor cx,cx
mov cl,maxpl
repe cmpsb
jnz done6
mov errcde,0
ret
done6: mov errcde,01 ;密碼不對
ret
checkpwd endp
;-------------------------------------------------
modpwd proc near
call scrl
lea dx,newpwd
mov ah,09
int 21h
call inpwd
call openf
mov al,maxnl+maxpl
mov cl,id
dec cl
mul cl ;計算出該用戶記錄在文件中的偏移量
;add cl,maxnl ;移動到保存密碼的位置
mov bx,handle
mov cx,0
mov dx,ax
mov al,0 ;從文件頭開始的絕對位移
mov ah,42h
int 21h
jc err4
cld
call tranc
call writef
cmp errcde,01
jz done9
lea dx,modmsg
jmp gogo
err4: lea dx,mermsg
gogo: mov ah,09
int 21h
done9: call closef
mov ah,07
int 21h
ret
modpwd endp
;-------------------------------------------------
lstall proc near
call scrl
lea dx,tilmsg
mov ah,09
int 21h
call scrl
call openf
next3: call readf
cmp errcde,04 ;已到文件末尾
jz done8
mov ah,40h ;request write
mov bx,01 ;set handle,01為標準輸出設備
mov cx,32 ;for length
lea dx,buf
int 21h
jmp next3
done8: call closef
mov ah,07
int 21h
ret
lstall endp
;-------------------------------------------------
scrl proc near
cmp row,18h ;bottom of screen?
jae c3 ;yes,bypass
inc row ;no,add to row
c3: mov ax,0601h ;scroll one row
call scren
call curs ;reset cursor
ret
scrl endp
;-------------------------------------------------
scren proc near ;AX set on entry
mov bh,1eh ;set yellow no blue
mov cx,0
mov dx,184fh
int 10h ;scroll
ret
scren endp
;-------------------------------------------------
curs proc near
mov ah,02
mov bh,0
mov dh,row ;set cursor
mov dl,0
int 10h
ret
curs endp
;-------------------------------------------------
error proc near ;通過DX傳遞要顯示的信息地址
mov ah,09
int 21h
mov errcde,01
ret
error endp
;-------------------------------------------------
code ends
end start
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -