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

58
1 第第第 第第第第第第第第第 §5.1 第第第第第第第 §5.2 第第第第第第 §5.3 第第第第第第

Upload: ama

Post on 03-Feb-2016

96 views

Category:

Documents


0 download

DESCRIPTION

第五章 循环与分支程序设计. §5.1 循环与转移指令 §5.2 循环程序设计 §5.3 分支程序设计. §5.1 循环与转移指令. 一、循环控制指令 二、转移指令. 控制转移类指令通过改变 IP( 和 CS) 值,实现程序执行顺序的改变. 一、循环控制指令. 8086指令系统的循环控制指令均为二字节指令 一字节为转移的相对位移量(8位带符号的二进制数) IP ← IP+ 相对位移量 EIP ← EIP+ 相对位移量 隐含使用 CX 作为循环计数器. 短转移. 程序中的某段需反复执行若干次时,用循环来实现. 一、循环控制指令. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第五章 循环与分支程序设计

1

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

§5.1 循环与转移指令 §5.2 循环程序设计 §5.3 分支程序设计

Page 2: 第五章 循环与分支程序设计

2

§5.1 循环与转移指令

一、循环控制指令二、转移指令

控制转移类指令通过改变 IP (和 CS )值,实现程序执行顺序的改变

Page 3: 第五章 循环与分支程序设计

3

一、循环控制指令 8086 指令系统的循环控制指令均为二字节指令

一字节为转移的相对位移量( 8 位带符号的二进制数) IP ← IP+ 相对位移量

EIP ← EIP+ 相对位移量 隐含使用 CX 作为循环计数器

程序中的某段需反复执行若干次时,用循环来实现

短转移

Page 4: 第五章 循环与分支程序设计

4

LOOP label

; CX←CX - 1 , CX≠0 ,循环到标号 label

一、循环控制指令

LOOPE/LOOPZ label

; CX←CX - 1 , CX≠0 且 ZF = 1 ,循环到标号 label

LOOPNE/NZ label

; CX←CX - 1 , CX≠0 且 ZF = 0 ,循环到标号 label

等于时循环

不等于时循环

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

5

一、循环控制指令(例)MOV CX,COUNT ;设置循环次数

MOV SI,OFFSET DATA_BYTE

XOR AX,AX ; BX 清 0 ,用于存放累加和

AGAIN: ADD AL,[SI]

ADC AH,0

INC SI

LOOP AGAIN ;计数器减 1 ,不为 0 继续循环

Page 6: 第五章 循环与分支程序设计

6

一、循环控制指令(例)MOV CX,COUNT ;设置循环次数

MOV SI,OFFSET STRING

XOR BX,BX ; BX 清 0 ,用于记录空格数

MOV AL,20H

AGAIN: CMP AL,[SI]

JNZ NEXT ; ZF=0 ,非空格,转移

INC BX ; ZF=1 ,是空格,个数加 1

NEXT: INC SI

LOOP AGAIN ;计数器减 1 ,不为 0 继续循环

Page 7: 第五章 循环与分支程序设计

7

二、转移指令

无条件转移指令 条件转移指令

Page 8: 第五章 循环与分支程序设计

8

无条件转移指令

JMP label

;程序转向 label 标号指定的地址

NEARFAR

只要执行无条件转移指令 JMP ,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令

JMP 指令分成 4 种类型:⑴ 段内转移、直接寻址⑵ 段内转移、间接寻址⑶ 段间转移、直接寻址⑷ 段间转移、间接寻址

目的地址与 JMP 属同一逻辑段,只修改 IP 值

从一个代码段转移到另一个代码段, CS和 IP 都会被修改

Page 9: 第五章 循环与分支程序设计

9

1. 无条件转移指令—目标地址的寻址方式

直接寻址方式 转移地址象立即数一样,直接在指令的机器代码中,就

是直接寻址方式 间接寻址方式

转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式

用标号表达

用寄存器或存储器操作数表达

Page 10: 第五章 循环与分支程序设计

10

1. 无条件转移指令—目标地址的范围:段内

段内转移——近转移( near ) 在当前代码段 64KB 范围内转移 ( ±3

2KB 范围) 不需要更改 CS 段基值,只要改变 IP 偏

