控制转移指令

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

控制转移指令
通常,程序中的指令都是顺序地逐条进行的,在8086中,指令的执行顺序由CS和IP 决出,每取出一条指令,指令指针IP自动进行调整,一条指令执行完成后,就从该指令之后的下一个存储单元中取出一条指令来执行。

利用控制转移指令可以改变CS和IP的值,从而改变指令的执行顺序。

为满足程序转移的不同要求,8086提供了无条件转移和过程调用、条件转移、循环控制以及中断指令等几类指令。

无条件转移指令和过程调用指令:JMP—无条件转移、CALL—过程调用、RET—过程返回条件转移:JZ\JE等十条指令—直接标志转移、JA\JNBE等8条指令—间接标志转移
条件循环控制:LOOP—CX≠0则循环、LOOPE和LOOPZ—CX≠0和ZF=1则循环、LOOPNE 和LOOPNE—CX≠0和ZF=0则循环、JCXZ—CX=0则循环
中断:INT—中断、INTO—溢出中断、IRET—中断返回
1、无条件转移和过程调用指令
1)JMP 无条件转移指令
指令格式:JMP 目的
指令功能:使程序无条件转移到指令中指定的目的地址去执行。

这类指令又分为两种类型:
第一种类型:段内转移或近(NEAR)转移,转移指令目的地址和JMP指令在同一代码段中,转移时仅改变IP寄存器的内容,段地址CS的值不变。

第二种类型:段间转移,又被称之为远(FAR)转移,转移指令的目的地址和JMP指令不在同一代码段中,发生转移时,CS和IP 的值都要改变也就是说,程序要转移到另一个代码段中去执行。

不论是段内还是段间转移,就转移地址提供的方式而言,又可分为两种方式:
第一种方式:直接转移,在指令码中直接给出转移的目的地址,目的操作数用一个标号来表示,它又分为段内直接转移和段间直接转移。

第二种方式:间接转移,目的地址包含在某个16位寄存器或存储单元中,CPU必须根据寄存器或存储器的寻址方式,间接地求出转移地址。

同样,这类转移也可分为段内间接转移和段间间接转移。

所以无条件转移指令可分为段内直接转移、段内间接转移、段间直接转移、段间间接转移这四种不同类型和方式。

段内直接转移指令
指令格式:JMP SHORT 标号
JMP NEAR PTR 标号(或JMP 标号)
这是一种段内相对转移指令,目的操作数均用标号表示,程序转向的有效地址等于当前IP 寄存器内容加上8位或者16位位移量(DISP).如果位移量位是16位,那么表示近转移,说
明目的地址与当前的IP的距离在-32768~32767个字节之间。

如果转移的范围在-128到127之内,则称为短转移,指令中只需要用8位位移量,它是近转移的一个特例。

在机器语言中,8位或16位位移量用带符号数表示,正的位移量表示向高地址方向转移,负的位移量表示向低地址方向转移,负位移量必须用补码表示。

段内近—短转移指令的机器码及其操作功能如下如所示。

段内近转移指令
段内短转移指令
其中,第一个字节为操作码,后面的字节是位移量,注意,由于IP为16位长,当它与8位的位移量相加时,实际上使用符号扩展法将8位位移量扩展成16位数后才相加的。

在汇编语言语句中,目的操作数用符号地址也就是标号表示。

对于位移量为16位的近转移,则在标号前加NEAR PTR,该说明符可以不写。

对于位移量为8位短转移,则需在标号面前说明符SHORT。


JMP SHORT PROG_S ;段内短转移
JMP NEAR PTR PROG_N;段内近转移(或写成JMP PROG_N)
下面是一个含有无条件转移指令的简单程序的列表文件,它是由汇编语言源程序翻译后产生的。

即:
;行号偏移量机器码程序
1 0000 CODE SEGMENT
2 ASSUME CS:CODE
3 0000 0405 PROG_S: ADD AL, 05H
4 0002 90 NOP
5 0003 EBFB JMP SHORT PROG_S
6 0005 90 NOP
7 0006 CODE ENDS
8 END\
程序共8行,最左边一列是程序的行号。

