用汇编语言编写一个程序

感楼主诚意,费了九牛二虎之力,方才完成。不知能否满足要求。

; 本程序通过编译,运行正确

Code Segment

Assume CS:Code,DS:Code

CR equ 000DH

LF equ 000AH

KBBack equ 0008H

Name_Len equ 18 ;用户名最大长度

Pass_Len equ 8 ;密码最大长度

; -------------------------------------

; 将用户名和密码定义为一个结构类型

User Struc ; 成绩单结构类型

User_Name db Name_Len dup(?) ; 用户名

Name_Lenth db ? ;用户名实际长度

Pass_Word db Name_Len dup(?) ; 密码

Pass_Lenth db ? ;密码实际长度

User EndS

; -------------------------------------

; 功能:显示指定地址(Str_Addr)的字符串

; 入口:

; Str_Addr=字符串地址(要求在数据段)

; 用法: Output Str_Addr

; 用法举例:Output PromptStr

Output MACRO Str_Addr

lea dx,Str_Addr

mov ah,9

int 21h

EndM

; -------------------------------------

; 功能:取光标位置

; 入口:无

; 出口:DH=行号,DL=列号

GetCursor Proc Near

PUSH AX

PUSH BX

PUSH CX

PUSH DX

XOR BX,BX

MOV AH,3

INT 10H

MOV Cursor_Row,DH

MOV Cursor_Col,DL

POP DX

POP CX

POP BX

POP AX

RET

Cursor_Row DB ?

Cursor_Col DB ?

GetCursor EndP

; -------------------------------------

; 功能:置光标位置

; 入口:Cursor_Row=行坐标; Cursor_Col: 列坐标)

SetCursor Proc Near

PUSH DX

PUSH CX

PUSH BX

PUSH AX

MOV DH,Cursor_Row

MOV DL,Cursor_Col

XOR BX,BX

MOV AH,2

INT 10H

POP AX

POP BX

POP CX

POP DX

RET

SetCursor EndP

; -------------------------------------

; 窗口上滚指定行数

Roll_Up Proc Near

xor bh,bh ;显示页号

mov ah,8 ;读光标位置的字符和属性

int 10h

mov bh,ah ;上滚窗口空行属性

mov cx,100h ;左上角坐标

mov al,5

mov dx,54fh ;右下角坐标

mov ah,6

int 10h

ret

Roll_Up EndP

; -------------------------------------

; 功能:输入指定位数的用户密码,实际输入的密码字符以“*”显示,并有回空纠错功能

; 入口:di=密码输入缓冲区地址

; 出口:AL=实际输入的密码字符数

Input_PassW Proc Near

push di

mov cx,Pass_Len ;密码最大长度

@@Input: call GetCursor ;取光标位置

mov ah,7 ;从键盘接受一个字符

int 21h

cmp al,CR ;回车符?

jz @@Calc_Chrs ;是,结束密码输入,转去计算实际输入的密码字符数

cmp al,KBBack

jz @@KB_Back ;若是回空键,重新输入

stosb ;保存输入的字符

mov dl,'*'

mov ah,2

int 21h

jmp @@KBBack

@@KB_Back: dec Cursor_Col

inc cx

dec di

@@KBBack: inc Cursor_Col

call SetCursor ;置光标位置

loop @@Input ;接受下一个数字

@@Calc_Chrs:mov cx,di

pop di

sub cx,di

cmp cl,[si.Pass_Lenth]

jnz @@Pass_Err ;密码长度不等

mov cl,[si.Pass_Lenth]

xor ch,ch

push si

lea si,[si.Pass_Word]

cld

repz cmpsb ;比较密码是否正确

pop si

jcxz $+4

@@Pass_Err: clc ;进位标志复位,表示密码不正确

ret

stc ;进位标志置位,表示密码正确

ret

Input_PassW EndP

; -------------------------------------

Again_Input Proc Near

Output Input_Again ;提示:是否重新输入用户名

mov ah,1 ;从键盘接受一个字符

int 21h

or al,20h ;转换成小写,大小写不敏感

cmp al,'y' ;重新输入?

jnz $+7 ;不

call Roll_Up ;窗口上滚指定行数

stc ;进位标志置位,表示重复前面的操作

ret

cmp al,'n' ;不重新输入?

jnz Again_Input ;不是,非有效字母,重新输入

clc ;进位标志复位,表示放弃前面的操作

ret

Again_Input EndP

; -------------------------------------

Users equ 5 ;用户数

Even

User_Inform User <'richcon',7,'12345678',8>

User <'WangMing',8,'21345678',8>

User <'ZhangHongQiao',13,'13245678',8>

User <'LiYan',5,'12435678',8>

User <'XuPengYu',12,'12354678',8>

Prompt_User db 'User name: $'

Prompt_Word db 'Pass word: $'

Empty_Error db 7,CR,LF,CR,LF,'User name is empty.$'

Register_No db 7,CR,LF,CR,LF,'No register.$'

Pass_Error db 7,CR,LF,CR,LF,'Pass word error!$'

Welcome db 7,CR,LF,CR,LF,'WELCOME$',0

Input_Again db CR,LF,CR,LF,'Do you input user name again(y/n)?$'

Start: push cs

pop ds ;使数据段与代码段同段

push cs

pop es ;使附加段与代码段同段

Output Prompt_User ;提示输入用户名

call GetCursor ;取光标位置

Input_Name: call SetCursor ;置光标位置

lea dx,Buffer ;数据缓冲区地址

mov ah,0ah ;键盘缓冲区输入

int 21h

lea si,Buffer[1] ;实际输入的字符数地址

lodsb ;取实际输入的字符数

test al,al ;空串?

jnz Valid_Test ;不是,检测输入的用户是否注册

Output Empty_Error ;提示用户名为空

jmp Input_Name ;重新输入用户名

Valid_Test: mov cx,Users ;注册用户数

lea si,User_Inform ;注册用户信息地址

Valid_Test0:cmp al,[si.Name_Lenth] ;输入的用户名长度=用户名实际长度?

jnz Next_One ;不相等,与下一个注册用户名比较

push cx

push si

lea si,[si.User_Name]

lea di,Buffer[2] ;实际输入的用户名地址

mov cl,al

xor ch,ch

cld

repz cmpsb ;比较用户名是否已注册

stc ;进位标志置位,表示用户名已注册

jcxz $+3

clc ;进位标志复位,表示用户名未注册

pop si

pop cx

jc Input_Pass ;用户名已注册,转去输入用户密码

Next_One: add si,type User ;下一个注册用户信息地址

loop Valid_Test0

Output Register_No ;提示:非注册用户

call Again_Input ;是否继续

jc Input_Name ;进位标志置位,转去重新输入用户名

jmp Exit_Proc ;不重新输入用户名,结束程序

Input_Pass: mov word ptr Cursor_Row,1

call SetCursor ;置光标位置

Output Prompt_Word ;提示输入密码

lea di,Buffer ;密码缓冲区地址

call Input_PassW ;输入密码

jc @@Welcome ;密码输入正确,显示欢迎信息

Output Pass_Error ;提示密码输入错误

call Again_Input ;是否继续

jc Input_Pass ;进位标志置位,转去重新输入密码

jmp Exit_Proc ;不重新输入密码,结束程序

@@Welcome: Output Welcome ;显示欢迎信息

Exit_Proc: mov ah,4ch ;结束程序

int 21h

Buffer db 20 ;数据缓冲区

Code ENDS

END Start ;编译到此结束