第五章 分支与循环程序设计
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指令