例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




最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