当前位置:首页 >> 理学 >>

第五章B:


第5章 循环与分支程序设计

?

循环程序设计

?

分支程序设计

跳转到第一页

程序结构:
顺序结构 循环结构

分支结构

子程序结构



复合结构:多种程序结构的组合
跳转到第一页

程 序 的 结 构 形 式 有

顺序:按顺序逐条执行指令

循环:
分支:

子程序:

跳转到第一页

5.1循环程序设计:有两种结构形式 Do while
当条件满足时执行,如 果有可能循环次数等于 零,则选择do while

Do until

执行循环 直到条件 满足才退出。

循环初始状态 循环初始

控制条件
循环体

循环体

控 制 条 件
跳转到第一页

不论哪一种结构形式,循环程序可由以下三部分组成: ①设置循环的初始状态,以及循环次数。 ② 循环体 工作部分。

修改部分。
③ 循环控制部分 用循环次数作为控制条件。 用循环次数加其它条件。 循环次数未知,设定其他条件

跳转到第一页

5.1.2循环程序设计
例 5.1编制一个程序把bx寄存器内的2进制数用16进 制数的形式在屏幕上显示出来。 根据题目要求应将BX中的内容从左到右每4位一组显 示出来,共显示4个十六进制数位。如果显示的数位是 0~9,则把4位二进制数加上30H,转换成相应的ASCII 30H~39H;如果是A~F,则应加上37H(30H+7)转 换成ASCII码41H~46H。显示字符可以使用DOS功能调 用来实现(详见第九章)是二-十六转换程序的流程。 1、分析题意。 将2进制数转化为16进制数,必须以4位2进制数转化 为1位16进制数。要转换一个16位的2进制数,需要循环 执行4次用来转换的程序主体 再显示时数值与ASCII码的转换,比如:01的ASCII 码是31 2、画出程序框图
跳转到第一页

开始 初始化循环计数值 BX循环左移一个数位 把最右面的数转换为ASCII码 是ASCII码的A~F Y 加上7 显示一个字符 N N

例 5.1是一个 典 型 的 DO until 型循环.

为什么要加上7, 跳过 : ; < = > ? @这7个ASCII

循环计数值=0?

Y 结束
跳转到第一页

例:把 BX 中的二进制数以十六进制的形式显示在屏幕上

BX
1

2 3

4

跳转到第一页

Prognam segment Main proc far Assume cs:prognam Start: 1 Push ds 2 Sub ax,ax 3 Push ax MOV BX, N ; N为一个要显示的二进制数 4 mov ch,4 ;置计数器,把BX中数分为4段,每段一个ASCII 5 Rotate: mov cl,4 ;循环入口,CL为计数器,对左移4个BIT计数 6 Rol bx,cl ;循环左移4次,把低4位变成4高位,最高4位变低4位 7 mov al,bl ;原高4位放AL 8 and al,0fh ;左4位置0,剩下右4位在AL中 9 Add al,30h ;剩下右4位在AL中加30h 10 Cmp al,3ah ; al-3ah>0 ? 11 Jl printit ; 上式中如小于等于0,则在0-9中 12 Add al, 7h ;大于0则在A-F数中 跳转到第一页 13 Printit: Mov dl,al ;P471 中断21H调用,显示AL中内容

14 Mov ah,2 15 Int 21h 16 Dec ch 17 Jnz rotate 18 Ret Main endp Prognam ends End start

; P471 中断21调用,显示AL中内容
; P471 中断21调用,显示AL中内容 ;循环计数 ; 循环出口(满足条件转移ROTATE)

跳转到第一页

例5.2 在ADDR 单元中存放着数Y的地址,试编制一个程序把Y中1的个数存 在COUNT单元中

datarea segment addr dw 1010101010101010b count dw ? datarea ends prognam segment main proc far assume cs:prognam,ds:datarea start: push dx sub ax,ax push ax moV ax,datarea mov ds,ax

跳转到第一页

mov cx,0 2 Mov bx, offset addr ; 地址放BX 3 mov ax,[bx] ; 放Y数到AX 4 repeat: test ax,0ffffh ; 测试AX=0(Y=0?) 5 jz exit ; 判断AX=0?,如AX=0则到EXIT句 ? jns shift ;判断最高位为0?为0不计数,为1才计数) 7 inc cx ; 计数 8 shift: shl ax,1 ;逻辑左移1位,把低位移到高位移 9 jmp repeat 10 exit: mov count,cx ;把最后计数器CX内容放COUNT中 11 ret main endp prognam ends 跳转到第一页 end start
1