整个程序只包含一个代码段,段名为CODE,它以CODE SEGMENT开头语句开头,以CODE ENDS语句结束。

整个程序以END结束。

行号后面的一列数字表示每条指令的首字节距离代码段基地址的偏移量(offset),偏移量后面的数字代表每条指令的机器码。

标号为PROG_S的加法指令的偏移量为0,该指令站两个字节,所以下一条空操作指令(NOP)首字节的偏移量为2,NOP 指令除占用一个字节空间和用去3个时钟周期外,不作任何事情。

JMP SHORT PROG_S指令的首字节偏移量为3,当8086取出这条两字节的JMP指令后,首先增量地址指针,使IP=5,指向CPU原打算执行的第二条NOP指令。

然而,JMP指令将改变程序执行的次序,它要转向目的地址PROG_S,而PROG_S的偏移量为0,所以JMP 指令中的位移量DISP位:
DISP=目的地址偏移量-IP当前值=0-5=-5,其补码为FBH,经符号扩展后成FFFBH,这样,
JMP指令将把IP修改为:IP=IP+DISP=0005+FFFB=0
于是程序就转到偏移量为0的位置,即标号PROG_S处执行
对于段内近转移指令,除了位移量可以是16位,和段内段转移指令一样,也采用相对寻址,在汇编格式中也是用符号地址(标号)。

不过段内近转移指令占3个字节,由于计算位移量时,总是从紧跟JMP指令之后的下条地址开始计算,所以取出这类JMP指令之后,IP要先加3,再与目标地址量相加。

对于位移量是16位的JMP指令,它可以转到段内任何地址去执行指令。

段内间接转移指令
这类指令转向的16位有效地址存放在一个16位寄存器或字存储单元中
用寄存器间接寻址的段内转移指令,要转向的有效地址存放在寄存器中,执行的操作是寄存器的内容送到IP中

JMP BX
若该指令执行前BX=4500H,则指令执行时,将当前IP修改成4500H,程序转到段内偏移地址为4500H处执行
对于用存储器间接寻址的段内转移指令,要转向的有效地址存放在存储单元中,所以JMP 指令先要计算存储单元的物理地址,再从该地址处取一个字送到IP 即,字存储单元的内容送到IP

JMP WORD PTR 5[BX]
设指令执行前,DS=2000H,BX=100H,(20105H)=4F0H,
则:指令执行后,IP=(20000H+100H+5H)=(20105H)=4F0H,即转到代码段内偏移地址为4F0H 处执行。

这种指令的目的操作数前加WORD PTR,表示进行的是字操作。

段间直接(远)转移指令
指令中用远标号直接给出了转向的段地址和偏移量,用指令中的段地址取代CS的内容,用指令中指定的段地址取代CS寄存器的内容,就可以是程序从一个代码段转到另一个代码段去执行。

例JMP FAR PTR PROG_F
指令中用说明符FAR PTR 说明PROG_F是远标号,指令执行的操作为,将远标号的段内偏移量送至IP中,将远标号所在段的段地址送到CS中。

设标号PROG_F所在段的基地址为=3500H,偏移地址=080AH,则,指令执行后,
IP=080AH,CS=3500,程序转到3500:080A处执行。

段间间接转移指令
将目的地址的段地址和偏移量事先放在存储器中的4个连续的地址单元中,其中,前两个字节为偏移量,后两个字节为段地址,转移指令中给出存放目标地址的存储单元的首字节地址值。

这种指令的目的操作数前要加说明符DWORD PTR ,表示转向地址需取双字
JMP DWORD PTR[SI+0125H]
设指令执行前,CS=1200H,IP=05H,DS=2500H,SI=1300H,内存单元(26425H)=4500H,(26427H)=32F0H.而指令中的位移量DISP=0125H,其中高位部分为DISP_H=01H,低位部分DISP_L=25H
该指令占4个字节,第一个字节是操作码,编码为FFH,第2个字节的编码为:MOD 101 R\M,因该指令属于[SI]+D16这种形式,查表的MOD=10,R/M=100,第3和4个字节分别为
位移量的低字节和高字节
于是,该指令的编码格式为:
指令要转向的地址放在内存中,内存单元的物理地址为DS:(SI+DISP),即:
目标操作地址=DS*16+SI+DISP
=25000+1300+0125H
=26425H
从该单元中取出JMP指令的转移地址,并赋予IP和CS,即IP=4500H,CS=32F0H,所以程序转到32F0:4500H处执行。

