例1:输入的0~9之间的数,如果是奇数,则输出“odd”,如果是偶数,则输出“even”
- 观察ASCII表可知道如果是奇数最右边一位一定是1,如果是偶数一定是0,用这个特性,使用TEST指令来进行判断
.MODEL SMALL
.STACK 100H
.DATA
;定义数据段
ODD_MSG DB 0DH,0AH,'ODD$'
EVEN_MSG DB 0DH,0AH,'EVEN$'
.CODE
MAIN PROC
MOV AX,@DATA ;把DATA首地址传送给AX,AX用来临时中转
MOV DS,AX ;把DATA首地址传送到DS里
MOV AH,2 ;AH 2显示输出
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入
;观察ASCII表可知道如果是奇数最右边一位一定是1,如果是偶数一定是0用这个特性,加使用TEST指令
TEST AL,01H ;将用户输入的和01H进行AND运算
;设置标志位但是不会改变这两个操作数
;用于测试AL的最右边一位是否为1,01H是00000001
JE @EVEN ;跳转EVEN,偶数
;如果不是就证明是奇数
LEA DX,ODD_MSG ;取字符串ODD_MSG的偏移地址存储到DX里
JMP @OUTPUT ;跳转OUTPUT
@EVEN:
LEA DX,EVEN_MSG ;取字符串EVEN_MSG的偏移地址存储到DX里
@OUTPUT:
MOV AH,9 ;AH 9输出字符串
INT 21H
MOV AH,4CH ;结束
INT 21H
MAIN ENDP
END MAIN
例2:输入一个二进制数,反向输出
- 把输入的二进制数存储到BL里
- 判断是0还是1还是回车,
- 是0和1的情况 先清空高四位 再把BL左移,再用OR把值存储到BL最低位
- 输出的时候,循环右移一位,把最后一位存到CF里,然后用JC判断CF是0还是1再输出
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
@BEGIN:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV BL,BL ;BL 0初始化
MOV AH,1
INT 21H ;键盘输入
@WHILE:
CMP AL,0DH
JE @END_WHILE ;如果是回车就跳转END_WHILE
CMP AL,'0'
JE @BINARY ;如果是0就跳转BINARY
CMP AL,'1'
JE @BINARY ;如果是1就跳转BINARY
JMP @ERROR ;其它情况跳转ERROR
@BINARY:
AND AL,0FH ;把AL变成二进制的数,高四位清零
SHL BL,1 ;把BL每位左移一位
OR BL,AL ;AL最低位就两种情况1或者0,所以OR是直接把AL的最低位赋值给BL的最低位
INT 21H ;键盘输入
JMP @WHILE ;跳转到WHILE继续循环
@END_WHILE:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车换行
MOV CX,8 ;CX存储8,循环次数
@OUTPUT:
ROR BL,1 ;循环右移一位,相当于是把最后一位顶到最前面
JC @HIGH ;JC用于判断CF是否等于1,等于1就跳转HIGH,ROR指令会把CF等于最低位
MOV DL,30H ;如果是0的话,DL保存0
JMP @NEXT ;跳转NEXT
@HIGH:
MOV DL,31H ;如果是1的话保存1
@NEXT:
INT 21H ;输出
LOOP @OUTPUT ;循环OUTPUT
JMP @EXIT ;循环八次结束以后跳转到退出
@ERROR:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车换行
JMP @BEGIN ;跳转到最开始
@EXIT:
MOV AH,4CH
INT 21H ;结束
MAIN ENDP
END MAIN
例3:编写一个程序,输出输入的两个十六进制数相加的结果。假设十六进制加法运算中不会发生溢出。
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
@BEGIN:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
XOR BX,BX ;初始化BX
MOV CL,4 ;CL存储4
MOV AH,1
INT 21H ;键盘输入
@WHILE1:
CMP AL,0DH
JE @END_WHILE1 ;如果是回车就跳转END_WHILE1
CMP AL,' '
JE @END_WHILE1 ;如果是空格就跳转END_WHILE1
CMP AL,30H
JB @ERROR ;如果是小于30H的情况(也就是ASCII表中0前面的一堆符号的情况)跳转ERROR
CMP AL,39H
JA @LETTER1 ;大于39H的情况(9)跳转LETTER1
AND AL,0FH ;输入的数AL高四位清0
JMP @SHIFT1 ;跳转SHIFT1
@LETTER1:
CMP AL,'A'
JB @ERROR ;如果小于A的情况(加减乘除符号)跳转ERROR
CMP AL,'F'
JA @ERROR ;大于F的情况跳转ERROR,16进制是由0-9或A-F组成
SUB AL,37H ;字母的情况把它转换成16进制,减37H
@SHIFT1:
SHL BX,CL ;把BX左移CL个位,4个位
OR BL,AL ;把用户输入的存储到BX的低位(BL里),第一个数
INT 21H ;键盘输入,继续循环
JMP @WHILE1 ;跳转WHILE1
@END_WHILE1:
XOR DX,DX ;DX初始化0
MOV CL,4 ;CL设置为4
MOV AH,1
INT 21H ;键盘输入
@WHILE2:
CMP AL,0DH
JE @END_WHILE2 ;如果是回车的情况跳转END_WHILE2,接上面
CMP AL,' '
JE @END_WHILE2 ;如果是空格就跳转END_WHILE2
CMP AL,30H
JB @ERROR ;如果小于30H(0)就跳转ERROR
CMP AL,39H
JA @LETTER2 ;如果大于39H就跳转LETTER2(字母符号的情况)
AND AL,0FH ;高四位清零,数字的情况
JMP @SHIFT2 ;跳转SHIFT2
@LETTER2:
CMP AL,'A'
JB @ERROR ;小于A的情况跳转ERROR
CMP AL,'F'
JA @ERROR ;大于F的情况跳转ERROR
SUB AL,37H ;将字母转换成十六进制
@SHIFT2:
SHL DX,CL ;将DX左移CL个位,CL是4
OR DL,AL ;相当于把AL存到DL里,第二个数
INT 21H ;键盘输入
JMP @WHILE2 ;继续循环判断
@END_WHILE2:
ADD BX,DX ;把两个十六进制数相加 (第一个数在BL里面第二个数在DL里)
;结果存储在BX里
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
MOV DH,4 ;计次
MOV CL,4
MOV AH,2
@OUTPUT:
MOV DL,BH ;BX的高位BH存放在DL里
SHR DL,CL ;右移四个位
CMP DL,0AH
JL @NUMBER ;如果小于跳转NUMBER
ADD DL,37H ;十六进制转回A-F,加上37H
JMP @NEXT
@NUMBER:
OR DL,30H ;16进制值转换成ASCII码
@NEXT:
INT 21H ;输出
ROL BX,CL ;相加的结果BX左移4个位
DEC DH ;DH减1
JNZ @OUTPUT ;如果不等于(ZF=0零标志)
JMP @EXIT
@ERROR:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH ;输出回车
INT 21H
JMP @BEGIN ;重新来
@EXIT:
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
例4:输入的数字(N)的(N+(N-1)+(N-2)+....+1)计算并编写以十六进制输出的程序。
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AH,2
MOV DL,'?'
INT 21H ;输出回车
MOV CX,0
MOV AH,1
INT 21H ;键盘输入
SUB AL,30H ;转换成真实的数字
MOV CL,AL ;把输入的存储到CL里
MOV BL,0
@TOP:
ADD BL,CL ;BL加上CL,结果存储在BL里
LOOP @TOP
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
MOV DH,2
MOV CL,4
@OUTPUT:
MOV DL,BL ;把BL传送到DL里
SHR DL,CL ;DL右移四个位
CMP DL,0AH
JL @NUMBER ;如果小于则跳转NUMBER
ADD DL,37H ;十六进制赚A-F
JMP @NEXT
@NUMBER:
OR DL,30H ;十六进制转ASCII码
@NEXT:
INT 21H ;输出
ROL BL,CL ;BL循环左移4位
DEC DH ;DH减1
JNZ @OUTPUT ;如果不等于则跳转OUTPUT
MOV AH,4CH
INT 21H ;结束
MAIN ENDP
END MAIN
例5:编写一个程序,只输出输入的二进制数字的有效位,如下所示。
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
@BEGIN:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
XOR BX,BX ;BX初始化
MOV AH,1
INT 21H ;键盘输入
@WHILE:
CMP AL,0DH
JE @END_WHILE ;如果是回车跳转END_WHILE
CMP AL,'0'
JE @BINARY ;如果等于0就跳转BINARY
CMP AL,'1'
JE @BINARY ;如果等于1就跳转BINARY
JMP @ERROR ;其它情况(非0非1的情况)就是错误的,跳转ERROR
@BINARY:
AND AL,0FH ;AL的高四位清零
SHL BX,1 ;BX左移一位
OR BL,AL ;把AL存到BL
INT 21H ;键盘输入
JMP @WHILE ;继续循环
@END_WHILE:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
MOV CX,16
MOV DH,0
@OUTPUT:
ROL BX,1 ;循环左移一位,BX的最高位移入CF
JC @HIGH ;如果CF=1
CMP DH,0
JE @NEXT2 ;如果DH是0的话就跳转NEXT2
MOV DL,30H ;DL存储30H(数字0)
JMP @NEXT1 ;跳转NEXT1
@HIGH:
MOV DL,31H ;DL存储31H(数字1)
CMP DH,1 ;如果DH是1就跳转NEXT1
JE @NEXT1
MOV DH,1 ;DH不是1的情况,把它变成1
@NEXT1:
INT 21H ;显示输出
@NEXT2:
LOOP @OUTPUT ;CX减1,继续循环直到CX=0
JMP @EXIT ;跳转EXIT
@ERROR:
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
例6:编写一个程序,将输入的十进制字符串中每个数字的总和输出为十六进制数。假设总和小于8位。
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
@BEGIN:
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV BL,0
MOV AH,1
INT 21H ;键盘输入
@WHILE:
CMP AL,0DH
JE @END_WHILE ;如果是回车就跳转END_WHILE
CMP AL,'0'
JB @ERROR ;如果小于就跳转ERROR
AND AL,0FH ;AL高四位清空
ADD BL,AL ;把用户输入的存储到BL里
INT 21H ;键盘输入
JMP @WHILE ;继续循环
@END_WHILE:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;回车
MOV DH,2 ;DH存储2
MOV CL,4 ;CL存储4,右移CL位
@OUTPUT:
MOV DL,BL ;把BL给DL
SHR DL,CL ;逻辑右移四个单位
CMP DL,0AH
JL @NUMBER ;CF=1的情况跳转NUMBER
ADD DL,37H ;十六进制转换成A-F
JMP @NEXT ;跳转NEXT
@NUMBER:
OR DL,30H
@NEXT:
INT 21H ;输出
ROL BL,CL ;BL循环左移4个位
DEC DH ;DH减1
JNZ @OUTPUT ;ZF=0跳转OUTPUT
JMP @EXIT ;否则跳EXIT
@ERROR:
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