例:从键盘接收十进制数并存入 BX
…… mov newchar: mov int sub jl cmp jg cbw xchg mov mul xchg add bx, 0 ah, 1 21h al, 30h exit al, 9 exit

1 2 5 31 32 35
;键盘输入

; <0退出

; >9退出

ax, cx, cx ax, bx,

bx 10 bx ax

( ( 0×10)+1 )×10+2 )×10+5

;默认被乘数为AX ;存入BX

exit:

jmp ……

newchar

例:从键盘接收十六进制数并存入 BX
…… mov newchar: mov int sub jl cmp jl sub cmp jl cmp jge add_to: mov shl mov add jmp exit: …… bx, 0 ah, 1 21h al, 30h exit al, 10 add_to al, 27h al, 0ah exit al, 10h exit cl, 4 bx, cl ah, 0 bx, ax newchar

1 a f 31 61 66
;键盘输入

; <0退出

; ‘a’~‘f’
; <‘a’退出 ; >’f’退出 ((0×16)+1) × 16+0a) × 16+0f

;存入 BX

例5.4: (p166)将正数 n 插入一个已整序的正数字数组
x dw array_head dw array_end dw n dw ? 3,5,15,23,37,49,52,65,78,99 105 32
x ?
array_head?

compare:

…… mov ax, n mov array_head-2, 0ffffh mov si, 0 cmp jle mov mov sub jmp array_end [si], ax insert bx, array_end [si] array_end [si+2], bx si, 2 short compare

-1 3 5 15 23 37 49 52

65
78 99
array_end?

insert:

105 32

mov array_end [si+2], ax ……

n ?

例5.5 :关于设定作标志的存储单元逻辑尺
设有数组x和Y。 x数组中有x1,…,x10;y数组中有 y1,…y10。试编制程序计算 z1=x1十Y1 z2=x2十Y2 z3=x3一Y3 Z4=x4一Y4 结果存入z数组 Z5=x5一Y5 z6=x6十Y6 Z7=x7一Y7 z8=x8一Y8 Z9=x9十Y9 Z10=x10十Y10

跳转到第一页

对于这种问题,我们也可用循环程序结构来完成。已知循 环计数值为10,每次循环的操作数是可以顺序取出的,但所做的操 作却有不同,这里有两种操作:加法和减法,为了区别每次应该做 哪一种操作,可以设立标志位,如标志位为0做加法;为1则做减法, 这样进入循环后只判别标志位就可确定应该做的操作了。显然,这 里要做10次操作就应该设立10个标志位,我们把它放在一个存储单 元logic_rule中,这种存储单元一般称为逻辑尺,本例设定的逻辑 尺为: 0000000011011100 从低位开始所设的标志位反映了每次要做的操作顺序,最高的6位 没有意义把它们设为0。 可以画出程序框图如图5.10所示。

编制程序如图5.11所示。
跳转到第一页

开始 初始化循环计数值 I=0 不=0 测试 逻辑尺第I位 的值 ZI结果 =0

XI-YI

XI+YI

I
N

II+1

循环 计数值=0?

Y
结束
跳转到第一页

Data segment X Y Z dw 1,3,5,7,9,8,7,6,9,9 dw 1,2,3,4,3,2,1,5,6,7 dw 10 dup (?)

Logic_rule dw 00dch Data ends Code segment

Main proc far
Assume cs:code,ds:data Start:

Push ds
Sub ax,ax Push ax

Mov ax,data
Mov ds,ax
跳转到第一页

Mov bx,0 Mov cx,10 Mov dx,logic_rule ;逻辑尺中数放DX中 Next: mov ax,x[bx] Shr dx,1 ; 取Xi数组中的i个数后放入AX中;(BX=i, i=1,2,3,….n) ;逻辑尺中最低位移入CF中

j c subtract ;判断CF=1/0?为1转SUBRTACT,为0顺序做下行加法 Add ax,y[bx] ; Xi数与Yi相加后的和放AX(BX=i, i=1,2,3,….n)