这条指令的执行过程如下图所示。

2)过程调用和返回指令
在编写程序时,把某些能完成特定功能而又经常要用到程序段,编写成独立的模块,并把它称为过程(Procedure),习惯上也称作子程序(Subroutine),然后在程序中用CALL
语句调用这些过程,调用过程的程序称为主程序。

过程以PROC语句开头,用语句ENDP结束。

在ENDP 之前要放一条过程返回语句RET,它与CALL指令相呼应,使过程执行完毕后,能正确返回主程序中紧跟在
CALL指令后面的那条指令继续执行。

若在过程运行中又调用一个过程,称为过程嵌套。

在模块化程序设计中,过程调用已成为一个不可或缺的手段,它使程序结构清晰,可读性强,同时也能节省内存。

过程调用和返回指令的格式如下:
CALL 过程名
RET
过程调用有近调用和远调用两种类型。

近过程调用指调用指令CALL和被调用的过程在同一代码段中,远过程调用则是指两者不在同一代码段中。

CALL指令执行分两步执行:
第一步是将返回地址,也就是CALL指令下面那条指令的地址堆入堆栈。

对于近调用来说,执行的操作是,SP-2赋给SP,IP入栈。

对于远调用来说,执行的操作是:SP-2赋给SP,SP 再-2赋给SP,IP入栈
第二步是转到子程序的入口地址去执行相应的子程序,入口地址由CALL指令目的操作数提供,寻找入口地址的方法与JMP指令的寻址方法基本上是一样的,有4种方式:段内直接调用、段内间接调用、段间直接调用、段间间接调用,但没有段内段调用指令。

执行过程中的RET指令后,从栈中弹出返回地址,使程序返回主程序继续执行。

这里也分为两种情况:
如果从近过程返回,则从栈中弹出一个字赋给IP,并且使SP+2赋给SP
如果从远过程返回,则从栈中弹出一个字赋给IP,并且使SP+2赋给SP,再从栈中弹出一个字CS,并使SP+2赋给SP

段内直接调用与返回
CALL PROG_N ;PROG_N是一个近标号
该指令含3个字节,编码格式为:E8 DISP_L DISP_H
设调用前:CS=2000H,IP=1050H,SS=5000H,SP=0100H,PROG_N与CALL指令之间的字节数距离为1234H(DISP=1234H),则执行CALL指令的过程:
SP-2的值赋给SP,即新的SP=0100-2=00FEH
返回地址的IP 入栈
由于存放CALL指令的内存首地址为CS:IP=2000:1050H,该指令占3个字节,所以返回地址为2000:1053H,即IP=1053H.于是1053H被推入堆栈
根据当前IP值和位移量DISP计算出新的IP值,作为子程序的入口地址,即:
IP=IP+DISP=1053H+1234H=2287H
程序转到本代码中偏移地址为2287H处执行。

指令CALL PROG_N的指令执行过程如下图
RET 指令的寻址方式与CALL 指令的寻址方式一致,在本例中是段内直接调用,所以过程PROG_N 中的RET 指令将执行如下操作: SP 和SP+1的单元内容为IP ,SP+2即新的SP 这样,控制就转回到主程序中CALL PROG_N 指令下面的那条指令,也就是2000:1053处继续执行程序。

这时堆栈指针为SP=1000H RET 的指令执行过程如下图
段内间接调用与返回 例
CALL BX
CALL WORD PTR [BX+SI] 它们的执行分三步进行:
SP SP-2 IP 入栈 IP EA
这类指令与段内直接调用的前两步操作过程完全一样,但第三步求子程序入口地址的方法不一样,它要根据从目的操作数计算出来的有效地址EA 来转移。