移地址 段内转移——短转移( short )

转移范围可以用一个字节表达,在段内- 128 ~+ 127 范围的转移

代码

代码

Page 11: 第五章 循环与分支程序设计

11

1. 无条件转移指令—目标地址的范围:段间

段间转移——远转移( far ) 从当前代码段跳转到另一个代码段,可以

在 1MB 范围 需要更改 CS 段基值和 IP 偏移地址 目标地址必须用一个 32 位数表达,叫做

32 位远指针,它就是逻辑地址

代码

代码

实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移程序员可用操作符 short 、 near ptr 或 far ptr 强制

Page 12: 第五章 循环与分支程序设计

12

段内直接寻址转移

JMP label ; IP←IP+ 位移量位移量是紧接着 JMP 指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负

实际为相对寻址

JMP AGAIN ;转移到 AGAIN 处继续执行……AGAIN: DEC CX ;标号 AGAIN 的指令

……JMP OUTPUT ;转向 OUTPUT……

OUTPUT: MOV RESULT,AL ;标号 OUTPUT 的指令

Page 13: 第五章 循环与分支程序设计

13

段内间接寻址转移

JMP r16/m16 ; IP←r16/m16将一个 16 位寄存器或主存字单元内容送入 IP 寄存器,作为新的指令指针,但不修改 CS 寄存器的内容

JMP AX ; IP←AX

JMP WORD PTR [BX] ; IP←[BX]

Page 14: 第五章 循环与分支程序设计

14

段间直接寻址转移JMP far ptr label

; IP←label 的偏移地址; CS←label 的段基值

将标号所在段的段基值作为新的 CS 值,标号在该段内的偏移地址作为新的 IP 值;程序跳转到新的代码段执行

JMP FAR PTR OTHERSEG

;远转移到代码段 2 的 otherseg

Page 15: 第五章 循环与分支程序设计

15

段间间接寻址转移JMP far ptr mem

; IP←[mem] , CS←[mem+2]

用一个双字存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的两个字单元中的,低位字送 IP 寄存器,高位字送 CS 寄存器

MOV WORD PTR [BX],0

MOV WORD PTR [BX+2],1500H

JMP FAR PTR [BX] ;转移到 1500H:0

Page 16: 第五章 循环与分支程序设计

16

2. 条件转移指令

Jcc label

;条件满足,发生转移: IP←IP + 8 位位移量 ;条件不满足,顺序执行

指定的条件 cc 如果成立,程序转移到由标号 label 指定的目标地址去执行指令;条件不成立,则程序将顺序执行下一条指令

操作数 label 是采用短转移,称为相对寻址方式

Page 17: 第五章 循环与分支程序设计

17

2. 条件转移指令 Jcc 指令的操作数 label 是一个标号

一个 8 位位移量是相对于当前 IP 的,且距当前 IP 地址-128 ~+ 127 个单元的范围之内,属于段内短距离转移

Jcc 指令为 2 个字节,条件不满足时的顺序执行就是当前指令偏移指针 IP 加 2

Page 18: 第五章 循环与分支程序设计

18

2. 条件转移指令—指令的分类 Jcc 指令不影响标志,但要利用标志。

根据利用的标志位不同, 19 条指令分成 4 种情况:⑴ 判断单个标志位状态⑵ 比较无符号数高低⑶ 比较有符号数大小⑷ 判断计数器 CX 为 0

Page 19: 第五章 循环与分支程序设计

19

助记符 标志位 助记符 标志位

JC CF=1 JA/JNBE CF=0 且 ZF=0

JNC CF=0 JAE/JNB CF=0 或 ZF=1

JZ/JE ZF =1 JB/JNAE CF=1 且 ZF=0

JNZ/JNE ZF =0 JBE/JNA CF=1 或 ZF=1

JS SF =1 JG/JNLE SF=OF 且 ZF=0

JNS SF=0 JGE/JNL SF=OF 或 ZF=1

JP/JPE PF =1 JL/JNGE SF≠ OF 且 ZF=0

JNP/JPO PF =0 JLE/JNG SF≠ OF 或 ZF=1

