第五章 循环与分支程序设计
合集下载
第5讲 循环与分支程序设计

; ’0’~’9’ ASCII 30H~39H
; ’A’~’F’数 n 插入一个已整序的正数字数组
loop和[bx]的联合应用
• 计算ffff:0~ffff:b单元中的数据的和,结 果存储在dx中。 • 分析: 怎样解决这两个看似矛盾的问题? 目前的方法(在后面的课程中我们还有 别的方法)就是我们得用一个16位寄 存器来做中介。
loop和[bx]的联合应用
• 我们将内存单元中的 8 位数据赋值到 一个16位寄存器ax中,再将ax中的数据 加到dx上,从而使两个运算对象的类 型匹配并且结果不会超界。
一段安全的空间
• 在8086模式中,随意向一段内存空间写 入内容是很危险的 ,因为这段空间中 可能存放着重要的系统数据或代码。 • 比如下面的指令: mov ax,1000h mov ds,ax mov al,0 mov ds:[0],al
一段安全的空间
• 我们以前在Debug中,为了讲解上的方便, 写过类似的指令。 • 但这种做法是不合理的 ,因为之前我们并 没有论证过 1000:0中是否存放着重要的系统 数据或代码。 • 如果1000:0中存放着重要的系统数据或代码, “mov ds:[0],al” 将其改写,将引发错误。 •
在循环开始前设(bx)=0,每次循环,将bx中 的内容加1即可。
loop和[bx]的联合应用
• 分析: (续)更详细的算法描述初 始化
(ds)=0ffffh (bx)=0 (dx)=0 (cx)=12 循环12 次: s:(al)=((ds)*16+(bx)) (ah)=0 (dx)=(dx)+(ax) (bx)=(bx)+1 loops
Loop指令
• 任务3:编程计算2∧12。 分析: 2∧12=2*2*2*2*2*2*2*2*2*2*2*2,若设 (ax)=2,可计算: (ax)= (ax)*2*2*2*2*2*2*2*2*2*2*2,最 后(ax)中为2∧12的值。N*2可用N+N 实现。
C语言 第五章-循环结构程序设计

