汇编语言(Assembly Language)习题:键盘输入任意一个字母,显示其前导字母、字母自身、后续字符共三个字母。

题目:键盘输入任意一个字母,显示其前导字母、字母自身、后续字符共三个字母。

逐句详解

如有前置知识障碍,请移步本专栏前两篇文章:汇编语言(Assembly Language)常用的系统功能调用
汇编语言(Assembly Language)习题:键盘输入一个字符串,试将其中的小写字母转换为大写字母,其它字符保持不变。

DATAS SEGMENT

DATAS SEGMENT
    ;此处输入数据段代码  
    MSG1 DB 'Please input a letter :$'
    MSG2 DB 0dh,0ah,'The previous letter is :$'
    MSG3 DB 0dh,0ah,'The next letter is :$'
    
DATAS ENDS

这里主要是要输入的语句,使用9号调用输出。

CODES SEGMENT(1)

    MOV DX,OFFSET MSG1             ;显示提示信息1
	MOV AH,09H
    INT 21H
	
	MOV AH,01H                    ;等待用户输入
	INT 21H                       ;从键盘输入字符的ASCII码送入寄存器AL中,并送显示器显示。
	
	MOV BX,AX                     ;将AX的值赋值给BX,相当于复制了一份AX的数据,至于为什么请看后文
	
	CMP AL,'A'
	JZ changeA                  ;如果AL的值与'A'相等,就跳转到changeA ,类似C语言中的goto语句
	CMP AL,'a'
	JZ changea1
	CMP BL,'Z'                   ;这里也可以直接写成CMP AL,'Z' ,主要是为了方便辨识
	JZ changeZ
	CMP BL,'z'
	JZ changez1
	
    DEC AL                  ;-1计算前导字符
	INC BL                  ;+1计算后继字符
	JMP PUSH1

本题看似简单,却有一点易错,对于非 ‘a’,‘A’,‘z’,‘Z’ 字符只需要输出其前一个ASCII码和后一个ASCII码即可,而 ‘a’,‘A’,‘z’,‘Z’ 则应该输出’a’,‘A’前置 ‘z’,‘Z’ ,‘z’,‘Z’ 后置’a’,‘A’ ,应该有另外的程序,这里需要使用跳转指令:
这组指令单独判断5个状态标志之一:
(1) JZ/JE和JNZ/JNE
利用零标志ZF,判断结果是否为零(或相等)
(2)JS和JNS
利用符号标志SF,判断结果是正是负
(3)JO和JNO
利用溢出标志OF,判断结果是否产生溢出
(4)JP/JPE和JNP/JPO
利用奇偶标志PF,判断结果中“1”的个数是偶是奇
(5)JC/JB/JNAE和JNC/JNB/JAE
利用进位标志CF,判断结果是否进位或借位

CODES SEGMENT(2)

changeA:  ADD AL,25
          INC BL 
          JMP PUSH1	
changea1:  ADD AL,25
           INC BL 
           JMP PUSH1	
changeZ:	SUB BL,25
            DEC AL
           JMP PUSH1
changez1:	SUB BL,25
            DEC AL
            JMP PUSH1    
	                  
PUSH1:PUSH BX                 ;保存BX内容即后继字符
	  PUSH AX                 ;保存AX内容即前导字符
	  
	MOV DX,OFFSET MSG2      ;显示提示信息2
	MOV AH,09H
    INT 21H
	
	POP AX                ;AX内容即前导字符出栈
	MOV DL,AL            ;AL内容送入DL(存放的是ASCLL码),准备输出
	MOV AH,02H            ;输出前导字符
	INT 21H
	
	
	MOV DX,OFFSET MSG3     ;显示提示信息3
	MOV AH,09H
    INT 21H
	
	POP BX                  ;BX内容即后继字符出栈
	MOV DL,BL            ;BL内容送入DL(存放的是ASCLL码),准备输出
	MOV AH,02H               ;输出后继字符
	INT 21H

对于’a’,‘A’,‘z’,‘Z’ 对输出的AL,BL值特殊处理,最后殊途同归到PUSH1:将BX,AX内容压栈,需要时再取出。这样可以避免寄存器放不下那么多数据,堆栈是先进后出方式工作,如果用好会对程序优化起到很大帮助。
对于16位指令:
进栈指令: PUSH SRC
执行操作: (SP) <-(SP) – 2
( (SP)+1, (SP) ) <- (SRC)
出栈指令: POP DST
执行操作: (DST) <- ( (SP)+1, (SP) )
(SP) <- (SP) + 2
堆栈:‘先进后出’的存储区,存在于堆栈段中,SP 在
任何时候都指向栈顶。
注意:
* 堆栈操作必须以字为单位。
* 不影响标志位*
* 不能用立即寻址方式 PUSH 1234H (error)
* DST不能是CS POP CS (error)

完整代码:

DATAS SEGMENT
    ;此处输入数据段代码  
    MSG1 DB 'Please input a letter :$'
    MSG2 DB 0dh,0ah,'The previous letter is :$'
    MSG3 DB 0dh,0ah,'The next letter is :$'
    
DATAS ENDS

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

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    
    MOV DX,OFFSET MSG1             ;显示提示信息1
	MOV AH,09H
    INT 21H
	
	MOV AH,01H                    ;等待用户输入
	INT 21H
	
	MOV BX,AX
	
	CMP AL,'A'
	JZ changeA
	CMP AL,'a'
	JZ changea1
	CMP BL,'Z'
	JZ changeZ
	CMP BL,'z'
	JZ changez1
	
    DEC AL                  ;-1计算前导字符
	INC BL                  ;+1计算后继字符
	JMP PUSH1
	
changeA:  ADD AL,25
          INC BL 
          JMP PUSH1	
changea1:  ADD AL,25
           INC BL 
           JMP PUSH1	
changeZ:	SUB BL,25
            DEC AL
           JMP PUSH1
changez1:	SUB BL,25
            DEC AL
            JMP PUSH1    
	                  
PUSH1:PUSH BX                 ;保存BX内容即后继字符
	  PUSH AX                 ;保存AX内容即前导字符
	  
	MOV DX,OFFSET MSG2;显示提示信息2
	MOV AH,09H
    INT 21H
	
	POP AX                ;AX内容即前导字符出栈
	MOV DL,AL            ;AL内容送入DL(存放的是ASCLL码),准备输出
	MOV AH,02H            ;输出前导字符
	INT 21H
	
	
	MOV DX,OFFSET MSG3     ;显示提示信息3
	MOV AH,09H
    INT 21H
	
	POP BX                  ;BX内容即后继字符出栈
	MOV DL,BL            ;BL内容送入DL(存放的是ASCLL码),准备输出
	MOV AH,02H               ;输出后继字符
	INT 21H
    
    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

运行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值