汇编学习之一(字符串输入、匹配、倒序、输出操作)

没想到第一篇博客竟然是汇编程序,晕头转向捣鼓了一天终于码完+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++那么多啦。
 
 
posted @ 2015-05-14 21:04  CheerM  阅读(2631)  评论(0)    收藏  举报