Jmp short result ;第i次的和要放入Zi数组中 (i=1,2,3,….n)
Subtract: Sub ax,y[bx] ;Xi数与Yi相减后的差放AX(BX=i, i=1,2,3,….n) Result: mov z[bx],ax ;把Xi数与Yi相加(减)后的和(差)放Zi数组中 (BX=i, i=1,2,3,….n) Add bx,2 ;下标加1(两个字节)

Loop next ;循环出口 Ret Main endp
跳转到第一页

这种设立逻辑尺的方法是很常用的。 如,把一组数据存入存储器时,如果其中数值为0的元素很 多,也可用这种方法设立一个每位表示一个下标的逻辑尺, (这样的逻辑尺可能占有几个字,由数组的长度确定。) 0元 素就可不占有存储单元了。

在例5·5中,每个标志只占一位,如果要表示的特征数更多, 则每个标志可占有几位,在处理方法上是完全相同的。
设立标志位的方法,除了如逻辑尺那样可静态地预置外, 还可以在程序中动态地修改标志位的值以达到控制的目的,下 例说明这种方法。

跳转到第一页

1 lea bx,buffer ;放缓冲器地址到BX中 2 mov flag ,0 ;标志FLAG置0 3 Next: mov ah,01 ;P471键盘输入字符放AL,并回显,AH=01为参数 调用 4 int 21h ;同上 5 test flag,01h ;测试FLAG位是否为10

6 7 8 9
10

1 )

jnz follow cmp al,20h jnz exit mov flag,1
jmp next

