汇编语言实例 简单用户登录程序

测试环境 win10下使用dosbox 0.75实现
支持多个用户名密码的显示
支持通过修改程序修改支持的用户名和密码长度。
使用macro 定义了一个名为DISP的宏,调用BIOS功能实现信息的打印
使用子程序SCOMP实现用户名的比对,并找出数据段中存储的该用户的密码所在存储单元的地址
使用子程序KEYCHECK实时输入、比对密码字符。

代码

;第三次版本
;输入用户名如果不正确就立即报错提示重新输入
;------------------------------------------------------------------
.586
DISP	MACRO	Y, X, VAR, LENGTH, COLOR;BIOS按照要求显示字符串
		 MOV         AH,13H
		 MOV         AL,1
		 MOV         BH,0                   ;选择0页显示屏
		 MOV         BL,COLOR                ;color属性字(颜色值) →BL
		 MOV         CX,LENGTH               ;LENGTH串长度 →CX
		 MOV         DH,Y                    ;Y行号 →DH
		 MOV         DL,X                    ;X列号 →DL
		 MOV         BP,OFFSET VAR           ;VAR串有效地址→BP
		 INT            10H
ENDM 

DATA SEGMENT USE16
LNAM  	= 10;姓名支持的最大长度
LKEY  	= 10;密码支持的最大长度
LPT   	= 10;打印的起始行数
LTIME   = 3;设置用户可以尝试的最大次数,注意修改第47行左右的字符串

NAM  	DB '1804','$';姓名列表
KEY   	DB '0215',0DH;密码列表
NAME1 	DB 'LENA','$'
PASS1 	DB 'JOBS',0DH
NAME2 	DB 'lau','$'
PASS2 	DB '.',0DH
ENDD  	DW ?,?

BUF   	DB LNAM+1
		DB ?
		DB LNAM+1 DUP(?);用来作为存储用户名的缓冲区
;下面是字符串
MESGN 	DB LNAM DUP(' ')
MESGP 	DB 'No.'
		DB ?
MESG1 Db 'welcome to THE login systerm'
L     =  $-MESG1
MESG2 DB 'please input your NAME'
LL    =  $-MESG2
MESG3 DB 'please input your password,YOU have THERE chance'
LLL   =  $-MESG3

MESG4 DB 'NO information!PLEASE input AGAIN'
L4    =  $-MESG4
MESG5 DB 'INCORRECT!TRY AGAIN'
L5    DB '$'

MESG7 DB ' Welcome!ENJOY your time'
L7    =  $-MESG7
MESG8 DB 'LOGIN failed',0DH,0ah
L8    =  $-MESG8

MESG9 	DB 0DH,0AH
		DB 'HI,'
		DB '$'
DATA ENDS

CODE SEGMENT USE16
	ASSUME DS:DATA,CS:CODE,ES:DATA
BEG:	MOV AX,DATA
		MOV DS,AX
		MOV ES,AX
		MOV AX,3   
		INT 10H ;设置屏幕显示方式  
		
		DISP LPT,(80-L)/2,MESG1, L,1FH;欢迎界面
		
		;输入用户名
		DISP LPT+1,(80-LL)/2,MESG2, LL,2
FIRST:	DISP LPT+2,(80-LNAM)/2,MESGN,LNAM,2;引导输入字符
		MOV BH,0
		MOV DH,LPT+2
		MOV DL,(80-LNAM)/2
		MOV AH,02H
		INT 10H	;设置光标位置			
		MOV AH,0AH
		MOV DX,OFFSET BUF
		INT 21H;读入用户键入的字符串放在buf中		
		MOV DI,OFFSET NAM
   STE:	CALL SCOMP
		JZ  SEC
		CMP di, OFFSET ENDD
		JC  STE	
		DISP LPT+3,40-L4/2,MESG4,L4,4;		
		JMP FIRST
		
		;输入密码
