第五章 分支与循环程序设计
第5章 循环与分支程序设计2013.ppt.Convertor
第5章循环与分支程序设计编制汇编语言程序的步骤:(1) 分析题意,确定算法(2) 根据算法画出程序框图(3) 根据框图编写程序(4) 上机调试程序5.1循环结构程序设计(1)初始化部分:设置循环的初始状态这是循环的准备部分,为程序操作、地址指针、循环计数、结束条件等设置初始值。
(2)循环体:循环的工作部分及修改部分,包括以下3个部分:循环工作部分------这是循环程序的主体,完成程序的基本操作,循环多少次,这部分语句就执行多少次。
循环修改部分-----修改循环工作部分的变量地址等,这保证每次重复时,参加执行的数据能发生有规律的变化。
循环控制部分-----保证循环条件满足时进入循环;循环结束条件不满足时,退出循环,执行循环体外的后续语句。
(3)循环结束部分完成循环结束后的处理,如数据分析、结果的存放等。
循环程序典型结构【例5.1】P163 在ADDR单元中存放着数Y的地址,试编制一程序把Y中(指数Y所有二进制位中包含)1的个数存入COUNT单元中。
(PH163.asm)要测出Y中1的个数就应逐位测试。
一个比较简单的办法是可以根据最高有效位是否为1来计数,然后用移位的方法把各位数逐次移到最高位去。
TITLE 数1的程序DA TA SEGMENTADDR DW NUMBERNUMBER DW 12F0H ; Y的值COUNT D W ?DA TA ENDSCODE SEGMENTMAIN PROC FARASSUME CS:CODE,DS:DA TASTART:PUSH DSSUB AX,AXPUSH AXMOV AX,DA TAMOV DS,AXMOV CX,0MOV BX,ADDRMOV AX,[BX]REPEAT: CMP AX,0JZ EXITJNS SHIFTINC CXSHIFT:SHL AX,1JMP REPEATEXIT:MOV COUNT,CXRETMAIN ENDPCODE ENDSEND START【例5.2】P161 :把BX 中的二进制数以十六进制的形式显示在屏幕上……mov ch, 4rotate: mov cl, 4rol bx, clmov al, bland al, 0fhadd al, 30h ; ’0’~’9’ AS CII 30H~39Hcmp al, 3ahjl printitadd al, 7h ; ’A’~’F’ ASCII 41H~46Hprintit: mov dl, almov ah, 2int 21hdec chjnz rotate……例:从键盘接收十进制数并存入BX……mov bx, 0newchar: mov ah, 1 ;键盘输入int 21hsub al, 30hjl exit ; <0退出cmp al, 9jg exit ; >9退出cbw;?xchg ax, bxmov cx, 10mul cxxchg ax, bxadd bx, axjmp newcharexit: ……例:从键盘接收十六进制数并存入BX……mov bx, 0newchar: mov ah, 1 ;键盘输入int 21hsub al, 30hjl exit ; <0退出cmp al, 10jl add_tosub al, 27h ; ‘a’~‘f’cmp al, 0ahjl exit ; <‘a’退出cmp al, 10hjge exit ; >’f’退出add_to: mov cl, 4shl bx, clmov ah, 0add bx, axjmp newcharexit: ……1 a f31 61 66((0×16)+1) × 16+0a) × 16+0f【*例5.3A 】分别统计COUNT个数据中正、负数的个数。
ch09-分支与循环程序设计
第5章 分支与循环程序设计5.1. 概述设计步骤:描述问题→确定算法→绘制流程图→分配存储空间和工作单元→编写程序→上机调试5.2. 分支程序设计5.2.1 分支程序结构二路分支结构 多路分支结构5.2.2 二路分支程序设计方法例5.2.1⎪⎩⎪⎨⎧<-=>=)0(1)0(0)0(1x x x Y -128≤x ≤127DATASEGMENTXX1 DB 10; X=给定一个值YY1 DB ? ; Y DATAENDS CODESEGMENT ASSUME CS:CODE, DS:DATASTART: MOV AX, DSMOV DS, AXMOV AL,XX1CMP AL, 0JZ AA1; =0JNS AA2MOV AL,0FFH; =-1JMP AA1AA2: MOV AL,1; =1AA1: MOV YY1,AL;MOV AH,4CHINT 21HCODE ENDSEND START5.2.3多路分支程序设计方法逻辑分解法;地址表法;段内转移表法;1.逻辑分解法CODE SEGMENTASSUME CS:CODESTART: MOV AH,1INT 21H ;键入值CMP AL,31HJZ WORK1CMP AL,32HJZ WORK2CMP AL,33HJZ WORK3CMP AL,34HJZ WORK4CMP AL,35HJZ WORK5JMP WORK0WORK1: …(jmp work0)WORK2: …(jmp work0)WORK3: …(jmp work0)WORK4: …(jmp work0)WORK5: …(jmp work0)WORK0: MOV AH,4CHINT 21HCODE ENDSEND START2.地址表法把模块的地址保存在一个表中,通过查表跳到相应模块。
表地址= 表首地址+ (键号-1)*2DATA SEGMENTTABLE DW WORK1,WORK2,WORK3,WORK4,WORK5 DATA ENDSCODE SEGMENTASSUME CS:CODE, DS:DATASTART: MOV AX,DATAMOV DS,AXLEA BX,TABLE ;表首地址MOV AH,1INT 21HAND AL,0FHDEC AL ;键号-1ADD AL,AL ;(键号-1)*2SUB AH,AHADD BX,AX ;表地址= 表首地址+ (键号-1)*2JMP WORD PTR[BX]WORK1: …(jmp work0)WORK2: …(jmp work0)WORK3: …(jmp work0)WORK4: …(jmp work0)WORK5: …(jmp work0)WORK0:MOV AH,4CHINT 21HCODE ENDSEND START3.段内转移表法段内短转移:(jmp disp8为2字节指令)转移表地址=转移表首地址+(键号-1)*2段内近转移:(jmp disp16为3字节指令)转移表地址=转移表首地址+(键号-1)*3段间远转移:(jmp disp32为4字节指令)转移表地址=转移表首地址+(键号-1)*4 CODE SEGMENTASSUME CS:CODESTART: LEA BX,WORKMOV AH,1INT 21HAND 0FHDEC ALMOV AH,ALADD AL,ALADD AL,AH ;x3SUB AH,AHADD BX,AXJMP BX;转移表WORK: JMP NEAR PTR WORK1JMP NEAR PTR WORK2JMP NEAR PTR WORK3JMP NEAR PTR WORK4JMP NEAR PTR WORK5;工作模块WORK1: …(jmp work0)WORK2: …(jmp work0)WORK3: …(jmp work0)WORK4: …(jmp work0)WORK5: …(jmp work0)WORK0:MOV AH,4CHINT 21HCODE ENDSEND START5.3.循环程序设计5.3.1循环程序的结构形式5.3.2循环程序的设计方法方法:计数控制循环;条件控制循环;变量控制循环1.计数控制循环(循环次数已知)例:5.3.1, 把1,2,3 …255加起来。
第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 实现。
循环与分支程序设计
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
第5章 循环与分支程序设计
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:
第五章 循环与分支程序
8
单分支程序设计
例2:计算AX的绝对值 SUB ax, 0 jge nonneg ;条件满足(AX≥0)? neg ax ;条件不满足,求补 nonneg: mov result, ax ;条件满足 ;
9
单分支程序设计
例3:将AX中存放的无符号数除以2,如果是奇数, 则加1后除以2 test ax,01h ;测试AX最低位 jz even1 ;最低位为0:AX为偶数 add ax,1 ;最低位为1:AX为奇数,需要加1 even1:rcr ax,1 ;AX←AX÷2
分析题意,确定算法。找出合理的算法与适当的数据 结构 根据算法画出流程图 根据流程图编写程序 上机调试程序
汇编语言程序的结构组成
顺序结构 分支结构 循环结构 子程序的结构
4
《汇编语言》 汇编语言》
5.2 分支程序
目标
分支程序的结构及设计
双分支程序的结构及设计 多分支程序的结构及设计 单分支程序的结构及设计
算法
二分查找 地址址表实现多分支
6
分支程序的结构
分支程序
分支程序根据条件是真或假决定执行与否 判断的条件是各种指令,如SUB、CMP、TEST等执行后 形成的状态标志 转移指令Jcc和JMP可以实现分支控制
分支程序的结构形式
单分支 双分支 多分支
7
单分支程序设计
例1:计算X-Y的绝对值 mov ax,X sub ax,Y jns nonneg ;条件满足(X-Y≥0)? neg ax ;条件不满足,求补 nonneg: mov result,ax ;条件满足
11
双分支程序设计
例2:寄存器AL中是字母Y或y,则令AH=0;否则 令AH=-1 cmp al,’Y’ ;AL是大写Y否? jz next ;是,转移 cmp al,’y’ ;AL是小写y否? jz next ;是,转移 mov ah,-1 ;不是Y或y,AH=-1,结束 jmp done ;一定要跳过另一个分支体 next:mov ah,0 ;是Y或y,AH=0,结束 done:...
第五章 循环与分支程序设计
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
第5章 循环与分支程序设计PPT课件
END START
例5.3 在附加段中,有一个首地址为LIST和未经排序的字数组.在数组的第一 个字中,存放着该数组的长度,数组的首地址已存放在DI寄存器中,AX寄存器 中存放着一个数,要求编制程序,在数组中查找该数,如果找到此数,则把它从 数组中删除.
…
DS
X
ARRAY_HEAD
45
46
54
57
61
66
68
71
ARRAY_END
90
N
60
DATAREA SEGMENT
X
DW ?
ARRAY_HEAD DW 45,46,54,57,61,66,68,71
ARRAY_END DW 90
N
DW 60
DARAREA ENDS
PROGNAM SEGMENT MAIN PROC FAR
第五章 循环与分支程序设计
5.1 循环程序设计 5.2 分支程序设计 5.3 如何在实模式下发挥80386及其后继机型的优势
5.1 循环程序设计
一、循环程序的结构形式
循环初始状态
Y 循环控制条件
N 循环体
(1)设置循环的初始状态 (2)循环体 (3)循环控制部分
循环初始状态 循环体 N
循环控制条件 Y
Z8=X8-Y8 Z9=X9+Y9 Z10=X10+Y10
…
DATA SEGMENT
X
23
45
90
…
X DW 23,45,90,12,48,72,95,83,75,29 Y DW 36,53,27,89,51,28,46,94,27,65 Z DW 10 DUP(?) LOGIC DW 00DCH
循环与分支程序设计.
5.2 分支程序设计
一、分支程序的结构形式 分支程序的结构形式: 二分支 多分支
Y 判定条件 N
判定条件 …
IF_THEN_LESE结构
CASE结构
二、分支程序设计方法 1、折半查找算法 例3:在附加段中,有一个按从小到大顺序排列的无符号数数组,其首地址 存放在 DI寄存器中,数组中的第一个单元存放着数组长度。在AX中 有一个无符号数,要求在数组中查找(AX),如找到,则使CF=0,并 在SI中给出该元素在数组中的偏移地址;如未找到,则使CF=1。 (1)确定算法: 由于已经排序,因此可以采用折半查找算法。折半查 找法先取有序数组的中间元素与查找值相比较,如相 等则查找成功;如查找值大于中间元素,则再取高半 部的中间元素与查找值相比较;如查找值小于中间元 素,则再取低半部的中间元素与查找值相比较;如此 重复直到查找成功或未找到该数(查找不成功)为止。 在一个长度为 n的有序数组r中,查找元素k的折半查 找算法可描述如下: ①初始化被查找数组的首尾下标,low←1,high←n; ②若low>high,则查找失败,置CF=1,退出程序。 否则,计算中点:mid←(low+high)/2; ③ k与中点元素r[mid]比较。若k=r[mid],则 查找成功,程序结束;若k<r[mid],则转步骤④; 若k>r[mid],则转步骤⑤;
该注意在每次通过外层循环再次进入内层循环时,内层的初始条件必须重
新设置。如:最典型的就是起泡排序算法。
排序算法:从第一个数开始依次对相邻两个数进行比较。如次序对,则不
其它略。
做任何操作,如次序不对,则使两个数交换位置。如果有 N个 数要进行排序,则第一遍做了 (N-1)次比较后,最小的数已经 放到了最后,所以第二遍比较只需要考 (N-1)个数,即只需要 比较(N-2)次。第三遍则只需要做(N-3)次比较 … …总共最多 (N-1)遍比较就可以完成排序。
第五章 循环与分支程序设计
第五章:循环与分支程序设计 第五章:
在实际应用的程序中,通常碰到根据某一条件是否成立来进行逻辑判断, 以便确定程序的下一步执行,这就形成了分支结构程序.在汇编语言程序设 计中,分支结构程序设计是一种很重要的程序设计方法.循环结构是控制重 复执行某一程序段的基本程序结构.在高级语言中,普遍设置有专用的循环 语句作为实现循环程序的手段.在汇编语言程序设计中,循环程序的地位也 是极其重要的.从本质上看,循环程序结构是分支程序结构的一种特殊形式, 编程时,都是使用条件转移指令来控制循环的.
本章重点: 本章重点
1)掌握使用比较指令和其他有关指令产生的相应标志位,继而通过条 件转移指令来形成分支程序的设计方法. 2)掌握多路分支程序的结构形式以及多路分支程序的设计方法. 3)掌握循环程序的结构形式和程序设计方法. 课件具体内容请看:第五章
第五章 循环与分支程序设计
数据定义:要定义源串和目的串
00
n1
……
处理方法:MOVSB指令是字节传送指令, 它要求事先设置约定寄存器:
① ② ③ ④
1F
将源串的首偏移地址送SI,段地址为DS 目的串的首偏移地址送DI,段地址为ES 串长度送CX寄存器中 并设置方向标志DF
n2 ……
程序源代码请自己编写
23/62
OFFSET n1
14/62
例5.1、试编制一个程序把BX寄存器内的二进 制数用十六进制数的形式在屏幕上显示出来
分析问题:把BX寄存器中16位的二进制数 用4位十六进制数的形式在屏幕上显示
1、初始设置
循环次数:每次显示1个十六进制数(送显示 器相应的ASCII),循环次数=4,CH=4
2、循环体
根据任务,选择算法
X Y DB DB MOV CMP JG JZ MOV JMP BIG: MOV SAV: MOV ? ;被测数据 ? ;函数值单元 AL,0 X,AL BIG SAV AL,0FFH ;小于0 SHORT SAV AL,1 Y,AL ;大于0 ;保存结果
9/62
循环程序设计方法
有一段指令被重复多次执行
每4位二进制数转换成1位十六进制数的ASCII 调用DOS系统功能在屏幕上显示
3、循环控制转移
根据计数控制循环次数
流程图
15/62
BX
1
2 3
4
16/62
没有数据分配问题,直接编写程序代码段
prognam segment main proc far Assume cs:prognam start: push ds sub ax, ax push ax 初始化 rotate: 循环体 printit: mov dl, al mov ah, 2 int 21h dec ch jnz rotate 循环控制转移 ret 系统调用 显示1个字符 mov ch, 4 mov cl, 4 …
第5章循环与分支程序设计
编程方法-举例2
Data segment mess db 'Your Hex number is:$' bb db 00110100b, 00010010b Data ends Prognam segment assume cs: prognam, ds:data start: mov ax, data mov ds,ax lea dx, mess mov ah,9 int 21h
例5.7
• 有一个首地址为A的N字数组,请编制程 序使该数组中的数按照从大到小的次序 整序。
采用起泡排序算法 方法: 从第一个数开始依次对相邻两个数进行比 较。如次序对,则不做任何操作;如次序不 对,则将这两个数交换位置。
数据段
datarea segment n equ 12 ;此处修改 a dw n dup (?) datarea ends • 程序:例5.7
mov di, offset len ;此处修改} mov start_addr,di ;首地址存放在内存中 mov cx, es:[di] ;根据首地址取元素个数N mov save_cnt, cx ;个数N保存在内存 init: mov bx, 1 ;初始化设置 ;设BX = 1(即假设未作过交换数据) dec save_cnt ;做 count-l 次比较 jz sorted ;如save_cnt=O,退出 mov cx,save_cnt ;否则 比较次数放cx mov di,start_addr ;将开始地址放 DI
续 mov cx, es:[di] ;取长度
add di, 2 Repne scasw je delete Pop di jmp short exit delete: jcxz dec_cnt Next_el: ;移动 mov bx, es: [di] mov es:[di-2], bx add di, 2 loop next_el
第5章循环与分支程序设计
第5章循环与分支程序设计【课前思考】1. 编制一个汇编语言程序分哪几步?2. 循环程序有哪两种基本结构?由几部分组成?3. 设计算法时对可能出现的边界情况如何考虑?4. 如何设置逻辑尺?5. 什么是起泡排序算法?6. 如何理解数组排序算法中采用的折半查找法?7. 如何使用跳跃表法实现CASE结构?【学习目标】了解并掌握循环程序的构造方法,尤其是对循环控制条件的设置以及可能出现的边界情况的考虑。
掌握起泡排序算法这种多重循环程序设计中的常用方法。
交换标志位的设置在此算法中更能提高效率。
学会在数组排序算法中采用折半查找法来提高查找效率。
学会使用跳跃表法实现CASE结构。
【学习指南】掌握编程的四个步骤至关重要。
通过多看举例,学会正确分析理解题意、选择合适的数据结构及算法、坚持先画框图、选取有效指令编程、最后应当掌握运用调试手段进行调试。
学习多重循环程序设计前应熟练掌握单层循环程序设计的各种实现方法及实现细节,如对可能出现的边界情况的处理等。
学习起泡排序算法、折半查找法、跳跃表法之前,应首先理解传统实现方法。
【难重点】循环控制条件的选择。
考虑循环算法时注意可能出现的边界情况。
静态地预置逻辑尺。
动态地修改标志位。
多重循环程序设计时应分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。
另外,应该注意在每次通过外层循环再次进入内层循环时,初始条件必须重新设置。
起泡排序算法是多重循环程序设计中的一种常用方法。
数组排序算法中可以采用折半查找法来提高查找效率。
CASE结构可以使用跳跃表法实现。
【知识点】编制一个汇编语言程序的一般步骤5.1 循环程序设计5.1.1 循环程序的基本结构5.1.2 循环程序设计方法举例循环控制条件边界情况的处理逻辑尺5.1.3 多重循环程序设计举例起泡排序算法交换标志位5.2 分支程序设计5.2.1 分支程序的基本结构5.2.2 分支程序设计方法举例——折半查找法5.2.3 跳跃表法一般说来,编制一个汇编语言程序的步骤如下:1)分析题意,确定算法。
分支与循环程序设计
分支与循环程序设计一、分支程序设计分支程序设计是指根据条件的不同,执行不同的代码块。
在程序中,我们经常需要根据一定条件来选择执行不同的操作,这就需要使用分支结构来实现。
常见的分支结构有if语句和switch语句。
1. if语句:if语句是最基本也是最常用的分支结构之一、它的语法形式如下:```if (条件表达式)//如果条件为真,执行这里的代码块} else//如果条件为假,执行这里的代码块```if语句的条件表达式可以是逻辑表达式、比较表达式或其他具有确定值的表达式。
当条件表达式为真时,执行if后面的代码块;当条件表达式为假时,执行else后面的代码块。
2. switch语句:switch语句是一种多分支选择结构,它根据一些变量的值来决定执行哪个代码块。
它的语法形式如下:```switch (变量)case 值1://如果变量的值等于值1,执行这里的代码块break;case 值2://如果变量的值等于值2,执行这里的代码块break;default:// 如果变量的值不等于任何一个case,执行这里的代码块```switch语句根据变量的值与每个case的值进行比较,当找到匹配的case时,执行对应的代码块。
如果没有找到匹配的case,执行default后面的代码块。
循环程序设计是指重复执行一些代码块,直到满足一些条件为止。
在实际应用中,我们常常需要重复执行一些操作,这就需要使用循环结构来实现。
常见的循环结构有for循环、while循环和do-while循环。
1. for循环:for循环是最常用的循环结构之一,它的语法形式如下:```for (初始化表达式; 循环条件; 更新表达式)//循环体,执行这里的代码块```for循环由3个表达式组成:初始化表达式、循环条件和更新表达式。
在每次循环开始时,先执行初始化表达式;然后再判断循环条件,如果条件为真,执行循环体;执行完循环体后,再执行更新表达式。
第5章 顺序、分支和循环程序设计
(3) 根据流程图编写汇编程序:
DATA SEGMENT X DW ? Y DW ? Z DW ? RESULT DD ? ;RESULT为双字变量 DATA ENDS CODE SEGMENT ‘CODE’ ;代码段 ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX ;数据段段地址送DS中 MOV AX,X ADD AX,Y ; 计算X+Y→AX MOV BX,5 IMUL BX ;计算(X+Y)*5, AX*5→DX:AX ADD AX,8 ADC DX,0 ;计算(X+Y)*5+8,(DX:AX)+8→DX:AX SUB AX,X SBB DX,0 ;计算 (X+Y)*5+8-X,(DX:AX)-X→DX:AX IDIV Z ;计算((X+Y)*5+8-X)/Z 商→AX,余数 →DX MOV WORD PTR RESULT,AX ;商→RESULT MOV WORD PTR RESULT+2,DX ;余数→RESULT+2 MOV AX,4C00H ;程序结束返回DOS INT 21H
2.根据单个标志的条件转移指令
由标志寄存器中某一个标志位的状态而形成的条件转移指令。 可用做转移条件的标志位包括:ZF、CF、SF、OF及PF。
助பைடு நூலகம்符
JC JNC JZ/JE JNZ/JNE
功
有进位(或借位)时转移 无进位(或无借位)时转移 结果为零/相等时转移
能
转移条件
CF=1 CF=0 ZF=1 ZF=0
比较两个无符号数的大小 (由CF、ZF判断)
CMP DST ,SRC 做DST-SRC
汇编语言第五、六章:循环与分支程序设计
PUSH DS MOV AX,0 PUSH AX ③用户程序结束时,用RET指令
程序结束的方法
(2)使用DOS功能调用的“INT 21H”指令,实现 用户程序结束,返回DOS
方法:在程序结束前,使用如下指令 MOV AH,4CH INT 21H
注意:一般情况下,使用第2种方法结束用户程序。
3.与简化段定义有关的预定义符号
汇编程序给出了与简化段定义有关的一组预定义符号,它们可在程 序中出现,并由汇编程序识别使用。有关的预定义符号如下:
(1)@code 由.CODE 伪指令定义的段名或段组名。 (2)@data 由.DATA 伪指令定义的段名,或 由 .DATA 、.DATA?、.CONST和 .STACK所定义的段组名。 (3)@stack 堆栈段的段名或段组名。
第一节:循环结构
初始化
循环体
修改部分 Y
控制条件 N
结束
循环的初始状态
循环的工作部分 及修改部分
计数控制循环 条件控制循环
ห้องสมุดไป่ตู้
第五章第循一环章与基分础支知程识序设计
第五章第循一环章与基分础支知程识序设计
循环程序设计
根据条件重复执行一段指令就构成了循环程序结构 。
例:将ARRAY数组中的50个数求和,并将和存入字变量S中 。
……
00110001
16. 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0 0 (ROL DX,1) 0 0 0 0 0 0 0 1 (AND)
00000000 + 0 0 1 1 0 0 0 0 (ADD)
00110000
binbuf 30 31 30 30 30 30 31 30 30 30 31 31 30 30 30 30 返回
循环与分支程序设计
标志位
CF=0且ZF=0 CF=0或ZF=1 CF=1且ZF=0 CF=1或ZF=1 SF=OF且ZF=0 SF=OF或ZF=1
JP/JPE
JNP/JPO JO JNO
PF =1
PF =0 OF =1 OF =0
JL/JNGE
JLE/JNG JCXZ
SF≠OF且ZF=0
SF≠OF或ZF=1
CX=0
实际虽然指令只有19条,但却有31个助记符 采用多个助记符,只是为了方便记忆和使用
⑴ 段内转移、直接寻址 ⑵ 段内转移、间接寻址 ⑶ 段间转移、直接寻址 ⑷ 段间转移、间接寻址 目的地址与JMP属同一逻辑段, 只修改IP值 从一个代码段转移到另一个代码段,CS 和IP都会被修改
8
1. 无条件转移指令 —目标地址的寻址方式
直接寻址方式
用标号表达
间接寻址方式
转移地址象立即数一样,直接在指令的机器代码中,就 是直接寻址方式 用寄存器或存储
转移范围可以用一个字节表达,在段内 -128~+127范围的转移
代 码 段
10
1.无条件转移指令 —目标地址的范围:段间
段间转移——远转移(far)
从当前代码段跳转到另一个代码段,可以 在1MB范围
需要更改CS段基值和IP偏移地址
代 码 段
目标地址必须用一个32位数表达,叫做 32位远指针,它就是逻辑地址
19
判断单个标志位状态
这组指令单独判断5个状态标志之一 ⑴JZ/JE和JNZ/JNE:利用零标志ZF,判断结果是否为零 (或相等) ⑵JS和JNS:利用符号标志SF,判断结果是正是负 ⑶JO和JNO:利用溢出标志OF,判断结果是否产生溢出 ⑷JP/JPE和JNP/JPO:利用奇偶标志PF,判断结果中 “1”的个数是偶是奇
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
findmax: mov cmp jge mov skip: add dec JA mov mov int code ends end 返回
ax,[si] bx,ax skip bx,ax si,2 CX findmax max,bx ax,4c00h 21h
start
分支表(跳转表)结构
当一个程序有多个分支时,用 JXXX指令跳转将非常烦琐,程 序势必冗长,为了简便编程,采 用的方法是将多个分支的入口地 址组成一个表,称为跳转表,然 后用JMP指令跳转。例如:
如果CX的值等于0转<目标>,否则顺序执行 返回
用比较/测试—分支结构
在产生分支之前,通常用比较、测试,逻辑,算术运算,在标志寄存器 中设置相应的标志位,如前面所介绍的 SUB dest,src AND dest,src TEST dest,src 这里主要介绍比较指令:
CMP DEST, SRC 比较指令属于减法类指令,它在完成两个操作数相减(即(DEST)-(SRC))后, 仅把运算结果特征记录在Flags的相应标志位上:OF、SF、ZF、AF、PF、CF。 不保留运算结果。 – 对于无符号数,
Zero:
… Y
(AX)=0?
Zero:
… Y
N 去Zero
(AX)=0?
去Zero
N
Above: …
去Zero
N 去Above (a) 两路分支
(b) 多路分支
返回
分支举例
;文 件 名:MAX1.ASM ;编 写 者:金旺春 ;程序功能:求整数数组A中的最大值放在 BX ;编写日期:1996.11.10 data segment ints dw 8,-7,9,4,3,6,1,8,2 count equ ($-ints)/2 max dw ? data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov cx,count mov bx,-32768 lea si,ints
mov mov jmp Sub1:
bx,offset table bx,ax [bx] … jmp end0 Sub2: … jmp end0 Sub3: … jmp end0 …. Subn: … End0: mov ah,4ch int 21h Code ends end start 返回
5.3 循环程序设计
SF=OF AND ZF=0
SF=OF OR ZF=1
SF!=OF AND ZF=0
SF!=OF OR ZF=1
A>B A>=B A<B A<=B
返回
简单条件转移指令
根据单个标志位的状态判断转移条件
标志位 指令 JC JNC 转移条件 CF=1 CF=0 含义 有进位/借位 无进位/借位
CF
ZF
–
根据题意,知我们应该把BX的内容从左至右每四位一组在屏幕上显示出来,显然这 可以用循环结构来完成,每次循环显示一个十六进制数,因而循环次数是已知的,计数 值为4。 – 循环体内,• 则应该包括从二进制数到显示字符的ASCII码之间的转换及每个字符的显 示,• 0-9的ASCII码为30H-39H,A-F为41-46H,所以在把四位二进制加上30H后,还要再 作一次判断,如果为A-F,则还要另加7H后才能正确显示。 – 如假设(BX)=1010 1010 1010 1000B=0AAA8H,在屏幕上应显示AAA8。
简例
在ARRAY数组中依次存储有7个字数据:23,36,2,100,32000,54,0: ARRAY DW 23,36,2,100,32000,54,0 TOTAL DW ? 如果BX中包含数组ARRAY的初始地址,• 请编写指令,将数组ARRAY的和传送给 TOTAL单元中。 解:
MOV AX,0 LOOP1: MOV SI,0 ADD AX,[BX][SI] ADD SI,2 CMP SI,0CH JLE LOOP1 MOV TOTAL,AX
所谓循环,是指重复执行一块代码, 用分支程序设计,我们可以实现循环, 这里先讲专用的循环指令实现的循环。 1. 循环指令 2. 循环程序的结构形式 3. 简例 4. 循环程序设计方法 返回
循环指令
专用循环指令有三条: LOOP 循环 LOOPZ/LOOPE 当为零或相等时循环 LOOPNZ/LOOPNE 当不为零或不相等时循环 格式: 1) LOOP <标号> ;测试条件 (CX)<>0 2) LOOPZ/LOOPE <标号> ;测试条件 ZF=1 且 (CX)<>0 3) LOOPNZ/LOOPNE <标号> ;测试条件 ZF=0 且 (CX)<>0 这三条指令的执行步骤是: 1) (CX)←(CX)-1 2) 检查是否满足测试条件,如满足则 (IP)←(IP)+D8
CF=0 AND ZF=0 CF=0 OR ZF=1 CF=1 AND ZF=0 CF=1 OR ZF=1
A>B A>=B A<B A<=B
返回
带符号数条件转移指令
假设在条件转移指令前使用 比较指令,比较两个无符号数A和B, 指令进行的操作是 A-B,转移指令如下: 指令
转移条件 含义
JG/JNLE JGE/JNL JL/JNGE JLE/JNG
段内直接转移
段间转移
– JMP FAR PTR <标号>--------段内直接转移,远标号 – JMP DWORD PTR mem------段内间接转移 – <目标>的低字IP,高字CS
返回
条件转移指令
指令格式: JXXX <目标>
XXX是条件,若条件成立,则转移到<目标>处,否则顺序执行后续指令。 该指令经过编译后将产生一个8位的位移量disp(-128+127), 该 disp+(IP)IP 在使用条件转移指令前,通常是由一些算术运算、逻辑运算或某些比较、测试 指令的执行结果设置标志位,然后根据转移要求,选择一条或几条转移指 令。
1.
转移指令:分为无条件转移指令和条件转移指令两种
1) 2)
无条件转移指令 条件转移指令
2.
分支程序设计
1) 2)
用比较/测试—分支结构 分支表(跳转表)结构
返回
无条件转移指令
指令格式:
– JMP <目标> – <目标>:标号/mem/reg
段内转移
– JMP <标号>----------段内直接转移,近标号 – JMP reg – JMP WORD PTR mem – <目标>的内容IP
8位地址,在-128--+127之间
否则退出,(IP)不变,程序继续顺序执行。
返回
循环程序的结构形式
⑴ 循环程序的结构有两种形式 DO WHILE 结构形式: 当满足条件时,循环 DO UNTIL 结构形式: 循环,直到不满足条件 ┌───────┐ ┌───────┐ │循环初始状态 │ │循环初始状态 │ └───┬───┘ └───┬───┘ ├──────────┐ ├──────────┐ ↓ │ ↓ │ ┌───┴───┐Y │ ┌───┴───┐ │ │循环控制条件 ├─┐ │ │ 循环体 │ │ └───┬───┘ ↓ │ └───┬───┘ │ N↓ ┌───┴───┐│ ↓ │ │ │ 循环体 ││ ┌───┴───┐ Y │ │ └───┬───┘│ │循环控制条件 ├→─────┘ │ ↓ │ └───┬───┘ │ └────┘ ↓N DO WHILE 结构 DO UNTIL 结构 ⑵ 循环程序的组成 ① 设置循环的初始状态:• 如设置循环次数的计数器,以及为循环正常工作而建立的 初始状态。 ② 循环体:• 这是循环的主体部分,包括两个部分,一个是循环的工作部分,另一个 的修改部分,即循环中某些参数的修改如地址的增加或减少等。 循环体中可以包含循环,即循环可以嵌套。 ③ 循环的控制部分:• 在以上的指令中,LOOP/LOOPZ/LOOPE/LOOPNZ/LOOPNE即 为循环的控制部分;用分支结构实现时,则较为复杂一些。 返回
SF
JE/JZ
JNE/JNZ JS JNS
ZF=1
ZF=0 SF=1 SF=0
相等/或等于0
不相等/或不等于0 是负数 是正数
OF
PF
JO
JNO JP/JPE JNP/JPO
OF=1
OF=0 PF=1 PF=0
Байду номын сангаас
有溢出
无溢出 有偶数个1 有奇数个1
返回
JCXZ指令
格式:
– JCXZ < 目标>
第五章 分支与循环程序设计
5.1 概述 5.2 分支程序设计 5.3 循环程序设计 5.4 串程序设计
返回
5.1 概述
我们在第二章讲述了Intel 8086/8088 CPU把存储器分成若干段,每个段是一个可独立 寻址的逻辑单位。段是宏汇编语言程序设计的基础。一个段就是若干指令和数据的 集合。用定义段的伪指令SEGMENT/ENDS构造段,一个程序有几个段可根据需要设 置。通常按用途来划分。如存储数据的段,作堆栈用的段,存放程序的段等等。在 代码段中,与其它高级语言程序一样,无论程序是复杂或简单,程序的基本结构形 式是四种:
–
条件转移指令可分为四类:
1) 2)
3)
4)
无符号数条件转移指令 带符号数条件转移指令 简单条件转移指令 JCXZ指令