设:
DS=1000H,BX=200H,SI=300H,(10500H)=3210H
第一条指令的操作数是BX 寄存器,它包含了过程的16位有效地址EA=0200H,执行调用指令后,
IP 0200H ,也就是转到段内偏移地址0200H 处执行程序
第二条指令的子程序入口地址在内存单元中,其值为: (16*DS+BX+SI)=(10000H+0200H+0300H)=(10500H)=3210H 即EA=3210H,调用指令执行后IP 3210H ,也就是转到段内偏移地址为3210处执行程序。

对应的RET 指令执行后的操作与段内直接过程的返回指令相同 段间直接调用 例
CALL FAR PTR PROG_F ;PROG_F 是一个远标号 CS=3000H,IP=0500H
存放CALL 指令的内存首地址为1000:205AH,由于该指令长度为5个字节,所以返回地址为1000:205FH
执行远调用的CALL 指令的过程如图所示:
段间调用指令执行过程 执行远调用CALL 指令的过程:
SP SP-2 即SP=0050H-2=004EH
CS入栈即CS=1000H入栈
SP SP-2 即SP 004C
IP入栈即IP=205F入栈
转子程序入口将PROG_F的段地址和偏移地址送CS和IP
即CS 3000H,IP 0500H
执行子程序
过程PROG_F中的RET指令的寻址方式也是段间直接调用,返回时执行的操作是:
SP SP+2 即SP 004C+2=004EH
IP 栈中内容即IP 205FH
SP SP+2 SP 004EH+2=0050H
CS 栈中内容CS 1000H
所以程序转返回地址CS:IP=1000H:205FH处执行
段间间接调用
这类操作数必须是存储单元,从该单元开始存放的双字表示过程的入口地址,其中前两个字节表示偏移量,后两个字节表示代码段基地址。

指令中的DWORD PTR 说明是对存储单元进行双字操作。

CALL DWORD PTR [BX]
设调用前DS=1000H,BX=200H,(10200H)=31F4H,(10202)=5200H.
执行指令前,先将返回地址的偏移量和段地址都堆入堆栈,再转向过程入口。

指令中操作数的物理地址=DS*16+BX=10200H,从该单元开始取得的双字就是过程的入口地址。

所以入口地址CS:IP分别为
IP (10200H) 即IP=31F4H
CS (10202) CS=5200H
8086还有一些带参数的返回指令,形式为
RET
常将n称为弹出值,它让CPU在弹出返回地址是,再从堆栈中弹出n个字节的数据。

也就是让SP再加上n。

n用表达式表示,其值可以是0000~FFFFH范围内的任何一个偶数。

例如,指令RET 8表示从堆栈中弹出地址后,再使SP的值加上8。

在RET指令上加弹出值可以让调用过程的主程序通过堆栈向过程传递参数。

这些参数必须在调用过程前堆入堆栈,过程在运行中可以通过堆栈指针找到他们。

当过程返回时,这些参数已没有用处,应该把它们从栈中弹出。

使用带弹出值得RET指令后,可以在过程返回主程序时,使SP自动增量,从而不需要用POP指令就能把这些参数从堆栈中弹出。

2、条件转移指令
定义:根据上一条指令执行后,CPU设置的状态标志作为判别测试条件来决定是否转移。

每一种条件转移指令都有它的测试条件,当条件成立,使控制程序转向指令中给出的目的地址,去执行那里的指令,否则,程序仍顺序执行
所有的条件均为段内短转移,也就是说,转移指令与目的地址必须在同一代码段中。

目的地址由当前IP值与指令中给出的8位相对位移量相加而成,它与转移指令之后的那条指令的距离,允许为-128~+127字节。

8位位移量是用符号扩展法扩展到16位才与IP相加。

条件转移指令通常用比较指令或算术逻辑指令之后,根据比较或运算结果,转向不同的目的地址。

在指令中,目的地址均用标号表示,因此指令的格式为:
条件操作符标号
1)直接标志转移指令
这类转移指令在指令助记符中直接给出状态的测试条件,它们以CF、ZF、SF、OF和PF等5个标志的10种状态为判断的条件,共形成10条指令。

