NO TIME, BUT COURAGE, BUT BEAUTY(汇编小程序)

程序题目:

编写一个程序。 先从键盘输入一个字符串(有英文字母,可能也有数字),然后显示其中数字符的个数、英文字母的个数和字符串的长度;字符串中不能有空格,若有将其删除,并将改变后的字符串按相反的顺序显示出来;输入第二个字符串,显示的时全都以‘*’显示,然后将输入的字符串与前面处理后的字符串比较是否相同,若相同,输出“Password Right!”,否则输出 “Password Error!”。
样例:

题目分析:这个题目比较直白,有几个要注意的地方

1)个人在处理输入原始的密码并计算其中的字母和数字的长度时,所用的方法是单个字符输入(调用中断),每次输入都检查是否是回车,是否是空格,是否是数字或是字母;
2)在输出长度时,如果长度小于10,可以直接将二进制表示与‘0’相加再用字符的形式输出,但是当长度大于10就行不通了,要把十位和个位分离出来;所用的方法是将长度去除以10,这样div会直接把个位和十位分开;

代码:

DATAS SEGMENT
    MSG  DB      "Please input a string:",  '$'
    MSG1 DB      "The number of alphabet:", '$'
    MSG2 DB      "The number of digit:", '$'
    MSG3 DB      "The length of string: ",'$'
    MSG4 DB      "The opposite direction string: " ,'$'
    MSG5 DB      "Please input password:",'$'
    MSG6 DB      "The result:", '$'
    MSG7 DB      "Password Right",'$'
    MSG8 DB      "Password Error", '$'
    DIG_NUM DB    0  ;数字长度
    ALP_NUM DB    0   ;字母长度
    BLANK_NUM DB  0   ;空格个数
    FLAG DB       '*', '$'
    
    PASSWORD DB 30 DUP ('$')  ;密码内容与长度
    PASSWORD_LEN DB 0
     
    TEST_PASS DB 30 DUP ('$') ;输入的测试密码内容与长度
    TEST_PASS_LEN DB 0
    
    CRLF DB 0DH, 0AH, '$' ;回车,换行 结束
DATAS ENDS

