⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1.asm

📁 汇编语言实现的简易登陆系统
💻 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 + -