有些指令有两种不同的助记符,如“结果为0”和“相等则转移”,都用ZF=1作为测试条件,可用助记符ZF或JE表示。

我们将这类情况JZ\JE,表示这两个助记符代表同样地指令。

求AL和BL寄存器中的两数之和,若有进位,则AH清1,否则AH清0.可用以下程序来实现:
ADD AL, BL ;两数相加
JC NEXT ;若有进位,转NEXT
MOV AH, 0 ;无进位,AH清0
JMP EXIT ;往下进行
NEXT: MOV AH, 1 ;有进位,AH置1
EXIT:……;程序继续进行
2)间接标志转移
这类指令的助记符中不直接给出标志状态位的测试条件,但仍以某一个标志的状态或或几个标志位的状态组合,若条件成立则转移,否则顺序往下进行。

间接转移指令共有8条。

每条指令都有两种不同的助记符
行比较,一定要用无符号数比较指令决定程序的走向;对带符号数比较后,则要用带符号数的比较测试指令。

使用时要严格加以区分,否则会得到错误的结果
在无符号比较测试指令中,指令助记符中的“A”是英文Above的缩写,表示“高于”之意,“B”是英文Below之意,表示“低于”之意

设AL=F0H, BL=35H,执行指令
CMP AL, BL
JAE NEXT
执行指令后,若AL中的无符号数大于或等于BL中的数,则转到符号为NEXT的指令去执行,否则执行下一条指令。

JAE\JNB是根据CF的标志是否为零来决定转移的,若CF=0,即无进位,则转移,这与直接转移指令中JNC功能完全一样。

同样,JB\JNAE与JC指令的功能完全相同
对于无符号数的进行比较转移指令比较容易理解,对于带符号数进行比较,情况比较复杂不能仅根据SF和OF标志来决定这两个数的大小,而要将它们综合起来考虑。

指令助记符中,“G”(Great than)表示大于,“L”表示小于(Less than)。

举例
设某个学生的英语成绩已存放在AL寄存器中,如果低于60分,那么打印F(FAIL);若高于或等于85分,则打印G(GOOD);当在60分和84分之间时,打印P(PASS).可用下面的程序实现要求的操作:
CMP AL, 60 ;与60分比较
JB FAIL ;<60,转FAIL
CMP AL, 85 ;>=60,与85分比较
JAE GOOD ;>=85,转GOOD
MOV AL, 'P' ;其它,将AL 'P'
JMP PRINT ;转打印程序
FAIL: MOV AL,'F' ;AL 'F'
JMP PRINT ;转打印程序
GOOD: MOV AL, 'G';AL 'G'
PRINT:……;打印存在AL中的字符

我们再来看一个温度控制的例子。

假设某温度控制系统中,从温度传感器中输入一个8位二进制的摄氏温度值。

当系统中的温度低于100摄氏度时,则打开加热器;当温度上升到100或100以上时,关闭加热器,进行下一步处理。

设温度传感器的端口号为320H,同时假设控制加热器的输出信号连到端口321H的最低有效,当将这一位置1时,加热器使打开,清0时则关闭加热器。

实现上述温度控制的程序为:
GET_TEMP:MOV DX, 320H
IN AL, DX ;读取温度值
CMP AL, 100H ;与100摄氏度相比较
JB HEAT_ON ;小于100摄氏度,加热
JMP HEAT_OFF;大于等于100摄氏度,停止加热
D位置1,加热
HEAT_ON:MOV AL, 01H ;
MOV DX, 321;加热器口地址
OUT DX, AL;打开加热器
JMP GET_TEMP ;继续检测温度
D位置0,停止加热
HEAT_OFF:MOV AL, 00;
MOV CX, 321H
OUT DX, AL ;关闭加热器
例在以首地址为TABLE的10个内存字节单元中存放了10个带符号数,要求统计其中正数、负数和零的个数,并将结果送到PLUS、NEGT和ZERO单元
程序如下:
TABLE DB 01H,80H,0F5H,32H,86H
DB 74H,49H,0AFH,25H,40H
PLUS DB 0 ;存正数的个数
ZEGT DB 0 ;存负数的个数
ZERO DB 0 ;存0的个数
MOV CX, 10 ;数据总数
MOV BX, 0 ;BX清0
AGAIN:CMP TABLE[BX], 0 ;取一个数与0比
JGE GRET_EQ ;>=0,转GRET_EQ
INC NEGT ;<0,负数个数加1
JMP NEXT ;往下执行
GRET_EQ:JG P_INC ;>0,转P_INC
INC ZERO ;=0,零个数加1
JMP NEXT ;往下执行
P_INC: INC PLUS ;正数个数加1
NEXT:INC BX ;数据地址指针加1
DEC CX;数据寄存器减1
JNZ AGAIN ;未完,继续统计
3、循环控制指令
循环控制指令是一组增强型的条件转移指令,用来控制一个程序段的重复执行,重复次数由CX寄存器中的内容决定。