JO OF =1 JCXZ CX=0

JNO OF =0

实际虽然指令只有 19 条,但却有 31 个助记符

采用多个助记符,只是为了方便记忆和使用

Page 20: 第五章 循环与分支程序设计

20

判断单个标志位状态这组指令单独判断 5 个状态标志之一

⑴JZ/JE 和 JNZ/JNE :利用零标志 ZF ,判断结果是否为零(或相等)

⑵JS 和 JNS :利用符号标志 SF ,判断结果是正是负

⑶JO 和 JNO :利用溢出标志 OF ,判断结果是否产生溢出

⑷JP/JPE 和 JNP/JPO :利用奇偶标志 PF ,判断结果中“ 1”的个数是偶是奇

⑸JC 和 JNC :利用进位标志 CF ,判断结果是否进位或借位

例 题例 题

例 题例 题

例 题例 题

例 题例 题

例 题 例 题

Page 21: 第五章 循环与分支程序设计

21

2. 条件转移指令— JZ/JNZ 指令REPZ CMPSB ;重复比较两个字符JNZ UNMAT ; ZF = 0 (不等),转移MOV AL,0 ;顺序执行(相等)JMP OUTPUT

UNMAT: MOV AL,0FFH OUTPUT: MOV RESULT,AL

REPZ CMPSB ;重复比较两个字符JZ MAT ; ZF = 1 (相等),转移MOV AL,0FFH ;顺序执行(不等)JMP OUTPUT

MAT: MOV AL,0 OUTPUT: MOV RESULT,AL

Page 22: 第五章 循环与分支程序设计

22

2. 条件转移指令— JS/JNS 指令 计算 |X - Y| (绝对值)。 X 和 Y 为存放于 X 单元和 Y 单

元的 16 位操作数,结果存入 RESULT 。

MOV AX,XSUB AX,YJNS NONNEGNEG AX

NONNEG: MOV RESULT,AX

Page 23: 第五章 循环与分支程序设计

23

2. 条件转移指令— JO/JNO 指令 计算 X - Y 。 X 和 Y 为存放于 X 单元和 Y 单元的 16 位操

作数,若溢出,则转移到 OVERFLOW 处理

MOV AX,XSUB AX,YJO OVERFLOW... ;无溢出,结果正确

OVERFLOW: ... ;有溢出处理

Page 24: 第五章 循环与分支程序设计

24

2. 条件转移指令— JP/JNP 指令 设字符的 ASCII 码在 AL 寄存器中。将字符加上奇校验位:

在字符 ASCII 码中为“ 1”的个数为奇数时令其最高位为“0”,否则令最高位为“ 1”

AND AL,7FH ;最高位置“ 0”,同时判断“ 1”的个数

JNP NEXT ;个数已为奇数,则转向 NEXT

OR AL,80H ;否则,最高位置“ 1”

NEXT: ...

Page 25: 第五章 循环与分支程序设计

25

2. 条件转移指令— JC/JNC 指令 记录 BX 中 1 的个数

XOR AL,AL ; AL = 0 , CF = 0

AGAIN: TEST BX,0FFFFH ;等价于 CMP BX,0

JZ NEXT

SHL BX,1

JNC AGAIN

INC AL

JMP AGAIN

NEXT: ... ; AL保存 1 的个数

Page 26: 第五章 循环与分支程序设计

26

2. 条件转移指令—无符号数的比较

无符号数的大小用高( Above )低( Below )表示利用 CF确定高低、利用 ZF 标志确定相等( Equal )两数的高低分成 4 种关系:

⑴ 高于(不低于等于): JA ( JNBE )

⑵ 高于等于(不低于): JAE ( JNB )

⑶ 低于(不高于等于): JB ( JNAE )

⑷ 低于等于(不高于): JBE ( JNA )

Page 27: 第五章 循环与分支程序设计

27

2. 条件转移指令—无符号数的比较(例)

CMP AX,BX ;比较 AX 和 BX

JAE NEXT ;若 AX≥BX ,转移

XCHG AX,BX ;若 AX < BX ,交换

NEXT: ...

结果: AX保存较大的无符号数

Page 28: 第五章 循环与分支程序设计