;不为0后则转FOLLOW处开始输入字符 ;flag为0,判断第一个字符是否为空格 ;输入的字符不为空格(ASCII=20H),退出 ;输入的字符为空格,则FLAG置
;转NEXT句,转下一个字符输入并比较(循环

11 follow: cmp al,20h ;接6行,FLAG为1后,输入字符与空格比较 12 jz exit ;为空格转EXIT 13 mov [bx],al ;不为空格,把AL内容放地址[BX]中 14 inc bx;地址增1 15 jmp next ;转下一个字符输入并比较(循环) 跳转到第一页

? ? ?

main endp code ends end start

跳转到第一页

3 4 5 6 7 8

loop1: loop2:

放前面a[bx],小数放后面a[bx+2]

mov di,cx ;大循环入口(保留CX计数器值,放DI) mov bx,0 ;一维数组下标初值为0 mov ax,a[bx] ;小循环入口 一维数组下标为BX数放AX中 cmp ax,a[bx+2];下标为BX与(BX+2)两数比较 jge cotinue ;比较后,前者大不交换,转COTINUE xchg ax,a[bx+2];比较后,后者大两数交换,即大数

9



mov a[bx],ax

;同上行,大数放a[bx],AX为中间交换

10 11 12 13 14

cotinue: add bx,2 ;一维数组下标初值为增2 隐含cx减1 loop loop2 ;小循环出口 mov cx,di ;从保留计数器DI中恢复到CX loop loop1;大循环出口(计数器CX减1,与11行比较) ret 隐含cx减1 main endp
跳转到第一页

5.2 分支程序的设计. 分支程序设计就是根据不同的条件让程序选择不同径中的一条. 分支程序设计分为两种形式:相当于 高级语言中的:
If -then- else
判别条 件

Case
判 别 条 件

………..

分支程序设计与循环程序设计比较,其特点是运行方向是向前的, 在判断条件以后只能执行多个分支中的一个分支。 分支程序设计多用条件跳转指令 实现。 跳转到第一页

试验教程:例2.4 显示月份名direct 试编写一程序,要求根据用户键入的月份数在终端上显示 该月的英文缩写名。本例要求根据月份数给出月份名,我们 可以建立一个月份表 Montab Db ‘jan’ Db ‘feb Db ‘mar’ 可以看出,‘JAN’的地址为MONTAB十0,‘FEB’的地址为 MONTAB十3,‘MAR’的地址为MONTAB十6,….,根据 用户给定的月份数可以计算出与其对应的表格地址,计算法 是 MoNTAB十(月份数一1)*3 应该注意,用户键入的月份数是ASCII码,必须转换为数字 才能用上述公式进行计算。根据上述算法,
跳转到第一页

在调试源程序之前:

介绍一下当ah=0a h时int 21h的动作
因为该程序要求从键盘输入1~2位数,用ah=1的int21功 能要输入两次,而且还要保存。如果要求输入的字符数更多 时,该功能显然失效。考虑用键盘输入到缓冲区中断。 功能:从键盘输入到缓冲区,ds:dx=缓冲区首地址, (ds:dx)=缓冲区最大字符数,(ds:dx+1)=缓冲区实际 输入的字符数。整个输入过程以回车结束。 1、在中断调用的时候,先根据最大字符数(ds:dx)分配空 间。等输入完毕后把实际字符数存入(ds:dx+1)即缓冲区 的第2个字节。实际字符数不包括回车。 2、因为有一个回车,回车也要占用一个字节。所以在规定 最大字符数的时候一定要比实际的最大字符数大1,留给回 车.
跳转到第一页

开始

询问‘MONTH?’

实际该程序主要的分支 有两个

见 源 程 序。

接收月份数
N 有输入否? Y 字符转换为数字 结束

计算相应的表格地址

1、判断输入的数是 一位的还是两位的分 别作不同的操作。

显示相应月份

2、根据地址计算的 结果不同做不同的动 作
跳转到第一页

练习:

将一个2进制数转换为10进制数
思想方法:比如要转换一个16位的2进制数,最大为65535。 将要转换的数与化成10进制数以后的最高位权值(10000) 相除所得的商放在一个寄存器中,表示万位。余数放在一个 寄存器中再于1000相除,商放在一个寄存器中表示千位,余 数在于100相除……最后分别把这些寄存器的数值转换为 ASCII码,显示出来。 注意:除数是10000是一个14位的2进制数显然除数要装在一 个16位的寄存器里面,那么被除数虽然也只有16位但是要符 号扩展到32位装在dx,ax中。
跳转到第一页


相关文章:
第五章 脂环烃习题答案(第五版)
第五章 脂环烃(P113-114) 1.分子式 C5H10 的环烷烃的异构体的构造式:(...1mol(A)与 1molHBr 作用生成(B)(B)也可以从(A)的同分异构体(C) ,与 ...
第五章 磁路与变压器试题及答案
第五章 磁路与变压器填空题 1,0.95 7000kW 负载的功率因数 2,(a);小;d; b(或 a);c(或 d) 3,铜损;铁损 4,短路铜环. 5,涡流损耗;磁滞损耗 6,消除...
线性代数第五章答案
第五章 相似矩阵及二次型 1. 试用施密特法把下列向量组正交化: 1 1 1 (1...解由 2 1 0 2 λ 1 5 a λ 3 1 = 0 , 1 b 2 λ 1 0 2 λ ...
会计基础 第五章 借贷记账法下主要经济业务的账务处理
第8页 会计从业资格考试辅导 【考点 3】生产成本计算与结转 会计基础(第五章) 借:生产成本——A 产品 材料费用 生产成本——B 产品 制造费用 贷:原材料 借:...
宏观经济学第五章习题答案
宏观经济学第五章习题答案_经济学_高等教育_教育专区。第五章习题参考答案一、...? 1125 1 ? b(1 ? t) 1 ? 0.8(1 ? 0.25) 0.4 这时预算盈余 BS=...
机械制造装备设计第五章习题答案(关慧贞)
机械制造装备设计第五章习题答案(关慧贞)_工学_高等教育_教育专区 暂无评价|0人阅读|0次下载|举报文档 机械制造装备设计第五章习题答案(关慧贞)_工学_高等教育_...
第五章答案
第五章答案_财会/金融考试_资格考试/认证_教育专区。5.1 简述电压测量的基本要求及电压测量仪器的分类方法。 答:电压测量的基本要求: 1)应有足够宽的电压测量范...
软件工程导论 第五章课后答案
软件工程导论 第五章课后答案_理学_高等教育_教育专区。第五章 习题答案 1、 ...b.数据耦合(Data Coupling)即一个模块访问另一个模块时,彼此 之间是通过数据...
第五章 病毒 导学案
第五章《病毒》八年级 主备课人: 谢恒 审核 班 小组 姓名: 编号 03 年月...放大镜 B.电子显微镜 C.望远镜 2.病毒的结构是由什么组成的( A.细胞壁、...
编译原理 第二版 第五章答案
第五章第 5 章自顶向下语法分析方法 练习(P99) 1.文法 S->a|^|(T) T...P→(E)|a|b|^ (1) 计算这个文法的每个非终结符的 FIRST 集和 FOLLOW 集...
更多相关标签: