汇编实验之字符、字符串

1、题目描述:
  编一个程序,实现从键盘输入一个长度不超过300个字符的串(以回车键作为输入结束),然后在下一行以倒序输出所输入的字符。

DATAS SEGMENT
    string db 301 dup('$') 
    ctrl db 0ah,0dh,'$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    lea bx,string
    mov cx,0
lp1:mov ah,1
    int 21H     ;1号调用输入字符将对应字符ASCII码送入AL中
    cmp al,0dh  ;判断是否为回车,回车ASCII码为0dh
    je lp2      ;结果相等则跳转到lp2的位置
    mov [bx],al
    inc bx
    inc cx      ;记录后面使用LOOP指令需要记录的循环次数
    jmp lp1
lp2:dec bx
    mov dl,[bx]
    mov ah,2    ;2号调用将DL寄存器中的字符显示出来
    int 21H
    loop lp2
exit:MOV AH,4CH ;返回DOS
    INT 21H
CODES ENDS
    END START

解题思想:
①输入字符串采用的是一号功能调用,即循环输入一个个字符,输入的字符会首先存在AL中,将输入的字符存放在相应的地址空间。后面输出字符时从地址空间里面取出。每存放一个字符,CX+1,即记录字符个数,作为后面循环输出字符的次数。
②判断输入字符是否为回车字符,是回车字符,则开始实现逆序输出,否则继续输入字符。
②逆序输出字符串采用的是二号功能调用,即一个一个输出相应字符,输出的字符要从DL中取,因此要把原存在地址空间里的字符先存放在DL中,再进行输出,直到循环结束。


STACKS SEGMENT
    DW 300 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,STACKS
    MOV SS,AX
    mov cx,100
    mov bx,0
L1: MOV AH,01H;从键盘上输入一个字符
    INT 21H
    INC bx;保存字符个数
    CMP al,0dh;判断是不是回车,若不是回车,继续输入字符,压栈保存,若是回车,则跳到L2弹栈输出
    jz L2
    mov ah,0
    PUSH AX
    LOOP L1
L2: mov dl,0dh
    mov ah,02h
    INT 21h;显示回车
    mov dl,0ah
    mov ah,02h
    int 21h;显示换行
    mov cx,bx
L3: pop dx;从栈顶中弹出数放到dx中
    mov ah,02h;二号调用显示单个字符,默认从dl中取数
    INT 21h
    LOOP L3    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

2、题目描述:
  先输出字符串“BASED ADDRESSING”。 然后在下一行逆序输出字符串“BASED ADDRESSING”。

DATAS SEGMENT
    STRING DB "BASED ADDRESSING",0DH,0AH,'$'
    LEN EQU $-STRING   ;表达式赋值操作
    ;LEN中装的是"BASED ADDRESSING"+0DH+0AH的长度
DATAS ENDS

STACKS SEGMENT
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX

    LEA DX,STRING
    MOV AH,9           ;9号调用,输出字符串
    INT 21H
    
    LEA SI,STRING
    ADD SI,LEN   
    SUB SI,03H         ;SI指向字符串的末尾一个字符G
    MOV CX,LEN
    SUB CX,02H         ;"BASED ADDRESSING"字符串的长度
LOP1:
    MOV AH,02H         ;2号调用输出字符
    MOV DL,[SI]
    INT 21H
    DEC SI
    LOOP LOP1
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

解题思想:
①定义字符串,求出字符串长度,作为后面输出字符的循环次数。
②根据字符串首地址+偏移量找到最后一个字符的地址,从而输出地址里面的内容,即字符。

3、题目描述:
  试编写一段程序,要求对键盘输入的小写字母用大写字母显示出来。

DATAS SEGMENT
    CAPITAL DB 0DH,0AH,'$'
    S DB 0DH,0AH,"Please enter a lowercase letter:",'$'
DATAS ENDS