28

2. 条件转移指令—有符号数的比较

有符号数的大( Greater )小( Less )需要组合OF 、 SF 标志,并利用 ZF 标志确定相等( Equal )

两数的大小分成 4 种关系: ⑴ 小于(不大于等于): JL ( JNGE ) ⑵ 小于等于(不大于): JLE ( JNG ) ⑶ 大于(不小于等于): JG ( JNLE ) ⑷ 大于等于(不小于): JGE ( JNL )

Page 29: 第五章 循环与分支程序设计

29

2. 条件转移指令—有符号数的比较(例)

CMP AX,BX ;比较 AX 和 BX

JGE NEXT ;若 AX≥BX ,转移

XCHG AX,BX ;若 AX < BX ,交换

NEXT: ...

结果: AX保存较大的有符号数

Page 30: 第五章 循环与分支程序设计

30

2. 条件转移指令—计数器 CX 为 0 转移

JCXZ label

; CX = 0 ,发生转移: IP←IP + 8 位位移量 ; CX≠0 ,顺序执行

CX 寄存器通常在程序中用做计数器JCXZ 指令用来判断计数是否为 0

Page 31: 第五章 循环与分支程序设计

31

§5.2 循环程序设计

一、循环程序的结构形式二、循环程序设计三、多重循环程序设计

Page 32: 第五章 循环与分支程序设计

32

一、循环程序的结构形式

结束

初始化

循环的初始状态

循环体

循环的工作部分及修改部分

计数控制循环条件控制循环

修改部分

控制条件Y

N先循环,后判断

Page 33: 第五章 循环与分支程序设计

33

一、循环程序的结构形式

结束

初始化

循环的初始状态

循环体

循环的工作部分及修改部分

计数控制循环条件控制循环

修改部分

控制条件

Y

N

先判断,后循环

Page 34: 第五章 循环与分支程序设计

34

xor ax,ax ;被加数 ax 清 0mov cx,100

again: add ax,cx ;从 100,99,...,2,1倒序累加loop again

.model small

.stack 256

.datasum dw ?

.code

.startup

mov sum,ax ;将累加和送入指定单元

.exit 0end

二、循环程序设计(例)

Page 35: 第五章 循环与分支程序设计

35

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

开始

1 的个数计数器← 0

循环次数计数器 CX←16

Y 左移一次

CF=1

1 的个数计数器 +1

CX ←CX-1=0

COUNT ← 1 的个数计数器

结束

N

Y

N

Y

循环次数固定,完全由循环计数器控制

Page 36: 第五章 循环与分支程序设计

36

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

NEXT: LOOP REPEATEXIT0: MOV COUNT,DL

MOV AH,4CH INT 21H

CODE ENDS END START

例 5.2

Page 37: 第五章 循环与分支程序设计

37

开始

1 的个数计数器← 0

循环次数计数器 CX←16

Y 左移一次

CF=1

1 的个数计数器 +1

CX ←CX-1=0

COUNT ← 1 的个数计数器

结束

NY

N

Y

Y=0

N

Y

例 5.2

Page 38: 第五章 循环与分支程序设计

38

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

NEXT: LOOP REPEAT

EXIT0: MOV COUNT,DL

ADD DL,30H

MOV AH,2

INT 21H

MOV AH,4CH

INT 21H

CODE ENDS

END START

CMP AX,0

JZ EXIT0

例 5.2

JMP REPEAT

Page 39: 第五章 循环与分支程序设计

39

例 5.4 将正数 N 插入一个已升序排列的字数组的正确位置。该数组的首地址和末地址分别为 ARRAY_ HEAD 和 ARRAY_ END ,其中所有的数均为正数。

解法一: 从数组的尾部开始比较 N较大,则在比较对象后插入,结束循环

N较小,则把比较对象及其后元素后移一个字

循环结束的控制: 执行插入操作后结束循环

若 N比所有元素都小,扫描整个数组后仍无法结束循环,将 -1 加在数组前可解决该问题

23, 37, 49, 52

32

ENDHEAD

-1, 23, 37, 49, 5232,-1,

Page 40: 第五章 循环与分支程序设计

40

开始

