如何用汇编编写以下程序?
发布网友
发布时间:2022-04-22 05:06
我来回答
共5个回答
热心网友
时间:2023-06-28 01:06
感楼主诚意,费了九牛二虎之力,方才完成。不知能否满足要求。
; 本程序通过编译,运行正确
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 p(?) ; 用户名
Name_Lenth db ? ;用户名实际长度
Pass_Word db Name_Len p(?) ; 密码
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 ;编译到此结束
热心网友
时间:2023-06-28 01:06
一个密码输入程序,错误的话就报警。。。
你可以仿写
STACK SEGMENT STACK
DW 64 DUP(?)
STACK ENDS
DATA SEGMENT
PASSWORD DB '1','2','3','4','5','6'
WRR DW 4553,4508,3615,4553,4508,3615,0000H
RII DW 4553,0000H
REPTT DW 4553,4508,3615,0000H
ERROR DB 0DH,0AH,'Keycode error!','$'
FA DB 0DH,0AH,'RETURN(F1)','$'
FB DB 0DH,0AH,'EXIT(F2)','$'
FC DB 0DH,0AH,'modify keycode(F1)','$'
right DB 0DH,0AH,'Your are right!','$'
bu DB 0DH,0AH,'NEW PASSWORD:','$'
buf DB 0DH,0AH,'REPEAT:','$'
INP DB 0DH,0AH,'INPUT OLD PASSWORD:','$'
MO DB 0DH,0AH,'Keycode modification succeed!','$'
input DB 0DH,0AH,'INPUT PASSWORD:','$'
NEW DB 6 DUP(?)
NEW2 DB 6 DUP(?)
DATA ENDS
CODE SEGMENT
start proc far
ASSUME CS:CODE,DS:DATA
MAIN: MOV AX,DATA
MOV DS,AX
MOV BX,03H
STA: MOV CX,06H
call appear2
MOV DX,OFFSET INPUT
MOV AH,9
INT 21H ;显示INPUT PASSWORD:
MOV SI,OFFSET NEW
JU: CALL INN
LOOP JU ;输入密码
MOV CX,06H
MOV DI,OFFSET PASSWORD
MOV SI,OFFSET NEW
COMP:
MOV AL,[DI]
CMP [SI],AL
JNZ WR
INC SI
INC DI
LOOP COMP
JMP RI
WR: MOV SI,OFFSET WRR
CALL RING
MOV DX,OFFSET ERROR
MOV AH,9
INT 21H ;显示ERROR
call appear1
call delay
AA6: DEC BX
CMP BX,00H
JZ vvv
JMP STA
vvv: JMP OVER
AA7: JMP WR
RI: MOV DX,OFFSET right
MOV AH,9
INT 21H
call appear2
MOV SI,OFFSET RII
CALL RING
aa:
MOV AH,00H
INT 16H
CMP AH,3CH
JZ vv
CMP AH,3DH
JZ REPT2
JMP aa
vv: JMP OVER
REPT2: MOV DX,OFFSET INP
MOV AH,9
INT 21H
MOV DI,OFFSET PASSWORD
MOV CX,06H
MOV SI,OFFSET NEW
A1: call INN
LOOP A1
MOV CX,06H
MOV SI,OFFSET NEW
MOV DI,OFFSET PASSWORD
COMPP:
MOV AL,[DI]
CMP [SI],AL
JNZ AA7
INC DI
INC SI
LOOP COMPP
K1: MOV DX,OFFSET bu
MOV AH,9
INT 21H
MOV SI,OFFSET NEW
MOV CX,6
K2: CALL INN
LOOP K2
MOV DX,OFFSET buf
MOV AH,9
INT 21H
MOV SI,OFFSET NEW2
MOV CX,6
K3: CALL INN
LOOP K3
MOV SI,OFFSET NEW
MOV DI,OFFSET NEW2
MOV CX,6
K4: MOV AL,[SI]
CMP [DI],AL
JNZ K1
INC SI
INC DI
LOOP K4
MOV CX,06H
MOV SI,OFFSET PASSWORD
MOV DI,OFFSET NEW
K5: MOV AL,[DI]
MOV [SI],AL
INC SI
INC DI
LOOP K5
MOV SI,OFFSET REPTT
CALL RING
call appear1
MOV DX,OFFSET MO
MOV AH,9
INT 21H ;
;报警延时
call delay
JMP STA
OVER: mov ah,4ch
int 21h
;INT 20H
RET
start endp
INN PROC
push bx
MOV AH,00H
INT 16H
CMP AH,3DH
JZ BB
CMP AH,3Ch
JZ BBB
MOV [SI],AL
INC SI
MOV DL,'*'
MOV AH,2
INT 21H
pop bx
RET
BB: pop bx
JMP REPT2
BBB: JMP OVER
INN ENDP
RING PROC
push bx
mov al,03h
out 61h,al
MOV AL,0B6H
OUT 43H,AL
CC1: MOV DX,[SI]
CMP DX,0000H
JNZ CC3
MOV AL,90H
OUT 61H,AL
pop bx
RET
CC3:
OUT 42H,AL
XCHG AL,AH
OUT 42H,AL
INC SI
mov DI,500
CC5: mov CX,65534
CC4:
push AX
pop AX
loop CC4
dec DI
cmp DI,00h
jnz CC5
jmp CC1
RING ENDP
DELAY PROC ;实现5秒的准确延时子过程
push bx
MOV AH,2CH ;取系统时间
INT 21H
MOV BH,DH
ADD BH,05H ;时间秒数加五
YY: MOV AH,2CH
INT 21H
CMP BH,DH;延时五秒到了吗?没有就继续去取系统时间
JZ RT3
JMP YY
RT3: pop bx
RET
DELAY ENDP
appear1 proc
push bx
mov DX,OFFSET FA
MOV AH,9
INT 21H
MOV DX,OFFSET FB
MOV AH,9
INT 21H
pop bx
RET
appear1 endp
appear2 proc
push bx
mov dx,offset FC
mov ah,9
int 21h
mov dx,offset fb
mov ah,9
int 21h
pop bx
ret
appear2 endp
CODE ENDS
END MAIN
热心网友
时间:2023-06-28 01:07
请给出具体要求,然后才能编写。
热心网友
时间:2023-06-28 01:07
这种小功能每种编程工具都可以实现,不过你总要说出是想用哪种吧.....
热心网友
时间:2023-06-28 01:08
估计汤叔这会儿正给你写呢,等着吧