STACKS SEGMENT
    
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    MOV CX,5
L:  MOV AH,1
    INT 21H
    MOV BL,AL
    CMP BL,61H    
    ;判断输入的字符是否为小写字母,若为小写字母则提示输入小写字母,否则跳至将小写字母转为大写字母输出
    JB  EXCEPTION 
    CMP BL,7AH
    JNB EXCEPTION
    
    LEA DX,CAPITAL
    MOV AH,9
    INT 21H
    MOV DL,AL
    SUB DL,20H    ;小写字母转为大写字母
    MOV AH,2
    INT 21H
    JMP FINAL
    
EXCEPTION:
    LEA SI,S
    MOV DX,SI
    MOV AH,9
    INT 21H
    LOOP L
    
FINAL:
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

解题思路:将小写字母转换大写字母需-20H。

4、题目描述:
  编写程序,从键盘接收一个小写字母,然后找出它的前导字母和后续字母,再按顺序显示这三个字符。

DATAS SEGMENT
    STRING DB "zabcdefghijklmnopqrstuvwxyza"
    SPACE DB 0DH,0AH,'$'
DATAS ENDS

STACKS SEGMENT
    
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
       MOV AX,DATAS
       MOV DS,AX

       MOV AH,1    ;输入并回显测试的一个小写字母
       INT 21H     ;字母默认存放在AL中
       LEA DX,SPACE
       MOV AH,9
       INT 21H
       
       LEA SI,STRING;在字符串string中查找输入的字母
 L:    INC SI       ;第一个字母没有前导字母,所以首地址要先加一
       CMP AL,[SI]
       JNZ L        ;与jne用法相同,结果不为0/不相等则跳转
       
       DEC SI       ;显示前导字母、输入字母和后续字母
       MOV CX,3
 L1:   MOV DL,[SI]
       MOV AH,2  
       INT 21H
       INC SI
       LOOP L1
             
       MOV AH,4CH
       INT 21H
CODES ENDS
    END START

解题思路:
①这里有个字符串定义的技巧,如果定义字符串为"abcd…xyz",那么当输入a时或z时,就没法找到前导字母或者是后续字母,所以定义字符为:
“zabcdefghijklmnopqrstuvwxyza”。
②将输入字符与字符串中字母依次进行比较找到在字符串中对应输入字符的地址,根据此找到前导字母的地址,依次可找寻输入字母和后续字母的地址,直接循环输出。

5、题目描述:
  试编写一段程序,要求比较两个字符串string1和string2所含字符是否相等,如相等则显示“MATCH”, 若不相同则显示“NO MATCH”.

DATAS SEGMENT
    STRING1 DB "A STRING"
    COUNT1 DW $-STRING1
    STRING2 DB "STRING"
    COUNT2 DW $-STRING2
    ANSWER1 DB 'MATCH','$'
    ANSWER2 DB 'NO MATCH','$'
DATAS ENDS

STACKS SEGMENT 
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
       
    MOV AX,COUNT1 ;比较字符串长度是否相同
    MOV BX,COUNT2
    CMP AX,BX
    JNZ NEXT      ;与JNE用法相同,结果不为0或不相等则跳转
    
    MOV CX,COUNT1 ;循环比较字符串的每个字符
    LEA SI,STRING1
    LEA DI,STRING2
    
L:  MOV AL,[SI]
    CMP AL,[DI]
    JNZ NEXT      ;如果不相同就jmp到next段执行
    INC SI
    INC DI
    LOOP L
        
    LEA DX,ANSWER1;两个字符串匹配
    MOV AH,9
    INT 21H
    JMP FINAL
    
NEXT: 
    LEA DX,ANSWER2;两个字符串不匹配
    MOV AH,9
    INT 21H
    
FINAL:   
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

解题思路:①先比较字符串长度②依次比较各个字符

DATAS SEGMENT
    STRING1 DB 'ABCDE',0DH,0AH,'$';此处输入数据段代码 
    STRING2 DB 'ABCDF',0DH,0AH,'$'
    STRING3 DB 'MATCH',0DH,0AH,'$' 
    STRING4 DB 'NO MATCH',0DH,0AH,'$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    mov cx,100
    mov di,offset string1;此处输入代码段代码
    mov si,offset string2