(ARRAY_HEAD-2)←-1

初始化变址寄存器 SI

将 N放在 K的后面

K<=N

修改地址

K后移一个字单元

结束

Y

N

例 5.4

Page 41: 第五章 循环与分支程序设计

41

DATAREA SEGMENT

X DW ?

ARRAY_HEAD DW 3,5,15,23,37,49

ARRAY_END DW 105

N DW 32

DATAREA ENDS

PROGRAM SEGMENT

MAIN PROC FAR

ASSUME CS:PROGRAM,DS:DATAREA

START: PUSH DS

SUB AX,AX

PUSH AX

MOV AX,DATAREA

MOV DS,AX

MOV AX,N

MOV ARRAY_HEAD-2,-1

MOV SI,0

COMP:CMP ARRAY_END[SI],AX

JLE INSERT

MOV BX,ARRAY_END[SI]

MOV ARRAY_END[SI+2],BX

SUB SI,2

JMP COMP

INSERT:

MOV ARRAY_END[SI+2],AX

RET

MAIN ENDP

PROGRAM ENDS

END START

例 5.4

MOV BX,ARRAY_END[SI]

CMP BX,AX

JLE INSERT

Page 42: 第五章 循环与分支程序设计

42

例 5.4 将正数 N 插入一个已升序排列的字数组的正确位置。 该数组的首地址和末地址分别为 ARRAY_ HEAD 和ARRAY_ END ,其中所有的数均为正数。

解法二: 从数组的头部开始比较 N较小,则在比较对象前插入,结束循环

N较大,则把比较对象及其前元素前移一个字

循环结束的控制: 可扫描整个数组,循环次数为数组元素个数执行插入操作后结束循环

若 N比所有元素都小,形成新的头;若 N比所有元素都大,则被置于尾部

Page 43: 第五章 循环与分支程序设计

43

DSEG SEGMENT PARA 'DATA'

DW ?

ARRAY_HEAD DW 3,5,13H,23H,37H

DW 49H,52H,65H,78H,99H,105H

COUNT EQU ( $-ARRAY_HEAD ) /2

N DW 32H

DSEG ENDS

CSEG SEGMENT PARA 'CODE'

ASSUME CS:CSEG

ASSUME DS:DSEG,SS:SSEG

MAIN PROC FAR

;MAKE NECCESSARY

INITALIZALITION

MOV AX,DSEG

MOV DS,AX

MOV ES,AX

MOV AX,N

MOV SI,0

MOV CX,COUNT

REPEAT: MOV BX,ARRAY_HEAD[SI]

CMP BX,AX

JAE INSERT ;N 较小,则转插入操作

MOV ARRAY_HEAD[SI-2],BX

; 数组元素前移 1 字单元

INC SI

INC SI

LOOP REPEAT

INSERT: MOV ARRAY_HEAD[SI-2],AX

; 将 N加入到数组中

MOV AX,4C00H

INT 21H

MAIN ENDP

CSEG ENDS

END MAIN ;SET ENTRY POINT

Page 44: 第五章 循环与分支程序设计

44

例 5.5 设有数组 X 和 Y ,每个数组都有 10个元素,完成以下计算:

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

结果存入数组 Z 。

比例尺: 0000000011011100B

Page 45: 第五章 循环与分支程序设计

45

DATA SEGMENT

X DW 11,33,10,60,4,7,19,80,45,23

Y DW 44,5,2,90,78,32,12,10,100,98

Z DW 10H DUP(?)

FLAG DW 0000000011011100B

DATA ENDS

STK SEGMENT STACK

DW 20H DUP(0)

STK ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STK

START:

MOV AX,DATA

MOV DS,AX

MOV BX,0

MOV CX,10

MOV DX,FLAG

NEXT: MOV AX,X[BX]

SHR DX ,1

JC SUBTRACT

ADD AX,Y[BX]

JMP RESULT

SUBTRACT :

SUB AX,Y[BX]

RESULT :

MOV Z[BX],AX

ADD BX,2

LOOP NEXT

MOV AH,4CH

INT 21H

CODE ENDS

END START

Page 46: 第五章 循环与分支程序设计

46

