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

it2023-10-16  72

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

两个题目源代码第一题的源代码第二题的源代码 运行结果

两个题目

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

源代码

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

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

第一题的源代码

.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系统

运行结果

第一个题目:

第二个题目:

最新回复(0)