L1: mov al,[di];把字符依次循环送入al,ah寄存器中
    mov ah,[si]
    inc di
    inc si
    cmp al,ah;比较字符是否相等,若相等则往下比较字符是否为回车,若不相等输出‘NO MATCH’
    jnz L2
    cmp al,0DH;比较字符是否为回车符,若不是回车符,则用循环比较下一个字符,若是回车符输出'MATCH'
    jz L3
    LOOP L1
L2:mov dx,offset string4
   mov ah,9
   int 21h
   jmp L4
L3:mov dx,offset string3
   mov ah,9
   int 21h
L4:MOV AH,4CH
   INT 21H
CODES ENDS
    END START

6、题目描述:
  键盘上输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,并显示计数结果。

DATAS SEGMENT
    STRING DB 128,?,128 DUP('$')  ;字符串的定义
    CRLF DB 0DH,0AH,24H     ;'$'的ASCII码为24H
    COUNT DW 0
    NUM DW 0  
DATAS ENDS

STACKS SEGMENT
    
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    LEA DX,STRING ;键盘输入字符串
    MOV AH,0AH
    INT 21H
    
    LEA DX,CRLF
    MOV AH,9
    INT 21H
    
    LEA SI,STRING+1;CX存放着字符串个数
    MOV CL,[SI]
    MOV CH,0
    LEA DI,STRING+2;从实际字符串开始
    
L1: MOV AL,[DI]
    INC DI
    CMP AL,30H   ;看是否为数字字符
    JL L2
    CMP AL,39H
    JG L2
    DEC NUM      ;如果是数字,NUM先减一后再加一
    
L2: INC NUM
    LOOP L1
    
    MOV CX,0
    MOV AX,NUM
    
L3: MOV BL,10  
    DIV BL        ;字节操作
    PUSH AX       ;PUSH、POP只能做字操作,只能先把AX压栈
    INC CX        ;记录循环次数
    MOV AH,0      ;余数
    CMP AL,0      ;商
    JNZ L3        ;商不为0则继续除
    
L4: POP AX
    MOV DL,AH     ;只显示余数,因此只将余数放入DL寄存器中
    ADD DL,30H    ;将数字字符转换为对应的ASCII码值
    MOV AH,2
    INT 21H
    LOOP L4
    
    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

解题思路:
①定义字符串,完成字符串的输入。②从字符串第一个字符地址开始,依次判断是否为非数字字符,若为则计数,直到字符串末尾。③输出计数个数,将计数数据不断除10,每次除10将余数压栈,直到商为0,则将余数依次出栈并显示出来。

7、题目描述:
  从键盘上输入一串字符(用回车键结束,使用10号功能调用。)放在STRING中,试编制一个程序测试字符串中是否存在数字。如有,则把CL的第5位置1,否则将该位置置0。

DATAS SEGMENT
    STRING DB 128,?,128 DUP('$') 
DATAS ENDS

STACKS SEGMENT
    
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX

    LEA DX,STRING
    MOV AH,0AH
    INT 21H
    
    LEA SI,STRING+1
    MOV CL,[SI]    ;循环次数=实际字符数
    MOV CH,0
    INC SI
    
L:  MOV AL,[SI]    ;判断是否有字符是数字
    CMP AL,30H
    JL L1
    CMP AL,39H
    JG L1
    OR CL,00100000B;有数字则CL第五位置一
    JMP NEXT
 
L1: 
    INC SI
    LOOP L
    
L2: AND CL,11011111B;循环结束,没有发现字符是数字,CL第五位置零
    
NEXT:
    MOV AH,4CH
    INT 21H    
    
CODES ENDS
    END START

解题思路:
①定义字符串,完成字符串的输入。②若判断有数字字符,将CL第5位置1,并退出程序。③若到字符串的末尾,都没有数字字符,则将CL第5位置0。注意:第5位是从0开始算起。

你可能感兴趣的:(汇编语言程序设计实验,字符串)