例1:输入一个字母,如果是大写就输出它的小写字母,如果是小写就输出它的大写字母,如果是其它的就输出Error
- 定义一个数据来输出错误提示语Error
- 把DATA的首地址传送到DS
- 输出问号
- 键盘输入并存储到BL,回车换行
- 排除A之前的各种符号数字
- 判断是否为大写
- 排除大写Z到小写a中间的一些字符
- 判断是否为小写字母
- 排除Z后一些符号
- @UP_CAP:大写转小写
- @LO_CAP:小写转大写
- @ERROR:输出错误提示
- @END_CASE:结束程序
- 观察ASCII表,可以分为几段,大写A前面一大堆符号数字;大写Z到小写a中间也有一些符号数字;小写z之后也有一些符号数字,需要排除掉
- 大写转小写字母+20H
- 小写转大写字母-20H
.MODEL SMALL
.STACK 100H
.DATA
ERR_MSG DB 'Error$' ;定义数据
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
;把DATA的首地址传送到AX里,AX用来中转,最后传送到DS里
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入并回显
MOV BL,AL ;把键盘输入的内容存储到BL里
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车换行
CMP BL,'A'
;从ASCII编码表里面可以看出比A小的全是符号数字,所以这里直接把用户输入的和A比较相减
JL @ERROR ;如果小于则跳转ERROR
CMP BL,'Z' ;上一步中已经排除掉了符号数字类的,这里是判断是否为大写
JLE @UP_CAP ;如果小于或等于则跳转UP_CAP
CMP BL,'a' ;因为大写Z到小写a中间还有一些字符所以这里也要排除掉
JL @ERROR ;如果小于则跳转ERROR
CMP BL,'z' ;这里是判断是否为小写字母
JLE @LO_CAP ;如果小于或等于就跳转LO_CAP
JMP @ERROR ;观察ASCII表z之后还有一些符号这里用于排除z后面的一些符号
@UP_CAP:
ADD BL,20H ;把用户输入的值加20H,就可以转换为小写字母,BL=BL+20H
MOV DL,BL ;把BL的值传送到DL里准备输出
INT 21H ;输出小写字母
JMP @END_CASE ;直接跳转到END_CASE
@LO_CAP:
SUB BL,20H ;把用户输入的值减20H,就可以转换为大写字母,BL=BL-20H
MOV DL,BL ;把BL的值传送到DL里准备输出
INT 21H ;输出
JMP @END_CASE ;直接跳转到END_CASE
@ERROR:
MOV AH,9 ;9=显示字符串
LEA DX,ERR_MSG ;取ERR_MSG的偏移地址到DX里
INT 21H
@END_CASE:
MOV AH,4CH
INT 21H ;结束程序
MAIN ENDP
END MAIN
例2:用户输入介于-9~9之间的数,储存在BL寄存器中,并输出输入数的绝对值
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV CX,0 ;CX初始化
MOV AH,1
INT 21H ;键盘输入
CMP AL,'-' ;如果输入负号跳转到MINUS
JE @MINUS
CMP AL,'+' ;如果输入加号跳转到PLUS
JE @PLUS
JMP @SAVE ;不是加号和负号的情况
@MINUS:
MOV CX,1 ;CX存储1
@PLUS:
INT 21H ;键盘输入
@SAVE:
SUB AL,30H ;ASCII码转真实数字
MOV BL,AL ;把用户输入的存储到BL里
CMP CX,1 ;CX和1比较
JNE @NEXT1 ;不等于1就跳转NEXT1,NEXT1的功能是 取相反数
NEG BL ;把操作数按位取反加1,也就是取相反数
@NEXT1:
CMP BL,0 ;把用户输入的和0比较
JGE @NEXT2 ;大于等于就跳转NEXT2 如果输入的数是正数就跳转NEXT2直接输出
NEG BL ;取相反数
@NEXT2: ;直接输出
MOV AH,2 ;显示输出
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;回车换行
MOV DL,BL ;把结果存储到DL里,待输出
ADD DL,30H ;转换为ASCII码
INT 21H ;输出
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
- 关于这个程序的执行流程:如果输入负号跳转到MINUS然后继续往下执行@PLUS、@SAVE 等
- 如果输入加号跳转到@PLUS 再往下执行@SAVE
- @NEXT1的最后一行NEG BL执行完以后会继续往下执行@NEXT2
- 不太能理解的地方:书上说SUB AL,30H 是转换成二进制 但不应该是转换成真实的数字吗
- NEG BL需要两次吗?
例3:写一个程序,输入0~9之间的两个数,找出输入的两数之间的差异,然后打印出来。
- 输出问号
- 键盘输入并把输入的内容转换为真实的数字 存储到BL里
- 键盘输入,转换,存储到CL里
- BL减CL 判断符号位是否发生改变 没有改变直接输出 改变的话先取相反数
- 输出
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入
SUB AL,30H ;转换为真实的数值
MOV BL,AL ;把真实的数值存储到BL里
INT 21H ;第二次键盘输入,让用户输入第二个数
SUB AL,30H ;转换为真实的数值
MOV CL,AL ;把真实的数值存储到CL里
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出空格回车
SUB BL,CL ;BL=BL-CL
JNS @OUTPUT;符号位没有被置位就跳转,说明BL大于CL,BL的符号没有发生改变
NEG BL ;取相反数吗,说明此时结果是负数
@OUTPUT:
MOV DL,BL
ADD DL,30H ;输出结果
INT 21H
MOV AH,4CH
INT 21H ;结束
MAIN ENDP
END MAIN
例4:输入两个小写字母,按照字母顺序输出。如果输入的字符不是小写字母,请从头重新开始程序。
- 输出问号
- 键盘输入 将第一次输入的存储到BL里
- 通过观察ASCII表可以得知大写字母数字和一些符号在a的上面,也就是比a的ASCII小 所以
- 把用户输入的和a比较 如果小于就直接跳转到WRONG 并从头来
- 通过观察ASCII表可以发现,z后面有一些符号这些也需要排除掉
- 把用户输入的和z比较,如果小于就直接跳转到WRONG 并从头来
- 键盘输入(第二个字母)同理排除
- 比较输入的两个字母的ASCII值,如果小于或等于直接输出,如果大于就交换两个位置
- 输出,退出
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
@BEGIN:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入
MOV BL,AL ;把用户输入的内容存储到BL
CMP AL,'a' ;用户输入的内容和a比较(ASCII)
JL @WRONG ;如果小于则跳转,这里排除了大写字母数字和一些符号
CMP AL,'z' ;再排除一些符号
JG @WRONG ;如果大于则跳转
;通过两轮排除,现在剩下的就是小写字母了
INT 21H ;键盘输入第二个字母
MOV CL,AL ;把输入的存储到CL里
CMP AL,'a'
JL @WRONG
CMP AL,'z'
JG @WRONG
;两轮排除,原理同上
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车换行
CMP BL,CL ;比较输入的两个字母
JLE @OUTPUT ;如果小于或等于就直接跳转输出
XCHG BL,CL ;如果大于就需要把两个的位置交换一下
@OUTPUT:
MOV DL,BL
INT 21H ;输出BL
MOV DL,CL
INT 21H ;输出CL
JMP @EXIT ;直接跳转退出
@WRONG:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
JMP @BEGIN ;从头来,跳转到最上面的BEGIN
@EXIT:
MOV AH,4CH
INT 21H ;退出
MAIN ENDP
END MAIN
例5:写一个程序,输入三个大写字母,按照字母顺序相反,输出。
- 首先要明确 字母顺序越大的越先输出(Z-A),Z的ASCII比A大
- 也就是说 ASCII最大的 第一个输出,最小的最后一个输出
- 比较的是ASCII码的大小
- 第一个数先和第二个数比较,把ASCII码更大的放到前面
- 再把第一个数和第三个数相比,把ASCII码更大的放到前面
- 再把第二个数和第三个数相比,把更大的放前面
- 比如41 49 54
第一次比较换位后:49 41 54
第二次比较换位后:54 41 49
第三次比较换位后:54 49 41 - 至此 三个数的大小从大到小排序了
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入.第一次
MOV BL,AL ;把键盘输入的字母存储到BL里
INT 21H ;键盘输入.第二次
MOV BH,AL ;把第二个输入的字母存储到BH里
INT 21H ;键盘输入.第三次
MOV CL,AL ;把第三个输入的字母存储到CL里
CMP BL,BH ;比较第二次输入的和第一次输入的字母
JLE @NEXT1 ;如果小于等于就跳转NEXT1,相当于此时BH的字母比BL的字母大
XCHG BL,BH ;交换BL和BH所存储的字母
@NEXT1:
CMP BL,CL ;再比较第一次输入的和第三次输入的字母
JLE @NEXT2 ;如果小于等于就跳转NEXT2,相当于此时CL的字母比BL的大
XCHG BL,CL ;交换BL和CL所存储的字母
@NEXT2:
CMP BH,CL ;再比较第二次输入的和第三次输入的字母
JLE @OUTPUT ;如果小于等于就跳转OUTPUT,相当于此时CL的字母比BH的大
XCHG BH,CL ;交换BH和CL所存储的字母
@OUTPUT:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车换行
MOV DL,CL ;把CL存储到DL,待输出,CL是最靠后的字母
INT 21H
MOV DL,BH ;把BH存储到DL,待输出,BH是第二靠后的字母
INT 21H
MOV DL,BL ;把BL存储到DL,待输出,BL是最靠前的字母(最后输出)
INT 21H
MOV AH,4CH ;结束
INT 21H
MAIN ENDP
END MAIN
1 条评论
[…] 汇编(17)五个例子 […]