没想到第一篇博客竟然是汇编程序,晕头转向捣鼓了一天终于码完+debug。各位看官凑合着看吧,如发现哪里有问题,请留言指出~~thx!
首先是,程序要实现的功能是,输入一个数字L,接着就输入一组长度为L的字符串str1(只能由字符和数字组成,若有空格,则要剔除),返回这组字符串中数字和字符的个数,以及总的长度,再把字符串str1倒序输出。然后,输入第二个字符串str2(显示的时候全部以'*'显示),若str2与倒序之后的str1相匹配,则输出"password right!!",否则输出"password error!!"
DATA SEGMENT A DB 10 DUP('$'),'$' B DB 10 DUP('$'),'$' C DB 10 DUP('$'),'$' COUNT_NUM DB 0 COUNT_CHAR DB 0 COUNT_SUM DB 0 ;ASCII码 M1 DB 'Input the length of a string:$' M2 DB 'input a string:$' M3 DB 'numbers of digital:$';数字个数 M4 DB 'numbers of sign:$';字符个数 M5 DB 'The length of the string is:$'; M6 DB 'Password Right!!$' M7 DB 'Password Error!!$' M8 DB 'normal order output:$' M9 DB 'inverted order output:$' DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA MAIN PROC FAR START:MOV AX,DATA MOV DS,AX LEA SI,A LEA DI,B CALL SUBR1 ;输出询问语句M1 CALL CRLF ;回车换行 CALL SUBR2 ;输入字符串长度,并且把长度存在BL中 CALL CRLF CBW MOV CX,BX ;把字符串长度放在CX中存储 MOV BX,0 ;清空BX CALL SUBR3 ;输出引导语句M2 CALL CRLF CALL SUBR4 ;输入字符串,并且计算个数 CALL CRLF MOV DX,OFFSET M3 ;引导语句M3 MOV AH,09H INT 21H CALL CRLF MOV AH,02H ;显示数字个数 MOV DL,BH ADD DL,30H INT 21H CALL CRLF MOV COUNT_NUM,DL ;把数字个数存入count_num MOV DX,OFFSET M4 ;引导语句M4 MOV AH,09H INT 21H CALL CRLF MOV AH,02H ;显示字符个数 MOV DL,BL ADD DL,30H INT 21H CALL CRLF MOV COUNT_CHAR,DL ;把字符个数存入count_char MOV DX,OFFSET M5 ;引导语句M5 MOV AH,09H INT 21H CALL CRLF MOV DL,BH ;用DL来存储总字符数SUM,这需要把BL、BH相加 ADD DL,BL ADD DL,30H ;加上30H,转化为ASCII码 MOV AH,02H ;结果作为单个字符输出显示 INT 21H CALL CRLF MOV COUNT_SUM,DL ;把字符串长度存入count_sum MOV DX,OFFSET M8 ;引导语句M8 MOV AH,09H INT 21H CALL CRLF MOV SI,OFFSET A MOV DI,OFFSET B MOV BX,0 ;清零BX LOOP1:MOV AH,02 MOV DL,[SI] CMP DL,'$' ;判断是否已经到了字符串末 JZ OVER INT 21H INC SI INC BX ;用BX来计数,计算字符串长度 JMP LOOP1 OVER:CALL CRLF MOV DX,OFFSET M9 ;引导语句M9 MOV AH,09H INT 21H CALL CRLF DEC SI MOV CX,BX ;设置循环计数器 LOOP2:MOV AH,02 MOV DL,[SI] MOV [DI],DL ;在倒序显示的同时,把倒序字符串存储到B中 INT 21H DEC SI INC DI LOOP LOOP2 CALL CRLF MOV SI,OFFSET C MOV CX,BX LOOP3:MOV DI,OFFSET B MOV AH,07 INT 21H MOV [SI],AL INC SI MOV AH,02 MOV DL,'*' INT 21H LOOP LOOP3 CALL CRLF ;调试代码,输出C字符串,查看存储是否正确 ; MOV SI,OFFSET C ; MOV CX,BX ;LOOP5:MOV DL,[SI] ; MOV AH,02 ; INT 21H ; INC SI ; LOOP LOOP5 ; CALL CRLF ;此处为一个匹配B、C内字符串的操作 MOV SI,OFFSET B MOV DI,OFFSET C MOV CX,BX LOOP4:MOV BL,[SI] MOV DL,[DI] CMP BL,DL JNZ OVER2 LOOP LOOP4 MOV DX,OFFSET M6 ;引导语句M6 MOV AH,09H INT 21H CALL CRLF JMP OVER3 OVER2:MOV DX,OFFSET M7 ;引导语句M7 MOV AH,09H INT 21H CALL CRLF OVER3:MOV AH,4CH INT 21H RET MAIN ENDP ;*************************************************** ;输出数字的个数 ;*************************************************** ;输入字符串 SUBR4 PROC D1:MOV AH,01H INT 21H ;输入单个字符 CMP AL,'0' ;AL存储字符 JL D2 CMP AL,'9' JG D3 INC BH ;BH存储数字的个数 MOV [SI],AL INC SI JMP D4 D2:JMP D3 ;判断是否有空格,若有则直接忽视掉,不放入缓存区 D3:CMP AL,' ' JZ D4 INC BL ;BL存储字符的个数 MOV [SI],AL INC SI D4:LOOP D1 RET SUBR4 ENDP ;*************************************************** ;输出引导语句M2 SUBR3 PROC MOV DX,OFFSET M2 MOV AH,09H INT 21H RET SUBR3 ENDP ;*************************************************** SUBR2 PROC MOV AH,01H ;输入单个字符,表示即将输入字符串的长度 INT 21H SUB AL,30H ;ascii码存在AL中,要转为数字 MOV BL,AL RET SUBR2 ENDP ;*************************************************** ;输出引导语句M1 SUBR1 PROC MOV DX,OFFSET M1 MOV AH,09H INT 21H RET SUBR1 ENDP ;*************************************************** ;回车换行 CRLF PROC NEAR MOV DL,0AH MOV AH,02H INT 21H MOV DL,0DH MOV AH,02H INT 21H RET CRLF ENDP ;*************************************************** CODE ENDS END START
好的,简单粗暴滴贴出代码,接下来就是运行结果了:

原来以为把程序中的各个功能分模块,写成子程序调用会减少代码复用,后来发现是我自己想多了。。。这样反倒不利于后期检查,而且写太多子程序不容易清楚寄存器里面存放的东西,回过头来检查就很麻烦(若是注释很清楚的话另说),代码里有几个子程序。。后面懒得改回来了,不过都有注释,可读性应该也还OK的。
这次的编程作业有查找了很多的资料,有参考了汇编大牛们的思路,当然自己去找的话网上也会有很多的资料可以查找,虽然不像C、C++那么多啦。