? 循环程序设计
分支程序设计第 5章 循环与分支程序设计分支结构 子程序结构程序结构:
复合结构:多种程序结构的组合

顺序结构 循环结构编制汇编语言程序的步骤:
(1) 分析题意,确定算法
(2) 根据算法画出程序框图
(3) 根据框图编写程序
(4) 上机调试程序
1,循环程序设计
DO-WHILE 结构 DO-UNTIL 结构控制条件初始化循环体
Y
N
控制条件初始化循环体
Y
N
初始化,设置循环的初始状态循环体,循环的工作部分及修改部分控制条件,计数控制特征值控制地址边界控制
BX
1
2
3
4
例:把 BX 中的二进制数以十六进制的形式显示在屏幕上
……
mov ch,4
rotate,mov cl,4
rol bx,cl
mov al,bl
and al,0fh
add al,30h ; ’0’~’9’ ASCII 30H~39H
cmp al,3ah
jl printit
add al,7h ; ’A’~’F’ ASCII 41H~46H
printit,mov dl,al
mov ah,2
int 21h
dec ch
jnz rotate
……
……
mov bx,0
newchar,mov ah,1 ;键盘输入
int 21h
sub al,30h
jl exit ; <0退出
cmp al,9
jg exit ; >9退出
cbw
xchg ax,bx
mov cx,10
mul cx
xchg ax,bx
add bx,ax
jmp newchar
exit,……
例:从键盘接收十进制数并存入 BX
( ( 0× 10)+1 )× 10+2 )× 10+5
1 2 5
31 32 35
……
mov bx,0
newchar,mov ah,1 ;键盘输入
int 21h
sub al,30h
jl exit ; <0退出
cmp al,10
jl add_to
sub al,27h ; ‘a’~‘f’
cmp al,0ah
jl exit ; <‘a’退出
cmp al,10h
jge exit ; >’f’退出
add_to,mov cl,4
shl bx,cl
mov ah,0
add bx,ax
jmp newchar
exit,……
例:从键盘接收十六进制数并存入 BX 1 a f
31 61 66
((0× 16)+1) × 16+0a) × 16+0f
x dw?
array_head dw 3,5,15,23,37,49,52,65,78,99
array_end dw 105
n dw 32
例:将正数 n 插入一个已整序的正数字数组
……
mov ax,n
mov array_head-2,0ffffh
mov si,0
compare:
cmp array_end [si],ax
jle insert
mov bx,array_end [si]
mov array_end [si+2],bx
sub si,2
jmp short compare
insert:
mov array_end [si+2],ax
……
3
5
15
23
37
49
52
65
78
99
105
32
-1
array_head?
array_end?
n?
x?
例,将首地址为 A的字数组从小到大排序
( 气泡算法,多重循环 ) 32,85,16,15,8
序号 地址 数比 较 遍 数
1 2 3 4
1 A 32
2 A+2 85
3 A+4 16
4 A+6 15
5 A+8 8
32
16
15
8
85
16
15
8
32
85
15
8
16
32
85
8
15
16
32
85
mov cx,5 ;元素个数
dec cx ;比较遍数
loop1,mov di,cx ;比较次数
mov bx,0
loop2:
mov ax,A[bx] ;相邻两数
cmp ax,A[bx+2] ; 比较
jle continue
xchg ax,A[bx+2] ;交换位置
mov A[bx],ax
continue:
add bx,2
loop loop2
mov cx,di
loop loop1
2,分支程序设计

