单分支程序(if then)
例
双字长数存放于dx和ax寄存器(高位于dx),求该数的绝对值(用16位指令)
算法分析:判断数正负,正数(首位为0),不需处理,负数(首位为1),对该数求补,即反码加一
code segment
assume cs:code
start:
test dx,8000h //测试数的正负
jz exit //不为负数则退出
not ax
not dx
add ax,1
adc dx,0
exit:
mov ah,4ch
int 21h
code ends
end start
复合分支程序
例
从键盘输入一位十六进制数,将其转换为十进制数显示输出
算法分析:
输入为数字(30h~39h),直接输出
为大写字母A~F(41h~46h)时,可减11h
a~f时(61h~66h),可减去31h得到30h~35h(0~5的ascii码),再输出2位十进制数字,
其他输入为非法输入,退出程序
code segment
assume cs:code
start:mov ah,1 //键盘输入
int 21h
cmp al,30h
jl exit
cmp al,39h
jle dig //输入为0~9
cmp al,41h
jl exit //非法输入
cmp al,46h
jle print //输入为A~F
cmp al,61h
jl exit //非法输入
cmp al,66h
jg exit //非法输入
sub al,31h
jmp out1 //输入为小写a~f
print:sub al,11h
out1:mov dl,31h //输出字符1
mov ah,2
push ax //暂存ax
int 21h //int指令改写ax
pop ax //恢复ax
dig:mov dl,al //输出个位
mov ah,2
int 21h
exit:mov ah,4ch
int 21h
code ends
end start
多分支程序
采用分支向量表法,int 21h指令就是根据中断类型号21h*4得84h直接到84h内存中的向量表取出中断向量(即系统子程序的首地址),来执行一段程序,我们把各分支地址集中存放于分支向量表中,根据分支号快速进入分支
例
根据键盘输入的一位数字1~4,使程序转移到4个不同的分支中去,以显示键盘输入的数字
算法分析:建立一个分支向量表branch,集中存放4个分支的偏移地址,因偏移地址为16位,所以每两个字节存放一个偏移地址,据输入的数字指向分支向量表,从表中取出对应分支的偏移地址,用jmp branch[bx]指令间接寻址方式转向对应分支
code segment
assume cs:code,ds:code
start:mov ax,code //ds=cs
mov ds,ax
mov ah,7 //键盘输入无回显
int 21h
cmp al,31h
jl exit //非法输入
cmp al,34h
jg exit //非法输入
mov dl,al //放入dl,待显示
mov bl,al
sub bl,31h //转换ascii码为数值
shl bl,1 //(bl)*2,指向分支向量表中某地址
mov bh,0
jmp branch[bx] //转向分支
rl:mov ah,2
int 21h //显示键盘输入的数字
jmp exit
r2:mov ah,2
int 21h
jmp exit
r3:mov ah,2
int 21h
jmp exit
r4:mov ah,2
int 21h
jmp exit
exit:mov ah,4ch
int 21h
branch dw r1
dw r2
dw r3
dw r4
code ends
end start
循环程序设计
循环有两种结构,do while和do null
do while先判断条件,再执行循环,do null先循环一遍再判断要不要下次循环
例
把bx寄存器中的二进制用16进制数格式显示输出
算法分析:
bx寄存器每4位表示一位16进制数位,从左到右循环移位,每移四位,就把要显示的4位二进制位移到最右边。取出最右边的4位,加上30h,转换成8位ascii字符码。因显示输出的十六进制是数字(30h~39h)和A~F(41h~46h),所以8位二进制大于39h时,应再加上7,程序采用计数循环,计数值为4
code segment
assume cs:code
start: mov cx,4
shift:rol bx,1 //连续循环左移4位
rol bx,1
rol bx,1
rol bx,1
mov al,bl
and al,bl
and al,0fh //取最右四位
add al,30h //转为ascii
cmp al,39h
jle dig //是0~9则转dig
add al,7 //是A~F
dig:mov dl,al
mov ah,2
int 21h
loop shift
mov ah,4ch
int 21h
code ends
end start //该程序因未对bx赋值,初值可能为0,需在调试状态下先设置bx的值再运行
例
从键盘输入一个四位的十六进制数(其中字母大写),并将其转换为二进制数显示输出
算法分析:该程序需要两段循环,第一个循环接收键盘输入的16进制数,30h~39h时减30h,输入为41h~46h时,减37h,应把四次的输入拼装成四位16进制数存放在bx寄存器,第二个循环利用16次位移从左到右显示bx寄存器中的二进制数
code segment
assume cs:code
start:mov bx,0 //初始化
mov ch,4
mov cl,4
inchar:mov ah,1 //键盘输入
int 21h
cmp al,30h
jl exit //非法输入
cmp al,39h
jle dig //输入数字0~9
cmp al,41h
jl exit
cmp al,46h
jg exit //非法输入
sub al,37h //输入A~F
jmp ks4
dig:sub al,30h
ks4:shl bx,cl
add bl,al
dec ch
jnz inchar
mov ah,2
mov dl,10 //输出换行
int 21h
mov cx,16 //循环计数初值
ks1:shl bx,1 //左移一位
jnc k30 //是0则转k30
mov dl,31h
jmp outb
k30:mov dl,30h
outb:mov ah,2
int 21h
loop ks1
exit:mov ah,4ch
int 21h
code ends
end start
条件循环程序
循环体有分支时,依据标志位判断,标志位为1表示执行a操作,为0表示执行b操作等,把这种标志字称为逻辑尺
例
先从键盘输入8位二进制数作为逻辑尺,再从键盘输入一个英文字母,根据逻辑尺当前的最高位标志显示输出该英文字母的相邻字符,标志位为0则显示前趋字符,标志位为1则显示其后继字符,显示相邻字符后,逻辑尺循环左移一位再接收下一个英文字母的输入,并依据逻辑尺显示相邻字符,直到回车键结束程序
算法分析:8位二进制数的输入构成一个8次循环,把输入整合到
8位寄存器bl中。键盘输入一个英文字母后依据逻辑尺最高标志位显示相邻字符,把最高位移到cf位,以cf位决定显示,构成一个条件循环,以回车键退出循环
code segment
assume cs:code
start:mov bx,0
mov cx,8
inlog:mov ah,1
int 21h
cmp al,30h
jb exit //非法输入
cmp al,31h
ja exit //非法输入
sub al,31h
shl bl,1
add bl,al
loop inlog
mov ah,2
mov dl,10 //输出换行
int 21h
inchr:mov ah,1
int 21h
cmp al,13
je exit
mov dl,al
rol bl,1
jnc k30 //是0则转为k30
inc dl
jmp putc
k30:dec dl
putc:mov ah,2
int 21h
jmp inchr
exit:mov ah,4ch
int 21h
code ends
end start