SEC:	DISP LPT+3,(80-LLL)/2,MESG3, LLL,2
		MOV CX,LTIME
SECOND:
		MOV DH,LPT+LTIME+3+1
		MOV BH,0
		SUB DH,CL
		MOV DL,(80-LKEY)/2
		MOV AH,02H
		INT 10H;设置光标位置
		CALL KEYCHECK
		JZ   YES
		CMP CX,1
		JZ  NO
		MOV AH,09H
		MOV DX,OFFSET MESG5
		INT 21H
		LOOP SECOND

		;登录结果反馈
NO:	    DISP LPT+LTIME+5,(80-L8)/2,MESG8,L8,4
		JMP LAST
YES:	DISP LPT+LTIME+6,0,MESG7,L7,1FH
		MOV AH,09H
		LEA DX,MESG9
		INT 21H
		MOV BL,BUF+1
        MOV BH,0
        MOV SI,OFFSET BUF+2
        MOV BYTE PTR[BX+SI],'$'
		MOV AH,09H
		MOV DX,OFFSET BUF+2
		INT 21H
LAST:	MOV AH ,4CH
	    INT 21H
		
		
;------------------------字符串比较-------------------------
SCOMP PROC;正确Z为1 错误Z为0
		MOV CL,BUF+1
		MOV CH,0
		LEA SI,BUF+2
		CLD
		REPE CMPSB
		JNZ SNO
		CMP BYTE PTR [DI],'$'
		JZ  SYES
SNO:	CMP BYTE PTR [DI],0DH
		JZ  SSNO
		INC DI
		JMP SNO	
SYES:  INC DI
		cmp di,di;z标志置1
		JMP SLAST
		
SSNO:   INC DI 
		TEST DI,DI;z标志置0 	
SLAST:	MOV ENDD,DI
RET
SCOMP ENDP
;--------------------检查密码是否正确----------------------
KEYCHECK  PROC
		MOV DI,ENDD
		MOV ENDD+2,DI
		MOV DH,0;将dh作为标志
KBEG:	MOV AH,08H
		INT 21H;输入一个字符
		CMP AL,0DH
		JZ KAL0D
		CMP BYTE PTR [DI],0DH
		JNZ KNEX
		INC DH
KNEX:	CMP BYTE PTR [DI],AL
		JZ  KSTEP
		INC DH
KSTEP:  INC DI    
		MOV AH,02H
		MOV DL,'*'
		INT 21H
		JMP KBEG
 
KAL0D:	CMP BYTE PTR [DI],0DH
		JZ  KLAST
		INC DH 
KLAST:	CMP DH,0
		RET
KEYCHECK	ENDP
CODE ENDS
END BEG 

实验中首先确定实验的大体框架

序号在屏幕上显示系统内部运行
1欢迎用户进入登录程序
2提示用户输入用户名系统检查用户名是否合法, 并寻找内存中该用户的密码
3提示用户输入密码与内存中的密码比对返回结果
4欢迎界面/密码错误返回

实验过程:

  1. 首先初步实现题目中的要求。实现了只有一种密码,不限定用户名的代码语言,利用宏的方法打印字符串。

  2. 然后增加了对用户名的核对。在前者的基础上,我对程序进行了比较大的修改,将原本只支持密码核对的程序,添加了核对名称的部分

  3. 之后,考虑到多个用户名的情况。核对用户名时将用户名所对应的密码的内存地址保存到内存指定单元中

  4. 再之后,对界面进行了美化。添加字符串将用户名旧内容遮挡并引导输入

调试过程

编程过程中,多次想要使用串操作来简化编程,但是有些地方在编程中发现并不适合,有些地方确实使用串操作之后更加地方便了。
在调试密码输入的子程序时,由于逻辑有些复杂,绘制如下表格

AL寄存器内容为0DH非0DH
DI指向 内存单元为0DHCMP DH,0INC DH 循环(继续输入字符)
非0DHINC DH CMP DH,0循环(继续输入字符)
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值