问答题 对缓冲区中的一组字符(100个)进行处理:
   (1)把其中的字母字符取出存放在ALPH起的单元中。
   (2)把已取出的字母串中重复的字符删除,并向前递补。
   (3)在不重复的字母串中,把小写字母改为大写字母。如有重复的大写字母,先删除重复大写字母并由后续字符向前递补。
   (4)统计不重复大写字母总数,并显示大写字母串。
   (5)显示处理后的字符串。
   按上述要求分别编写子程序。并构成一个主程序、子程序和具有嵌套调用关系的程序。
【正确答案】DATA  SEGMENT
   A       DB  'A23HJL4KJ6LJ7L5L56JKJLLJK75KJ2Lafbgmn……'
   ALPH    DB   100DUP(?)    ;字母字符存储区
   ALPH1  DB   00H    ;统计字母字符数量
   DEAL    DB   00H    ;删除重复字母字符数量
   LOCASE  DB   30DUP(?)    ;只有不重复大写字母的字符串存储区
   COUNT   DB   0   ;统计大写字母的个数
   DATA ENDS
   CODE SEGMENT
     ASSUME  CS: CODE,DS: DATA
   START: MOV  AX,DATA
          MOV  DS,AX
          MOV  SI,OFFSET A
          MOV  DI,OFFSET ALPH
          MOV  CX,100
          CALL DEDT
          CALL LOC
          CALL DISP
          MOV  AH,4CH    ;返回DOS
          INT  21H
          CODE ENDS
          ;删除数字子程序
   DEDT PROC
   BEG:   INC  SI    ;指向下一个字符
          MOV  AL,[SI]    ;取第一个字符
          CMP  AL,'9'    ;寻找字母字符
          JB   BEG    ;转取下一个字符
          MOV  [DI],AL    ;存字母字符
          INC  DI    ;修改指针
          INC  ALPH1   ;统计字母字符个数
          LOOP BEG
   DEDT ENDlP
       ;小写字母转换为大写字母子程序
   LOC   PROC
         MOV  DI,00H    ;将指针回零
         MOV  CX,ALPH1   ;字母字符串长度送CX
   BEG1: MOV  AL,[DI]    ;取第一个字符
         CMP  AL,'a'    ;判断字母大小写
         JB   BEG2
         SUB  AL,20H    ;将小写字母转换为大写字母
         MOV  [DI],AL    ;存回原单元
   BEG2: INC  DI
         LOOP BEG1
         CALL DELO
         RET
         ENDP
        ;删除相同的大写字母,并前移
   DELO  PROC
         MOV  DI,00H    ;置DI到字母字符串首
   BEG4: MOV  DX,DI    ;刚DX保存串首
         MOV  CX,ALPH1   ;取字母字符长度到CX
         SUB  CX,DEAL    ;求剩余串长
         MOV  AL,[DI]    ;取第一个字符到AL中
         MOV  BL,AL    ;保存移动前的字符
   BEG3: CMP  AL,[DI+1]    ;判断当前字符和下一个字符是否相等
         JNZ  NFS    ;不相同,转NFS(未找到)
         MOV  AX,DI    ;相同,为前移做准备,暂存DI地址
         INC  DEAL    ;将DEAL内容加1,表示找到一个相同的字符
         PUSH CX    ;保存CX的内容
   LP1:  MOV  AL,[DI+1]    ;将下一个数前移一位
         MOV  [DI],AL
         INC  DI
         LOOP LP1
         MOV  DI,AX    ;将DI恢复到移动之前
         POP  CX    ;恢复移动前的CX计数
         MOV  AL,BL    ;恢复移动前的AL内容
   NFS:  INC DI
         DEC CX
         JZ    A2   ;判断Cx是否为0,为0表示第一遍结束
         JMP   BEG3   ;第一遍循环
   A2:   MOV   DI,DX    ;恢复DI指针
         INC   DX:
         CMP   DX,ALPH1+DEAL    ;判断是否所有重复的大写字母已经删除
         JNZ   BEG4
   OVER: MOV   AH,4CH
         INT   21H
         RET
         ENDP
                ;统计大写字母数并显示,同时显示大写字母串
   DISP PROC
        MOV  AX,ALPHl
        SUB  AX,DEAL    ;两数之差即为大写字母长度
        MOV  BL,10
        DIV  BL
        MOV  DH,AH    ;保存个位数
        ADD  AL,30H    ;显示十位数
        MOV  DL,AL
        MOV  AH,02H
        INT  21H
        MOV  DL,DH    ;显示个位数
        ADD  DL,30H
        INT  21H
        LEA  SI,ALPH    ;显示大写字母
        MOV  CX,ALPH1
        SUB  CX,DEAL    ;求要显示大写字母字符串长度
   LP2: MOV  DL,[S1]
        ADD  DL,30H
        MOV  AH,02H
        INT  21H
        INC  SI
        LOOP LP2
        RET
        ENDP
   END START
【答案解析】由于字符存在大小写问题,因此共计有62个字符,分别为0~9,A~Z,a~z。为简化程序设计,将缓冲区中的字符都看作有效字符。本程序分三步:首先将0~9字符从缓冲区删除,其次将a~z字符改为对应的大写字符,最后删除字符串中有重复的大写字母。本程序最后的字符串长度最多不能超过26个大写字母的长度,否则程序有误。本题第(2)部分和第(3)部分要求基本类同,此处只给出第(3)部分源程序。