case 1 case 2 case n
case 1 case 2 case n
CASE 结构 IF-THEN-ELSE 结构
(1) 逻辑尺控制
(2) 条件控制
(3) 地址跳跃表 (值与地址有对应关系的表)
例:有数组 x(x1,x2,……,x10) 和 y(y1,y2,……,y10),
编程计算 z(z1,z2,……,z10)
z1 = x1 + y1
z2 = x2 + y2
z3 = x3 - y3
z4 = x4 - y4
z5 = x5 - y5
z6 = x6 + y6
z7 = x7 - y7
z8 = x8 - y8
z9 = x9 + y9
z10= x10 + y10
逻辑尺,0 0 1 1 0 1 1 1 0 0
1 减法
0 加法
x dw x1,x2,x3,x4,x5,x6,x7,x8,x9,x10
y dw y1,y2,y3,y4,y5,y6,y7,y8,y9,y10
z dw z1,z2,z3,z4,z5,z6,z7,z8,z9,z10
logic_rule dw 00dch ;0000,0000,1101,1100
……
mov bx,0
mov cx,10
mov dx,logic_rule
next,mov ax,x[bx]
shr dx,1
jc subtract
add ax,y[bx]
jmp short result ; 向前引用
subtract,
sub ax,y[bx]
result,mov z[bx],ax
add bx,2
loop next
……
data segment
array dw 12,11,22,33,44,55,66,
77,88,99,111,222,333
number dw 55
low_idx dw?
high_idx dw?
data ends
例:折半查找算法
12
11
22
33
44
55
66
77
88
99
111
222
333
0
1
2
3
4
5
6
7
8
9
10
11
12
(ax)=55
low_idx
1
1
4
5
high_idx
12
5
5
5
(si)=0ah
Cf=0
(ax)=90
low_idx
1
7
7
8
9
high_idx
12
12
8
8
8
(si)=10h
Cf=1
折半算法 1
……
lea di,array
mov ax,number ;要查找数
cmp ax,[di+2] ; (ax)与第一个元素比较
ja chk_last
lea si,[di+2]
je exit ; (ax)=第一个元素,找到退出
stc
jmp exit ; (ax)<第一个元素,未找到退出
chk_last:
mov si,[di] ;元素个数,第 0个存的是数组元素个数
shl si,1 ; 计算 最后一个元素
add si,di ; 的地址
cmp ax,[si] ; (ax)与最后一个元素比较
jb search
je exit ; (ax)=最后一个元素,找到退出
stc
jmp exit ; (ax)>最后一个元素,未找到退出算法 1
compare:
cmp ax,[bx+si]
je exit
ja higher
dec cx
mov high_idx,cx
jmp mid
higher:
inc cx
mov low_idx,cx
jmp mid
no_match:
stc
exit:
……
search:
mov low_idx,1
mov bx,[di] ;个数
mov high_idx,bx
mov bx,di
mid:
mov cx,low_idx
mov dx,high_idx
cmp cx,dx
ja no_match
add cx,dx
shr cx,1
mov si,cx
shl si,1
12
11
22
33
44
55
66
77
88
99
111
222
333
0
1
2
3
4
5
6
7
8
9
10
11
12
(ax)=55
di
12
6
10
si
12
6
4
(si)=0ah
(di)=0ah
Cf=0
(ax)=90
di
12
18
14
16
si
12
6
4
2
(si)=2
(di)=10h
Cf=1
折半算法 2
算法 2 idx_ok:
shr si,1
test si,1
jz sub_idx
inc si
sub_idx:
sub di,si
jmp short compare
higher:
cmp si,2
je no_match
shr si,1
jmp short even_idx
all_done:
mov si,di
exit:
……
search:
mov si,[di]
even_idx:
test si,1
jz add_idx
inc si
add_idx:
add di,si
compare:
cmp ax,[di]
je all_done
ja higher
cmp si,2
jne idx_ok
no_match:
stc
jmp exit
例:根据 AL 寄存器中哪一位为 1( 从低位到高位 ),
把程序转移到 8 个不同的程序分支
branch_table dw routine1
dw routine2
dw routine3
dw routine4
dw routine5
dw routine6
dw routine7
dw routine8
……
cmp al,0 ;AL为逻辑尺
je continue
lea bx,branch_table
L,shr al,1 ;逻辑右移
jnc add1
jmp word ptr[bx] ;段内间接转移
add1,add bx,type branch_table ; add bx,2
jmp L
continue,
……
routine1,
……
routine2,
……
( 寄存器间接寻址 )
( 寄存器相对寻址 )……
cmp al,0
je continue
mov si,0
L,shr al,1 ;逻辑右移
jnc add1
jmp branch_table[si] ;段内间接转移
add1:
add si,type branch_table
jmp L
continue,
……
routine1,
……
routine2,
……
( 基址变址寻址 )……
cmp al,0
je continue
lea bx,branch_table
mov si,7 * type branch_table
mov cx,8
L,shl al,1 ;逻辑左移
jnc sub1
jmp word ptr [bx][si] ;段内间接转移
sub1,sub si,type branch_table ;(si)-2
loop L
continue,
……
routine1,
……
routine2,
……
第 5章作业
Page 193 5.5 5.7
5.12 5.18
Array为数组(从小到大排序)
Number为要搜索的数
Low_idx与 High_idx表示搜索的范围初值,Low_idx为 1
High_idx为 n
CF的值:
0:表示搜索到如果有搜到,则
( SI)存放元素的地址
1:表示没有搜到
Number与 array
的头元素比较
Number与 array
的尾元素比较
Number与 array
的中间元素比较
Number与 array
的头元素比较
Number与 array
的尾元素比较
Number与 array
的中间元素比较
Number>array[0]
STC
结束
Y
Number=
array[0]
N
Y
N
找到
(SI)?
首地址
Number与 array
的头元素比较
Number与 array
的尾元素比较
Number与 array
的中间元素比较
Number<array[n-1]
STC
结束
Y
Number=
array[n-1]
N
Y
N
找到
(SI)?
尾地址
Number与 array
的头元素比较
Number与 array
的尾元素比较
Number与 array
的中间元素比较
Low_idx≤High_idx
结束
Y
N
Y
N
STC计算中间元素是数组的第几个元素和它的地址并赋给( SI)
Number=中间元素
Number<中间元素
High_idx?
第几个元素 -1
Low_idx?
第几个元素 +1
N