这类指令的字节数均为2,第1个字节是操作码,第2个字节是8位位移量,转移目标都是短标号。

它们的操作过程与条件转移相似,转移地址等于当前IP 加上8位偏移量,8位偏移量与IP相加时,先按符号扩展法扩展到16位后再相加,循环指令中的偏移量都是负值。

循环控制指令均不影响任何标志,这类指令共有4条。

1)LOOP循环指令(loop)
指令格式:LOOP 短标号
指令功能:这条指令用于控制重复执行一系列指令。

指令执行前必须事先将重复次数,放在CX寄存器中,每执行一次LOOP指令,CX自动减1.如果减1后CX 0,则转移到指令中所给的标号处继续循环;若自动减1后CX=0.则结束循环,转去执行LOOP指令之后的那条指令。

一条LOOP指令相当于执行以下两条指令的功能:
DEC CX\
JNZ 标号

设商店里有8种商品,它们的价格分别为83元,76元,65元,84元,71元,49元,62元,58元,现将每种商品提价7元,编程计算每种商品提价后的价格。

这是一个简单的加法问题,我们将商品的原价按BCD码的形式,依次存放在标号为OLD 开始的8个存储单元中,而新的价格存放进NEW开始的8个单元中,然后用LOOP指令来实现8次循环。


OLD DB, 83H,76H,65H,84H
DB 71H,49H,62H,58H
NEW DB 8 DUP(?)
MOV CX, 08H ;共8种商品
MOV BX, 00H;BX做指针,初值为0
NEXT:MOV AL, OLD[BX];读入一个商品的原价
ADD AL, 7;加上提价因子
DAA;调整为十进制数
MOV NEW[BX],AL;存放结果
INC BX;地址指针加1
LOOP NEXT;已加完8次
从LOOP指令到它所指向的标号之间的指令也称为循环体,在循环体内的所有指令将被重复执行,执行的次数由CX寄存器中的初值决定。

循环体中也可以含一条指令,即LOOP
指令自身,这样的程序常用来延时。

例如:
MOV CX, 10
DELAY:LOOP DELAY

这时一个用循环和跳转指令来控制PC机上的扬声器的发声程序。

在PC机中,61H端口的D1和D0位的扬声器接口电路上,在D0=0的情况下:D1=1时,扬声器被接通,D1=0时,则断开,通过控制这一位的值,就能产生一个由1和0的二进制序列,使扬声器发声。

61H 端口的其它位用来控制PC机的内部开关状态、奇偶校验和键盘状态等。

控制扬声器发声的程序如下:
IN AL, 61H ;从61H端口读取数据到AL
AND AL, 0FCH ;保护D7~D2位,D0位清零
MORE:XOR AL, 02 ;触发D1位,使之在0和1之间变化
OUT 61H,AL ;控制扬声器开关的通断
MOV CX,260 ;CX=循环次数
DELAY:LOOP DELAY ;循环延时
JMP MORE ;再次触发
本例中,LOOP中的指令重复执行260遍,起延时作用,是开关的接通和断开维持一定的时间,这是非常必要的,否则开关的动作太快,发出的声音的频率太高,使人耳听不出来。