三、多重循环程序设计 例 5.7 有一个首地址为 A 的 N字数组,请编制程序

使该数组中的数按照从大到小的次序整序

冒泡法从第一个元素开始,依次对相邻的两个元素进行比较,使前一个元素不小于后一个元素;将所有元素比较完之后,最小的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次小的元素排在后面;如此重复,直至完成就实现元素从大到小的排序

这需要一个双重循环程序结构

Page 47: 第五章 循环与分支程序设计

47

冒泡法的排序

序号 数

比 较 遍 数

1 2 3 4

1 32

2 15

3 16

4 8

5 85

32

16

15

85

8

32

16

85

15

8

32

85

16

15

8

85

32

16

15

8

Page 48: 第五章 循环与分支程序设计

48

CSEG SEGMENT PARA ‘CODE’ASSUME CS:CSEG, DS:DSEG,SS:SSEG

MAIN PROC FAR ;MAKE NECCESSARY INITALIZALITIONPUSH DSXOR AX,AXPUSH AXMOV AX,DSEGMOV DS,AXMOV ES,AXMOV CX,NDEC CX

LOOP1: MOV DI,CX ; 保存计数器MOV BX,0 ; 数组地址指针清零

LOOP2: MOV AX,A[BX]CMP AX,A[BX+2]JGE COTINUEXCHG A[BX+2],AX ; 交换MOV A[BX],AX

COTINUE:ADD BX,2 ; 修改数组指针LOOP LOOP2MOV CX,DI ; 恢复循环计数器LOOP LOOP1RET

MAIN ENDPCSEG ENDS

END MAIN ;SET ENTRY POINT

Page 49: 第五章 循环与分支程序设计

49

CSEG SEGMENT PARA ‘CODE’ASSUME CS:CSEG, DS:DSEG,SS:SSEG

MAIN PROC FAR ;MAKE NECCESSARY INITALIZALITIONPUSH DSXOR AX,AXPUSH AXMOV AX,DSEGMOV DS,AXMOV ES,AXMOV CX,NDEC CX

LOOP1: MOV DI,CX ; 保存计数器MOV BX,0 ;数组地址指针清零MOV DL,0

LOOP2: MOV AX,A[BX]CMP AX,A[BX+2]JGE COTINUEXCHG A[BX+2],AX ; 交换MOV A[BX],AXINC DL ; 交换次数计数器 +1

COTINUE:ADD BX,2 ;修改数组指针LOOP LOOP2CMP DL,0JZ EXIT0 ; 数组已整序,则退出MOV CX,DI ; 恢复循环计数器LOOP LOOP1

EXIT0: RET MAIN ENDP CSEG ENDS

END MAIN ;SET ENTRY POINT

Page 50: 第五章 循环与分支程序设计

50

§5.3 分支程序设计

一、分支程序的结构形式二、分支程序的设计三、跳转表

Page 51: 第五章 循环与分支程序设计

51

一、分支程序的结构形式

AH=0 fuction0N

AH=1

AH=2

fuction1

fuction2

N

N

Y

Y

Y

( C )多分支结构

Page 52: 第五章 循环与分支程序设计

52

分支程序的设计方法 例 5.9 在附加段中,有一个按从小到大顺序排列的无符号数

数组,其首地址存放在 DI 寄存器中,数组中的第一个单元存放着数组长度。在 AX 中有一无符号数,要求在数组中查找该数,如找到则使 CF=0 ,并在 SI 中给出该元素的偏移地址;如未找到,则使 CF=1 。

Page 53: 第五章 循环与分支程序设计

53

Page 54: 第五章 循环与分支程序设计

54

跳跃表法 例 5.10 试根据 AL 寄存器中哪一位为 1 (从低位到

高位)把程序转移到 8 个不同的程序分支去。 跳转目标的地址在数据段中( 5-10-1.asm) 跳转目标的地址在代码段中( 5-10-2.asm)

Page 55: 第五章 循环与分支程序设计

55

SSEG SEGMENT PARA STACK 'STACK'DW 100H DUP(0)

SSEG ENDSDSEG SEGMENT PARA 'DATA'TAB DW ROUTINE1 ;程序段 1 在代码段的偏移量