执行过程如图所示。其中i为外循环的控制变 量,j为内循环的控制变量。
i =0 当 i <=10
j=0 当 j<=10
printf(“%d ”, i*j ) j++ i++
例4 编程打印“九九乘法表”。
分析:九九乘法表 1×1=1 1×2=2 1×3=3 … 2×1=2 2×2=4 2×3=6 … 3×1=3 3×2=6 3×3=9 … …… 9×1=9 9×2=18 9×3=27 …
i ++ ; } while ( i <= 100 ) ; printf ( " %d " , sum ) ; }
结果相同
同样是下列程序,但如果while后面的表达式结果一开始就是 假时,两种循环结果会不一样。
main ( ) /*程序1*/
{ int i , sum = 0 ; i = 101 ;
所以程序需要设计成二重循环。由于题目只 要求找到一组解,所以在循环过程中只要找到一组 满足条件的x, y, z就可以跳出循环。
跳出循环的方法可以采用break语句,但是, 因为是二重循环,所以要考虑使用break是否方便。
程序 百钱买百鸡问题。 void main ( ) { int x , y , z ;
打印第2行 ( i = 2 ) for (j=1;j<=9;j++) printf(“%5d”,i*j) ; printf ( “ \n ” ) ; /*换行打印*/
…… 打印第9行 ( i = 9 )
for (j=1;j<=9;j++) printf(“%5d”,i*j) ; printf ( “ \n ” ) ; /*换行打印*/
循环与分支程序设计

cl,4 bx,cl al,bl al,0fh al,30h al,3ah printit al,7h
printit: mov mov int dec jnz mov int prognam end
dl,al ah,2 21h ch rotate ah,4ch 21h ends start
开始 1的个数计数器←0 循环次数计数器CX←16
例5.2 在ADDR单
元存放着数Y的 地址,试编制一 程序把Y中1的 个数存入 COUNT单元中
Y左移一次 CF=1 N
Y
1的个数计数器+1 CX ←CX-1=0 N
Y
COUNT ← 1的个数计数器 结束
循环次数固定,完全由循环计数器控制
例5.2
DATA SEGMENT Y DW 1234H ADDR DW Y COUNT DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV DL,0 MOV BX,ADDR MOV AX,[BX] MOV CX,16 REPEAT: SHL AX,1 JNC NEXT INC DL LOOP REPEAT MOV COUNT,DL MOV AH,4CH INT 21H ENDS END START
例5址分别为ARRAY_ HEAD 和 ARRAY_ END,其中所有的数均为正数。
例5.4 mov ax,n mov array_head-2,-1 mov si,0 Comp:cmp movarray_end[si],ax bx,array_end[si] jle insert cmp bx,ax mov bx,array_end[si] jle insert mov array_end[si+2],bx sub si,2 jmp comp Insert: mov array_end[si+2],ax mov ah,4ch int 21h Program ends end start
printit: mov mov int dec jnz mov int prognam end
dl,al ah,2 21h ch rotate ah,4ch 21h ends start
开始 1的个数计数器←0 循环次数计数器CX←16
例5.2 在ADDR单
元存放着数Y的 地址,试编制一 程序把Y中1的 个数存入 COUNT单元中
Y左移一次 CF=1 N
Y
1的个数计数器+1 CX ←CX-1=0 N
Y
COUNT ← 1的个数计数器 结束
循环次数固定,完全由循环计数器控制
例5.2
DATA SEGMENT Y DW 1234H ADDR DW Y COUNT DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV DL,0 MOV BX,ADDR MOV AX,[BX] MOV CX,16 REPEAT: SHL AX,1 JNC NEXT INC DL LOOP REPEAT MOV COUNT,DL MOV AH,4CH INT 21H ENDS END START
例5址分别为ARRAY_ HEAD 和 ARRAY_ END,其中所有的数均为正数。
例5.4 mov ax,n mov array_head-2,-1 mov si,0 Comp:cmp movarray_end[si],ax bx,array_end[si] jle insert cmp bx,ax mov bx,array_end[si] jle insert mov array_end[si+2],bx sub si,2 jmp comp Insert: mov array_end[si+2],ax mov ah,4ch int 21h Program ends end start
[工学]第05章 循环结构程序设计 (2)
![[工学]第05章 循环结构程序设计 (2)](https://img.taocdn.com/s3/m/90d7833fff00bed5b9f31d37.png)
T
22
i=i+c
2019/2/17
例:#include<stdio.h> 例:#include<stdio.h> main( ) main( ) { int i=0; { int i=0; for(;i<10;i++) for(i=0;i<10;i++) putchar(‘a’+i); putchar(‘a’+i); } } 运行结果:abcdefghij
2019/2/17
21
(7)表达式2一般是关系表达式(如 for语句说明4 i<=100)或逻辑 表达式(如a<b&&x<y),但也可以是数值表达式 或字符表达式,只要其值为非零,就执行循环体。分 析下面两个例子: ①for ( i=0;(c=getchar( ))!=‘\n’;i+ =c); i=0 此 for语句的执行过程见图 ,它的作 用是不断输入字符,将它们的ASCII 取一个字 码相加,直到输入一个“换行”符为 符=>c 止。 F ② for( ;(c=getchar( ))!=‘ \ n’;) C≠换行符 printf(“%c”,c);
15
思考:该程序是什么功能?
2019/2/17
5.3 for语句
for循环语句是C语言中功能最强的循环语句,它有
多个变化形式,并且可以很方便的代替其它的循环语
16
句。 for语句的一般形式
for(表达式1;表达式2;表达式3)循环体语句
2019/2/17
17
for执行流程
①先计算初值表达式1,它主要 用于循环开始前设置变量初值; ②接着计算循环控制逻辑表达式 2,它控制循环条件,决定循环 次数; ③如果表达式2为真,则执行循 环体语句,否则结束for循环; ④求解表达式3,它主要是对循 环控制变量进行修改。 ⑤转步骤②执行。
22
i=i+c
2019/2/17
例:#include<stdio.h> 例:#include<stdio.h> main( ) main( ) { int i=0; { int i=0; for(;i<10;i++) for(i=0;i<10;i++) putchar(‘a’+i); putchar(‘a’+i); } } 运行结果:abcdefghij
2019/2/17
21
(7)表达式2一般是关系表达式(如 for语句说明4 i<=100)或逻辑 表达式(如a<b&&x<y),但也可以是数值表达式 或字符表达式,只要其值为非零,就执行循环体。分 析下面两个例子: ①for ( i=0;(c=getchar( ))!=‘\n’;i+ =c); i=0 此 for语句的执行过程见图 ,它的作 用是不断输入字符,将它们的ASCII 取一个字 码相加,直到输入一个“换行”符为 符=>c 止。 F ② for( ;(c=getchar( ))!=‘ \ n’;) C≠换行符 printf(“%c”,c);
15
思考:该程序是什么功能?
2019/2/17
5.3 for语句
for循环语句是C语言中功能最强的循环语句,它有
多个变化形式,并且可以很方便的代替其它的循环语
16
句。 for语句的一般形式
for(表达式1;表达式2;表达式3)循环体语句
2019/2/17
17
for执行流程
①先计算初值表达式1,它主要 用于循环开始前设置变量初值; ②接着计算循环控制逻辑表达式 2,它控制循环条件,决定循环 次数; ③如果表达式2为真,则执行循 环体语句,否则结束for循环; ④求解表达式3,它主要是对循 环控制变量进行修改。 ⑤转步骤②执行。
C语言程序设计:第5章 循环结构

执行过程: 先执行循环体语句,再检查 循环条件表达式的值是否为真, 如果为真则继续执行循环体语句, 否则结束循环。
12
do...while语句(cont...)
课堂练习: 1.输出1---n之间的数,其中n从键盘输入。
int main(void) {
//1.定义变量i和n //2.输入n的值 //3.思考循环的开始条件:i从1开始 //4.思考循环的结束条件:i++,i > n //5.循环的条件:i<=n //6.循环要做的事情:输出i的值 return 0; }
} 相当于 while(1) {
}
26
小结
❖for(i=m;i<n;i++)//循环次数:n-m次 ❖for(i=m;i<=n;i++)//循环次数:n-m+1次
27
循环语句的练习
课堂练习: 1.输出n---1之间的数,其中n>1且n从键盘输入。 2.计算1*2*3*...*n的值(n的阶乘n!), 其中n从键盘输入。 3.计算10- 1/2 - 1/3 -....1/n的值 以上练习分别以while、do...while、for语句实现
int main(void) {
//1.定义变量i,n,sum //2.输入n的值 //3.思考循环的开始条件:i从1开始 //4.思考循环的结束条件:i++,i > n //5.循环的条件:i<=n //6.循环要做的事情:累加i的值 //7.输出计算结果 return 0; }
24
for语句(cont...)
{
sum = sum + i;
if(sum > 100)break;
12
do...while语句(cont...)
课堂练习: 1.输出1---n之间的数,其中n从键盘输入。
int main(void) {
//1.定义变量i和n //2.输入n的值 //3.思考循环的开始条件:i从1开始 //4.思考循环的结束条件:i++,i > n //5.循环的条件:i<=n //6.循环要做的事情:输出i的值 return 0; }
} 相当于 while(1) {
}
26
小结
❖for(i=m;i<n;i++)//循环次数:n-m次 ❖for(i=m;i<=n;i++)//循环次数:n-m+1次
27
循环语句的练习
课堂练习: 1.输出n---1之间的数,其中n>1且n从键盘输入。 2.计算1*2*3*...*n的值(n的阶乘n!), 其中n从键盘输入。 3.计算10- 1/2 - 1/3 -....1/n的值 以上练习分别以while、do...while、for语句实现
int main(void) {
//1.定义变量i,n,sum //2.输入n的值 //3.思考循环的开始条件:i从1开始 //4.思考循环的结束条件:i++,i > n //5.循环的条件:i<=n //6.循环要做的事情:累加i的值 //7.输出计算结果 return 0; }
24
for语句(cont...)
{
sum = sum + i;
if(sum > 100)break;
第5章 循环与分支程序设计

2018/11/8
CH5
5.1 循环程序设计
循环结构一般是根据某一条件判断为真
或假来确定是否重复执行循环体
循环指令和转移指令可以实现循环控制
2018/11/8
CH5
● 循环程序结构形式
初始化
初始化
控制条件
Y
N N
循环体 控制条件
Y
循环体
DO-WHILE 结构
DO-UNTIL 结构
2018/11/8
2018/11/8
CH5
(3)循环控制条件 循环次数已知,可以使用: ●LOOP指令实现,但是必须注意: 循环移位指令中使用CL寄存器作为 移位次数寄存器,LOOP 指令的循 环次数隐含在CX寄存器中,避免这 两者之间的冲突。
● 条件跳转指令实现。
LOOP AGAIN DEC 计数器 JNZ AGAIN
xor ax,ax push ax X dw 5 1.简单的加减法运算,直接用加减法指令实现 mov ax,data Y dw 6 mov ds,ax 2. 数据存储方式 : 字节、字、双字、四字等 W dw 7 mov ax,Y Z dw ? 3.寻址方式:直接寻址 sub ax,X data ends add ax,W mov Z,ax code segment ret
2018/11/8
CH5
开始 初始化CX=0 Y
N
Y=0? N
Y=-? Y
CX←CX+1 Y逻辑左移1位
;移位
; ’0’~’9’ ASCII 30H~39H
; ’A’~’F’ ASCII 41H~46H
2018/11/8
CH5
方法2 (条件跳转指令)
rotate:
CH5
5.1 循环程序设计
循环结构一般是根据某一条件判断为真
或假来确定是否重复执行循环体
循环指令和转移指令可以实现循环控制
2018/11/8
CH5
● 循环程序结构形式
初始化
初始化
控制条件
Y
N N
循环体 控制条件
Y
循环体
DO-WHILE 结构
DO-UNTIL 结构
2018/11/8
2018/11/8
CH5
(3)循环控制条件 循环次数已知,可以使用: ●LOOP指令实现,但是必须注意: 循环移位指令中使用CL寄存器作为 移位次数寄存器,LOOP 指令的循 环次数隐含在CX寄存器中,避免这 两者之间的冲突。
● 条件跳转指令实现。
LOOP AGAIN DEC 计数器 JNZ AGAIN
xor ax,ax push ax X dw 5 1.简单的加减法运算,直接用加减法指令实现 mov ax,data Y dw 6 mov ds,ax 2. 数据存储方式 : 字节、字、双字、四字等 W dw 7 mov ax,Y Z dw ? 3.寻址方式:直接寻址 sub ax,X data ends add ax,W mov Z,ax code segment ret
2018/11/8
CH5
开始 初始化CX=0 Y
N
Y=0? N
Y=-? Y
CX←CX+1 Y逻辑左移1位
;移位
; ’0’~’9’ ASCII 30H~39H
; ’A’~’F’ ASCII 41H~46H
2018/11/8
CH5
方法2 (条件跳转指令)
rotate:
第五章 循环与分支程序设计

12
continue: add loop mov loop ……
2. 分支程序设计
? ? … case 1 case 2 case n case 1 case 2 case n
CASE 结构
(1) 逻辑尺控制 (2) 条件控制
IF-THEN-ELSE 结构
(3) 地址跳跃表(值与地址有对应关系的表) 地址跳跃表(值与地址有对应关系的表)
13
x(x1,x2,…… x2,……,x10) 例:有数组 x(x1,x2,……,x10) 和 y(y1,y2,……,y10), (z1,z2,…… z2,……,z10) 编程计算 z(z1,z2,……,z10) z1 = x1 z2 = x2 z3 = x3 z4 = x4 z5 = x5 z6 = x6 z7 = x7 z8 = x8 z9 = x9 + y1 + y2 - y3 - y4 - y5 + y6 - y7 - y8 + y9
3
1. 循环程序设计
初始化
初始化
N N
控制条件
Y
循环体 控制条件
Y
循环体
DO-WHILE 结构
DO-UNTIL 结构
4
初始化:设置循环的初始状态 循环体:循环的工作部分及修改部分 控制条件:计数控制
特征值控制 地址边界控制
5
例:把 BX 中的二进制数以十六进制的形式显示在屏幕上
BX
1
2 3
4je lea L: shr jnb jmp add1: add jmp continue: …… routine1: …… routine2: …… al, 0
(寄存器间接寻址) 寄存器间接寻址)
continue bx, branch_table ;逻辑右移 al, 1 逻辑右移 ;jnb=jnc add1 ;段内间接转移 word ptr[bx] bx, type branch_table L
continue: add loop mov loop ……
2. 分支程序设计
? ? … case 1 case 2 case n case 1 case 2 case n
CASE 结构
(1) 逻辑尺控制 (2) 条件控制
IF-THEN-ELSE 结构
(3) 地址跳跃表(值与地址有对应关系的表) 地址跳跃表(值与地址有对应关系的表)
13
x(x1,x2,…… x2,……,x10) 例:有数组 x(x1,x2,……,x10) 和 y(y1,y2,……,y10), (z1,z2,…… z2,……,z10) 编程计算 z(z1,z2,……,z10) z1 = x1 z2 = x2 z3 = x3 z4 = x4 z5 = x5 z6 = x6 z7 = x7 z8 = x8 z9 = x9 + y1 + y2 - y3 - y4 - y5 + y6 - y7 - y8 + y9
3
1. 循环程序设计
初始化
初始化
N N
控制条件
Y
循环体 控制条件
Y
循环体
DO-WHILE 结构
DO-UNTIL 结构
4
初始化:设置循环的初始状态 循环体:循环的工作部分及修改部分 控制条件:计数控制
特征值控制 地址边界控制
5
例:把 BX 中的二进制数以十六进制的形式显示在屏幕上
BX
1
2 3
4je lea L: shr jnb jmp add1: add jmp continue: …… routine1: …… routine2: …… al, 0
(寄存器间接寻址) 寄存器间接寻址)
continue bx, branch_table ;逻辑右移 al, 1 逻辑右移 ;jnb=jnc add1 ;段内间接转移 word ptr[bx] bx, type branch_table L
循环与分支程序设计

注意循环与分支的执行效率
循环与分支的执行效率
在编写循环和分支语句时,应注意程序的执行效率。过多的循环和分支语句会 导致程序运行缓慢,影响用户体验。
提高执行效率的方法
尽量减少不必要的循环和分支语句,使用合适的数据结构和算法,以及优化代 码逻辑。同时,可以使用性能分析工具来检测程序的性能瓶颈,并进行针对性 的优化。
05
CATALOGUE
循环与分支的编程实践
使用循环结构实现数组的遍历
循环结构
在编程中,循环结构是一种重复执行一段代码块的控制结构,可以根据条件来决定循环的次数。常见的循环结构有 for循环、while循环和do-while循环。
数组遍历
数组是一种数据结构,用于存储相同类型的元素。使用循环结构可以实现数组的遍历,即将数组中的每个元素执行相 同的操作。
注意循环与分支的逻辑正确性
循环与分支的逻辑正确性
在编写循环和分支语句时,应注意逻辑的正确性。错误的逻辑可能导致程序出现意外的结果或错误。
保证逻辑正确性的方法
在编写代码之前,应先进行详细的需求分析和设计,明确循环和分支的逻辑关系。同时,应进行充分 的测试,确保程序的逻辑正确性。在代码编写过程中,可以使用注释、文档和代码审查等方式来提高 代码的可读性和可维护性。
示例
在Python中,可以使用if语句来 实现条件判断,根据条件的结果 执行不同的代码块。
结合循环与分支实现算法设计
算法设计
算法是一系列解决问题的步骤,通过算 法可以将复杂的问题分解为简单的操作 。结合循环和分支结构可以实现复杂的 算法设计。
VS
示例
冒泡排序算法是一种常见的排序算法,通 过结合循环和分支结构,可以实现将一个 数组按照从小到大的顺序排列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
也可以把计数值初始化为0,每循环一次加1,然后比 较判断
也可用LOOP指令
通过堆栈保存信息解决CX冲突问题
19/62
例:编制一个数据块移动程序 (已知 循环次数)
1)任务1:用程序设置数据
给内存数据段(DATA)中偏移 地址为n1开始的连续32个字节单 元,置入数据00H,01H, 02H,¨¨¨,1FH
……
……
00 n1
1F
n2
程序源代码请自己编写
23/62
OFFSET n1 SI
: 00 AL
: 32 CX
AL [SI]
AL+1 AL
SI+1 SI
CX-1 CX
N
CX=0?
Y
置入数据程序流程图
data1 n1 data1
segment db 32 dup (?) ends
00 n1
……
data2 n2 data2
第五章 循环与分支程序
5.1 循环程序设计 5.2 分支程序设计 5.3 如何在实模式下发挥 80386
及其后继机型的优势
1/62
本章目标
•掌握汇编语言程序设计的基本步骤 •熟练掌握顺序、分支和循环程序设计方法 •掌握汇编语言程序常用的几种退出方法 •掌握DOS系统功能调用
2/62
汇编语言程序设计的基本步骤
(3)DO_WHILE 结构
Y本身为0的可能性
开始 初始化C=0
Y Y=0?
N N
Y= - ? Y
C → COUNT 结束
C=C+1
Y逻辑左移1位
25/62
datarea
segment
开始
addr dw number
number dw y
初始化C=0
count datarea
dw ? segment
对有规律(连续)的内存单元操作,地址 有规律变化采用变址寻址方式
多次同样功能的处理,数据处理有规律, 采用循环程序结构
1、初始设置:
循环次数:连续32个字节单元,循环次数=32 数据初值:数据有规律变化,程序中可以自动
生成数据,数据初值=00H 变址指针初始化:内存数据段中偏移地址为n1
end start 26/62
例子5.3 删除在未经排序的数组中找到 的数(待找的数存放在AX中)P179
分析题意: (1)如果没有找到,则不对数组作任何处理 (2)如果找到这一元素,则应把数组中位于高
14/62
例5.1、试编制一个程序把BX寄存器内的二进 制数用十六进制数的形式在屏幕上显示出来
分析问题:把BX寄存器中16位的二进制数 用4位十六进制数的形式在屏幕上显示
1、初始设置
循环次数:每次显示1个十六进制数(送显示 器相应的ASCII),循环次数=4,CH=4
2、循环体
根据任务,选择算法
5.1 循环程序设计
5.1.1 循环程序的结构形式 5.1.2 循环程序的设计方法 5.1.3 多重循环程序设计
11/62
5.1.1 循环程序的基本结构
•两种基本结构
•三个基本组成部分: 循环初始化
1、初始设置
2、循环体 3、循环控制转移
条件 满足
不满足
循环体
DO-WHILE结构
循环初始化
循环体
endp
prognam ends
end start
熟记程序框架结构 和系统调用约定
17/62
rotate: printit:
mov mov rol mov and add cmp jl add mov mov int dec jnz
ch, 4 cl, 4 bx, cl al, bl al, 0fh al, 30h al, 3ah printit al, 7h dl, al ah, 2 21h ch rotate
mov si, offset n1 mov al, 0 mov cx, 32 mov [si], al inc si inc al dec cx jnz rotate
mov si, offset n1 mov di, offset n2 cld mov cx, 32 rep movsb
ret
main
程序结构:这个问题是数据块移动问题,可选择循环结构 或串传送指令来处理
选择串传送指令MOVSB,或REP MOVSB
数据定义:要定义源串和目的串
源串是任务(1)中所设置的数据 目的串要保留相应长度的空间
处理方法:MOVSB指令是字节传送指令, 它要求事先设置约定寄存器:
① 将源串的首偏移地址送SI,段地址为DS ② 目的串的首偏移地址送DI,段地址为ES ③ 串长度送CX寄存器中 ④ 并设置方向标志DF
2、循环体
根据任务,选择算法:一次设置一个字节 修改指针:变址指针修改 修改数据,生成新的数据 设置循环控制转移其他条件:无
3、循环控制转移
根据计数控制循环次数
21/62
选择寄存器 进一步细化程序流程 OFFSETn1 SI
循环的初始化部分完成
(1)将n1的偏移地址置入变址寄存器SI,这里的变址寄 存器作为地址指针用
y
5/62
程序结构
顺序结构
循环结构
分支结构
子程序结构
…
复合结构:多种程序结构的组合
6/62
顺序程序设计方法
程序的执行顺序是从程序的第一条可执 行指令开始执行,按照程序编写安排的 顺序逐条执行指令直到最后一条指令为 止
顺序程序结构所能解决的问题一般属于 简单的顺序性处理问题 如求:Y=(2*X+4*Y)*Z
AL,0 X,AL BIG SAV AL,0FFH ;小于0 SHORT SAV AL,1 ;大于0 Y,AL ;保存结果
9/62
循环程序设计方法
有一段指令被重复多次执行
被循环多次执行的指令段称为循环体
适应于处理算法相同,每次处理时需要有规 律地改变数据或数据地址的问题
例如,求内存数据段中存放的N个字节
Y Y=0?
prognam segment
N
C → COUNT
mian proc far
N Y= - ?
assume cs:prognam, ds:datarea
结束 Y
start: push ds
C=C+1
sub ax, ax push ax
Y逻辑左移1位
mov ax, datarea
mov ds, ax
……
00 n1
1F
2)任务2:移动数据
将内存数据段(DATA)中偏移 地址为n1的数据传送到偏移地址 为n2开始的连续的内存单元中去
……
n2
20/62
1)任务1:用程序设置数据 给内存数据段(DATA)中偏移地址为n1开始的连续32个字 节单元,置入数据00H,01H,02H,¨¨¨,1FH
程序设计中最基本的结构
7/62
分支程序设计方法
分支程序是根据判断条件转向不同的处 理,则要采用分支程序结构。当执行到 条件判断指令时,程序必定存在两个以 上分支
两分支:条件转移,标志寄存器,直接寻址
满足条件(条件成立) 不满足条件(条件不成立)
多分支:无条件转移,变址寄存器,存储器
间接寻址
程序每次只能执行其中一个分支
1 C1
条件
2
n
C2
...
Cn
多分支结构 8/62
例1.实现符号函数Y的功能。 其中:-128≤X≤+127
1当X>0时 Y= 0当X=0时
-1当X<0时
X DB Y DB
? ;被测数据 ? ;函数值单元
MOV CMP JG JZ MOV JMP BIG: MOV SAV: MOV
每4位二进制数转换成1位十六进制数的ASCII 调用DOS系统功能在屏幕上显示
3、循环控制转移
根据计数控制循环次数
流程图 15/62
BX
1 2 3 4
16/62
没有数据分配问题,直接编写程序代码段
流程图
prognam segment main proc far
Assume cs:prognam start:
满足 条件 不满足
DO-UNTIL结构
12/62
5.1.2 循环程序的设计方法
分析任务,实现三要素:
1、初始设置
循环次数,数据和变址指针初始化等
2、循环体
根据任务,选择算法 修改指针等 设置循环控制转移其他条件
3、循环控制转移
正确选择条件转移指令,2要素
循环次数 其他条件,如FLAGS
1.分析问题 根据实际任务(问题)确定任务的数据结构、处理的数 学模型或逻辑模型;
2.确定算法 确定所要解决问题的适当算法,既处理步骤,如何解决 问题,完成任务;
3.绘制流程图 设计整个程序处理的逻辑结构,从粗流程到细流程; 4.存储空间分配 分配数据段、堆栈段和代码段的存储空间,分配工
作单元,借助数据段、堆栈段和代码段定义的伪操作实现; 5.编写汇编语言源程序 正确运用80X86CPU提供的指令、伪操作、宏
数据(或字数据)的某种运算(加、减、 循
乘、除,移动等等)
环
体
循环体是加、减、乘、除,移动等运算指令
设置一个地址指针指向这N个数据的首地址, 再设置一个计数器
每次运算之后,修改地址指针使其指向下一 个数据,依次执行N次
初始化
处理指令序列
控制指令序列
任务完成否 N Y
结束处理
循环程序结构
也可用LOOP指令
通过堆栈保存信息解决CX冲突问题
19/62
例:编制一个数据块移动程序 (已知 循环次数)
1)任务1:用程序设置数据
给内存数据段(DATA)中偏移 地址为n1开始的连续32个字节单 元,置入数据00H,01H, 02H,¨¨¨,1FH
……
……
00 n1
1F
n2
程序源代码请自己编写
23/62
OFFSET n1 SI
: 00 AL
: 32 CX
AL [SI]
AL+1 AL
SI+1 SI
CX-1 CX
N
CX=0?
Y
置入数据程序流程图
data1 n1 data1
segment db 32 dup (?) ends
00 n1
……
data2 n2 data2
第五章 循环与分支程序
5.1 循环程序设计 5.2 分支程序设计 5.3 如何在实模式下发挥 80386
及其后继机型的优势
1/62
本章目标
•掌握汇编语言程序设计的基本步骤 •熟练掌握顺序、分支和循环程序设计方法 •掌握汇编语言程序常用的几种退出方法 •掌握DOS系统功能调用
2/62
汇编语言程序设计的基本步骤
(3)DO_WHILE 结构
Y本身为0的可能性
开始 初始化C=0
Y Y=0?
N N
Y= - ? Y
C → COUNT 结束
C=C+1
Y逻辑左移1位
25/62
datarea
segment
开始
addr dw number
number dw y
初始化C=0
count datarea
dw ? segment
对有规律(连续)的内存单元操作,地址 有规律变化采用变址寻址方式
多次同样功能的处理,数据处理有规律, 采用循环程序结构
1、初始设置:
循环次数:连续32个字节单元,循环次数=32 数据初值:数据有规律变化,程序中可以自动
生成数据,数据初值=00H 变址指针初始化:内存数据段中偏移地址为n1
end start 26/62
例子5.3 删除在未经排序的数组中找到 的数(待找的数存放在AX中)P179
分析题意: (1)如果没有找到,则不对数组作任何处理 (2)如果找到这一元素,则应把数组中位于高
14/62
例5.1、试编制一个程序把BX寄存器内的二进 制数用十六进制数的形式在屏幕上显示出来
分析问题:把BX寄存器中16位的二进制数 用4位十六进制数的形式在屏幕上显示
1、初始设置
循环次数:每次显示1个十六进制数(送显示 器相应的ASCII),循环次数=4,CH=4
2、循环体
根据任务,选择算法
5.1 循环程序设计
5.1.1 循环程序的结构形式 5.1.2 循环程序的设计方法 5.1.3 多重循环程序设计
11/62
5.1.1 循环程序的基本结构
•两种基本结构
•三个基本组成部分: 循环初始化
1、初始设置
2、循环体 3、循环控制转移
条件 满足
不满足
循环体
DO-WHILE结构
循环初始化
循环体
endp
prognam ends
end start
熟记程序框架结构 和系统调用约定
17/62
rotate: printit:
mov mov rol mov and add cmp jl add mov mov int dec jnz
ch, 4 cl, 4 bx, cl al, bl al, 0fh al, 30h al, 3ah printit al, 7h dl, al ah, 2 21h ch rotate
mov si, offset n1 mov al, 0 mov cx, 32 mov [si], al inc si inc al dec cx jnz rotate
mov si, offset n1 mov di, offset n2 cld mov cx, 32 rep movsb
ret
main
程序结构:这个问题是数据块移动问题,可选择循环结构 或串传送指令来处理
选择串传送指令MOVSB,或REP MOVSB
数据定义:要定义源串和目的串
源串是任务(1)中所设置的数据 目的串要保留相应长度的空间
处理方法:MOVSB指令是字节传送指令, 它要求事先设置约定寄存器:
① 将源串的首偏移地址送SI,段地址为DS ② 目的串的首偏移地址送DI,段地址为ES ③ 串长度送CX寄存器中 ④ 并设置方向标志DF
2、循环体
根据任务,选择算法:一次设置一个字节 修改指针:变址指针修改 修改数据,生成新的数据 设置循环控制转移其他条件:无
3、循环控制转移
根据计数控制循环次数
21/62
选择寄存器 进一步细化程序流程 OFFSETn1 SI
循环的初始化部分完成
(1)将n1的偏移地址置入变址寄存器SI,这里的变址寄 存器作为地址指针用
y
5/62
程序结构
顺序结构
循环结构
分支结构
子程序结构
…
复合结构:多种程序结构的组合
6/62
顺序程序设计方法
程序的执行顺序是从程序的第一条可执 行指令开始执行,按照程序编写安排的 顺序逐条执行指令直到最后一条指令为 止
顺序程序结构所能解决的问题一般属于 简单的顺序性处理问题 如求:Y=(2*X+4*Y)*Z
AL,0 X,AL BIG SAV AL,0FFH ;小于0 SHORT SAV AL,1 ;大于0 Y,AL ;保存结果
9/62
循环程序设计方法
有一段指令被重复多次执行
被循环多次执行的指令段称为循环体
适应于处理算法相同,每次处理时需要有规 律地改变数据或数据地址的问题
例如,求内存数据段中存放的N个字节
Y Y=0?
prognam segment
N
C → COUNT
mian proc far
N Y= - ?
assume cs:prognam, ds:datarea
结束 Y
start: push ds
C=C+1
sub ax, ax push ax
Y逻辑左移1位
mov ax, datarea
mov ds, ax
……
00 n1
1F
2)任务2:移动数据
将内存数据段(DATA)中偏移 地址为n1的数据传送到偏移地址 为n2开始的连续的内存单元中去
……
n2
20/62
1)任务1:用程序设置数据 给内存数据段(DATA)中偏移地址为n1开始的连续32个字 节单元,置入数据00H,01H,02H,¨¨¨,1FH
程序设计中最基本的结构
7/62
分支程序设计方法
分支程序是根据判断条件转向不同的处 理,则要采用分支程序结构。当执行到 条件判断指令时,程序必定存在两个以 上分支
两分支:条件转移,标志寄存器,直接寻址
满足条件(条件成立) 不满足条件(条件不成立)
多分支:无条件转移,变址寄存器,存储器
间接寻址
程序每次只能执行其中一个分支
1 C1
条件
2
n
C2
...
Cn
多分支结构 8/62
例1.实现符号函数Y的功能。 其中:-128≤X≤+127
1当X>0时 Y= 0当X=0时
-1当X<0时
X DB Y DB
? ;被测数据 ? ;函数值单元
MOV CMP JG JZ MOV JMP BIG: MOV SAV: MOV
每4位二进制数转换成1位十六进制数的ASCII 调用DOS系统功能在屏幕上显示
3、循环控制转移
根据计数控制循环次数
流程图 15/62
BX
1 2 3 4
16/62
没有数据分配问题,直接编写程序代码段
流程图
prognam segment main proc far
Assume cs:prognam start:
满足 条件 不满足
DO-UNTIL结构
12/62
5.1.2 循环程序的设计方法
分析任务,实现三要素:
1、初始设置
循环次数,数据和变址指针初始化等
2、循环体
根据任务,选择算法 修改指针等 设置循环控制转移其他条件
3、循环控制转移
正确选择条件转移指令,2要素
循环次数 其他条件,如FLAGS
1.分析问题 根据实际任务(问题)确定任务的数据结构、处理的数 学模型或逻辑模型;
2.确定算法 确定所要解决问题的适当算法,既处理步骤,如何解决 问题,完成任务;
3.绘制流程图 设计整个程序处理的逻辑结构,从粗流程到细流程; 4.存储空间分配 分配数据段、堆栈段和代码段的存储空间,分配工
作单元,借助数据段、堆栈段和代码段定义的伪操作实现; 5.编写汇编语言源程序 正确运用80X86CPU提供的指令、伪操作、宏
数据(或字数据)的某种运算(加、减、 循
乘、除,移动等等)
环
体
循环体是加、减、乘、除,移动等运算指令
设置一个地址指针指向这N个数据的首地址, 再设置一个计数器
每次运算之后,修改地址指针使其指向下一 个数据,依次执行N次
初始化
处理指令序列
控制指令序列
任务完成否 N Y
结束处理
循环程序结构