2)LOOPE\LOOPZ相等或结果为零时循环(loop if equal or zero)
指令格式:LOOPE 标号
或LOOPZ 标号
指令功能:LOOPE是相等时循环,LOOPZ是结果为0时循环,这是两条指令功能相同,而具有不同的助记符,它们用于控制重复执行一组指令。

指令执行前,先将重复次数送到CX 中,每执行一条指令,CX自动减1,若减1后CX不等于零和ZF=1,则转到指令所指定的标号处重复执行;若CX=0或ZF=0,便退出循环,执行LOOPZ\LOOPE之后的那一条指令。


设有一个由50个字节组成的数组放在ARRAY开始的内存单元,现要对该数组中的元素进行测试,若元素为0,而且不是最后一个元素,便继续进行下一个元素的测试,直到找到第一个非零元素为止
程序如下:
ARRAY DB **,**,……;含50个元素的数组
MOV BX, OFFSET ARRAY;BX指向数组开始的单元
DEC BX;指针减1
MOV CX, 50;CX=元素的个数
NEXT:INC BX;指向数组的下个元素
CMP [BX], 00H;数组元素与0元素比较
LOOPE NEXT;若元素为0和CX不等于0.循环,否则,结束查找
3)LOOPNE\LOOPNZ不相等或结果不为0循环
格式:LOOPNE 标号
LOOPNZ 标号
指令功能:LOOPNE是不相等时循环,而LOOPNZ是结果不为零循环,它们也是一对功能相同但是形式不一样的指令。

指令执行前,应将重复此时送入CX,每执行一次,CX自动减1,若减1后CX不等于零和ZF=0,则转移到标号所指定地方重复执行;若CX=0和ZF=1,则退出循环,顺序执行下一条指令
设一个由17个字符组成的字节组成的字符串存放在STRING开始的内存中,现要查找该字符串中是否有空字符。

若没有找到空格符和尚未查完,则继续查找,直到找到第一个空格符或查完了才退出循环
下面是实现上述操作的程序:
STRING DB 'Personal Computer' ;字符串
MOV BX, OFFSET STRING ;
DEC BX ;BX指向字符串的开始
MOV CX, 17 ;BX-1
NEXT: INC BX ;CX=字符串长度
CMP [BX], 20H ;字符串元素与空格比较
LOOPNE NEXT ;若不是空格和CX不等于0,循环
4)JCXZ若CX=0则转
指令格式:JCXZ 标号
指令功能:若CX寄存器为0,则转移到指令中标号所指定的地址处,否则将往下顺序执行,它不对CX寄存器进行自动减1的操作
这条指令用在循环程序的开始处。

为了使程序跳过循环,只要事先把CX清0
4、中断指令
1)中断的概念
中断是指计算机在执行正常的程序过程中,由于某些事件的发生,需要暂时中止当前程序的运行,转到中断服务程序中去为临时发生的事件服务,中断执行完成后,又返回到正常程序继续运行,这个过程称为中断
引起中断的原因有两个:
第一种是外部中断,也成为硬件中断,它们从8086的不可屏蔽引脚NMI或可屏蔽中断引脚INTR上引入.。

NMI引脚上的中断请求,情况比较紧急,如存储器校验错、电源掉电等发生时,CPU必须马上响应。

从INTR脚上来的请求信号,CPU可以立即响应,也可以暂时不响应。

如果CPU内部的标志寄存器中的IF置1,则允许响应这类中断;若IF=0,则不予响应。

在PC机中,外部的可屏蔽中断是通过8259A可编程中断控制器连到CPU上的,主要用来管理I\O设备与CPU之间的通信
第二种是内部中断,这种中断是为解决CPU在运行过程中的发生的意外情况,如运算出错和溢出出错等,或者是为便于对程序进行调试而设置的。

此外,也可以在程序中安排一条中断指令INT n,利用这条指令直接产生8086的内部中断,指令中的n为中断类型号。

CPU每响应一次中断,首先不但要向过程调用一样,把CS和IP的值也即断点送到堆栈段保护起来,而且还要将标志寄存器的值入栈保护起来,以便在中断服务程序执行完后,能正。

相关文档
最新文档