南京邮电大学汇编——实验二:用户登陆验证程序的设计

南京邮电大学汇编——实验二:用户登陆验证程序的设计

两个题目

  1. 从BUF单元开始存有一字符串(长度<255),编程实现统计该字符串中的ASCII在42H~45H之间的字符个数,并将统计结果以二进制形式显示在屏幕。
  2. 程序执行后,给出提示操作,请用户键入用户名和密码;用户在键入密码时,程序不回显键入字符;只有当用户键入的用户名,密码字符串和程序内定的字符串相同时,显示欢迎界面并返回DOS;否则给出提示信息,用户名或密码错误,再次输入。界面颜色自定(彩色或黑白)

源代码

本来是想用rdrand指令来写一段随机数生成代码的,但是发现rdrand这个指令是在Inter于Ivy Bridge微架构(2012年生产)后才定义到IA32架构中的,目前我们的电脑上基本上都支持这个指令,但是经过尝试之后发现即使采用直接写字节码dosbox也不支持这个指令,可能有以下两个原因:

  1. DosBox的虚拟化环境采用了模拟而不是虚拟,这导致了只支持实模式下的指令集;
  2. 这个指令只能在保护模式下使用

第一题的源代码

.586P
data segment use16
	Count_Number db 0
	String_1 db 'ABCDEFG',0
data ends



Code segment USE16
ASSUME CS: CODE, DS: DATA
	BEG:
		mov ax,data
		mov ds,ax
		mov di,offset String_1
		
	;得到在范围内的数
	Get_Count:
		mov al,ds:[di]
		cmp al,0
		jz	Print_Result
		cmp al,42h
		jb	.1
		cmp	al,45h
		ja	.1
		inc Count_Number
	.1:	
		inc di
		jmp	Get_Count
	;得到在范围内的数
	
	;打印数据
	Print_Result:
		mov bl,Count_Number
		mov cx,8
	.2:
		mov dl,0
		shl bl,1
		adc dl,30h
		mov ah,2
		int 21h
		loop .2
		mov dl,'h'
		int 21h
	;打印数据
	
		mov ah,4ch
		int 21h
code ends

end BEG 

第二题的源代码

.586P
data segment use16
	;定义数据接受区
	UserName 			db 100 	dup(0)
	UserName_Recived_Number	dw 0
	Password			db 100	dup(0)
	Password_Recived_Number	dw 0
	;定义数据接受区
	
	UserName_Origin		db	'YourUserName',0
	Password_Origin		db	'YourPassword',0
	String_Tip 			db 'Please enter your username!',0ah,0dh,'$'
	String_Password_Tip 			db 'Please enter your password!',0ah,0dh,'$'
	String_Wrong_Tip 	db 'Wrong username or password!\n',0ah,0dh,'$'
	String_Hello_Tip	db 'You got it!',0ah,0dh,'$'
data ends



Code segment USE16
ASSUME CS: CODE, DS: DATA
	BEG:
		mov ax,data
		mov ds,ax
		mov dx,offset String_Tip
		mov ah,9
		int 21h
		
		mov UserName_Recived_Number,0
	GetUserName:
		mov ah,1
		int 21h
		mov di,offset UserName
		add di,UserName_Recived_Number
		mov	ds:[di],al
		inc	UserName_Recived_Number
		cmp al,0dh;当输入回车时实际上是输入了0x0a,0x0d两个字符,此时系统调用实际上返回的是最后一个字符0x0d
		jnz GetUserName
		mov di,offset UserName
		add di,UserName_Recived_Number
		sub di,1
		mov [di],0
		
		mov dx,offset String_Password_Tip
		mov ah,9
		int 21h
		
		mov Password_Recived_Number,0
	GetPassword:
		mov ah,8
		int 21h
		mov di,offset Password
		add di,Password_Recived_Number
		mov	ds:[di],al
		inc	Password_Recived_Number
		cmp al,0dh;当输入回车时实际上是输入了0x0a,0x0d两个字符,此时系统调用实际上返回的是最后一个字符0x0d
		jnz GetPassword
		mov di,offset Password
		add di,Password_Recived_Number
		sub di,1;将最后一个输入的0x0d字符删去
		mov [di],0
	
		cld;当df位为0时,采用大端方式
		mov ax,ds
		mov es,ax
		
	CheckUserName:
		mov si,offset UserName_Origin
		mov di,offset UserName
		mov cx,UserName_Recived_Number
		REPE cmpsb;采用串比较,源地址为ds:si,目的地址为es:di
		jnz Wrong
		
	CheckPassword:
		mov si,offset Password_Origin
		mov di,offset Password
		mov cx,Password_Recived_Number
		REPE cmpsb
		jnz Wrong
	
		mov dx,offset String_Hello_Tip
		mov ah,9
		int 21h
		mov ah,4ch
		int 21h
	Wrong:
		mov dx,offset String_Wrong_Tip
		mov ah,9
		int 21h
		jmp BEG
		
code ends

end BEG 

实际上这两个题目都比较简单,实际上编写的时候只需要注意一下系统调用之后的参数改变就好了。
其中第二个源代码由于比较懒…有以下缺陷:

  • 并没有判断输入字符的个数,而是以回车作为结束循环条件,所以存在缓冲区溢出;
  • 并没有考虑结束条件,这意味着如果不能输入正确的用户名和秘密将不能返回DOS系统

运行结果

第一个题目:
在这里插入图片描述

第二个题目:
在这里插入图片描述

  • 4
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值