STACKS SEGMENT
    DB 8 DUP (0)
    DB 8 DUP (0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES, DS:DATAS, SS:STACKS
START: ;PROC FAR ;主函数 
    MOV AX, DATAS
    MOV DS, AX
    MOV AX, STACKS
    MOV SS,AX
    ;MOV AX, CODES  ;怎么回事
    ;MOV CS,AX
    
    LEA DX, MSG
    MOV AH, 9
    INT 21H
    ;输入并处理密码,处理指去空格并同时计算各种长度
    LEA DI, PASSWORD
    CALL SET_AND_DEAL_POSSWORD
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    ;输出各种长度
    LEA DX, MSG1
    MOV AH, 9
    INT 21H
    
    MOV AL, ALP_NUM
    MOV AH, 0
    CALL OUTPUT_LEN
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    
    LEA DX, MSG2
    MOV AH, 9
    INT 21H
    
    MOV AL, DIG_NUM
    MOV AH, 0
    CALL OUTPUT_LEN
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    
    LEA DX, MSG3
    MOV AH ,9
    INT 21H
    
    MOV AL, PASSWORD_LEN
    ADD AL, BLANK_NUM
    MOV AH, 0
    CALL OUTPUT_LEN
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    ;输出真正的字符串,有空格就反序输出
    LEA DX, MSG4
    MOV AH, 9
    INT 21H
    
    ;LEA DX, PASSWORD
    ;MOV AH, 9
    ;INT 21H
    
    LEA SI, PASSWORD
    CALL OUTPUT_PASSWORD
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    
    ;输入密码
    LEA DX, MSG5
    MOV AH, 9
    INT 21H
    
    LEA DI, TEST_PASS
    CALL INPUT_PASSWORD
    
    LEA DX, CRLF
    MOV AH, 9
    INT 21H
    
    ;测试密码
    ;输入参数
    LEA SI, TEST_PASS
    LEA DI, PASSWORD
    MOV AL, [PASSWORD_LEN]
    MOV AH, [TEST_PASS_LEN]
    
    CALL IS_RIGHT
    
    LEA DX,CRLF
    MOV AH,9
    INT 21H
    
    MOV AH,4CH
    INT 21H

;******************* SET_AND_DEAL_POSSWORD ***************
SET_AND_DEAL_POSSWORD PROC NEAR
  SO:
    MOV AH, 1
    INT 21H
    CMP AL, 0DH ;输入回车结束
    JNZ NOT_END
    MOV AH, '$'
    MOV [DI], AH ;输入字符串结束符
    RET
    
  NOT_END:
    CMP AL, ' '
    JZ BLANK_CASE
    
    MOV [DI], AL ;把数据装入密码中
    INC DI
    
    CMP AL, 'A'; 'A' = 65, 'a' = 97, '9' = 57
    JB  DIGIT_CASE ; 数字的情况
    JMP ALPHABEG_CASE ;字母的情况
    
  BLANK_CASE:
    INC BLANK_NUM
    JMP SO
    
  DIGIT_CASE:
    INC DIG_NUM
    INC PASSWORD_LEN
    JMP SO
    
  ALPHABEG_CASE:
    INC ALP_NUM
    INC PASSWORD_LEN
    JMP SO

SET_AND_DEAL_POSSWORD ENDP

;*************** OUTPUT_LEN ************
OUTPUT_LEN PROC NEAR
    MOV BL, 10
    DIV BL
    
    MOV BH, AH ;保存余数
    
    MOV DL, AL
    CMP DL, 0
    JZ OL_S1  ;如果十位为0不输出
    ADD DL, '0'
    MOV AH, 2
    INT 21H
    
  OL_S1:
    MOV DL, BH ;得到个位
    ADD DL, '0'
    MOV AH, 2
    INT 21H
    RET
    
OUTPUT_LEN ENDP
;**************************
OUTPUT_PASSWORD PROC NEAR
    CMP BLANK_NUM, 0
    JNZ OP_S1 ;反序
    ;ELSE
    MOV DX, SI
    MOV AH, 9
    INT 21H
    RET
    
  OP_S1:
    MOV DL, PASSWORD_LEN
    MOV DH, 0
    ADD SI, DX ;从后面开始
    DEC SI
    ;按字符输出
    MOV CL, PASSWORD_LEN
    MOV CH, 0
  OP_S2:
    MOV DL, [SI]
    MOV AH, 2
    INT 21H
    DEC SI
    LOOP OP_S2
    
    RET
OUTPUT_PASSWORD ENDP

;********************** INPUT_PASSWORD **************
INPUT_PASSWORD PROC NEAR
    S2:
    MOV AH, 8
    INT 21H
    CMP AL, 0DH ; 判断是不是输入换行符
    JNZ IP_S3
    MOV AH, '$'
    MOV [DI], AH
    RET
    
  IP_S3:
    MOV [DI], AL;[si]是当前地址,相当于c语言中的*pt = value; 
    INC DI
    INC [TEST_PASS_LEN]
    MOV DL, '*'
    MOV AH, 2
    INT 21H
    JMP S2
    
INPUT_PASSWORD ENDP

;*************************
IS_RIGHT PROC NEAR
    CMP AL, AH
    JZ S3
    LEA DX, MSG8 ;长度不相等
    MOV AH, 9
    INT 21H
    RET
    
     S3:
    MOV CL, PASSWORD_LEN
    MOV CH, 0
    
   S4: 
    MOV AL, [SI]
    MOV AH, [DI]
    INC SI
    INC DI
    CMP AL, AH
    JNZ S5
    LOOP S4
    ;right
    LEA DX, MSG7
    MOV AH,9
    INT 21H
    RET
  S5:
    ;error
    LEA DX, MSG8
    MOV AH,9
    INT 21H
    RET

IS_RIGHT ENDP
;********
CODES ENDS
END START
NO TIME, BUT COURAGE, BUT BEAUTY

 经验总结:

1)写代码,可读性,可重用性,简洁性要保证, BUT BEAUTY;

2)对于自己的代码,如果自己都不能清晰地表达出思路,那就该反省反省,并采取行动,NOT TIME, BUT COURAGE.

原文地址:https://www.cnblogs.com/kinthon/p/4497186.html