DW ROUTINE2DW ROUTINE3DW ROUTINE4DW ROUTINE5DW ROUTINE6DW ROUTINE7DW ROUTINE8

MESS DB 'THIS IS ROUTINE 'NUMBERDB 8

DB 0AH,0DH,'$'DSEG ENDSCSEG SEGMENT PARA 'CODE'

ASSUME CS:CSEG, DS:DSEG,SS:SSEGMAIN PROC FAR

MOV AX,DSEG ;MAKE NECCESSARY INITALIZALITION

MOV DS,AXMOV ES,AX

MOV AL, NUMBERCMP AL,0JE CONTINUE_MAIN_LINE;AL 值为 0 则继续运行主程序段LEA BX,TAB

LOP1: SHR AL,1JNC NOT_YETJMP WORD PTR [BX]

NOT_YET:ADD BX,TYPE TABJMP LOP1

CONTINUE_MAIN_LINE:MOV AH,4CHINT 21H

Page 56: 第五章 循环与分支程序设计

56

ROUTINE1:MOV NUMBER, 31HJMP EXIT

ROUTINE2:MOV NUMBER, 32HJMP EXIT

ROUTINE3:MOV NUMBER, 33HJMP EXIT

ROUTINE4:MOV NUMBER, 34HJMP EXIT

ROUTINE5:MOV NUMBER, 35HJMP EXIT

ROUTINE6:MOV NUMBER, 36HJMP EXIT

ROUTINE7:MOV NUMBER, 37HJMP EXIT

ROUTINE8:MOV NUMBER, 38HJMP EXIT

EXIT: MOV DX,OFFSET MESS

MOV AH,9

INT 21H

JMP CONTINUE_MAIN_LINE

;MOV AH,0AH

;INT 21H

;RETURN DOS

MOV AX,4C00H

INT 21H

MAIN ENDP

CSEG ENDS

END MAIN ;SET ENTRY POINT

Page 57: 第五章 循环与分支程序设计

57

SSEG SEGMENT PARA STACK 'STACK'DW 100H DUP(0)

SSEG ENDS

DSEG SEGMENT PARA 'DATA'MESG1: DB 'PLEASE INPUT THE NUMBER:$'MESS DB 0AH,0DH,'THIS IS ROUTINE 'NUMBER DB ?

DB 0AH,0DH,'$'DSEG ENDS

CSEG SEGMENT PARA 'CODE'ASSUME CS:CSEG, DS:DSEG,SS:SSEG

MAIN PROC FAR;MAKE NECCESSARY INITALIZALITIONMOV AX,DSEGMOV DS,AXMOV ES,AX

MOV DX,OFFSET MESG1MOV AH,9INT 21HMOV AH,1 ; 从键盘获得 AL 值INT 21HAND AL,0FHDEC AL ; 计算表地址 (号 -1)*3MOV BL,ALSHL BL,1ADD BL,ALMOV BH,0ADD BX,OFFSET TABJMP BX

TAB: JMP ROUTINE1JMP ROUTINE2JMP ROUTINE3JMP ROUTINE4JMP ROUTINE5JMP ROUTINE6JMP ROUTINE7JMP ROUTINE8JMP ROUTINE9

Page 58: 第五章 循环与分支程序设计

58

ROUTINE1:MOV NUMBER, 31HJMP EXIT

ROUTINE2:MOV NUMBER, 32HJMP EXIT

ROUTINE3:MOV NUMBER, 33HJMP EXIT

ROUTINE4:MOV NUMBER, 34HJMP EXIT

ROUTINE5:MOV NUMBER, 35HJMP EXIT

ROUTINE6:MOV NUMBER, 36HJMP EXIT

ROUTINE7:MOV NUMBER, 37HJMP EXIT

ROUTINE8:MOV NUMBER, 38HJMP EXIT

ROUTINE9:MOV NUMBER, 39HJMP EXIT

EXIT: MOV DX,OFFSET MESSMOV AH,9INT 21H;MOV AH,0AH;INT 21H

;RETURN DOSMOV AX,4C00HINT 21H

MAIN ENDPCSEG ENDS

END MAIN ;SET ENTRY POINT