没想到第一篇博客竟然是汇编程序,晕头转向捣鼓了一天终于码完+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++那么多啦。