1
第3章8086的寻址方式和指令系统
(5)
2
3.3.5 控制转移指令
通常,程序中的指令都是顺序地逐条执行。利用控制转移指令可以改变CS和IP的值,从而改变指令的执行顺序。
控制转移指令分为:无条件转移指令和过
程调用指令条件转移指令条件循环指令中断指令
3
目标地址的寻址方式相对寻址方式指令代码中提供目的地址相对于当前IP的位移量,转移到的目的地址(转移后的IP值)就是当前IP值加上位移量
直接寻址方式指令代码中提供目的逻辑地址,转移后的CS和IP值直接来自指令操作码后的目的地址操作数
间接寻址方式指令代码中指示寄存器或存储单元,目的地址从寄存器或存储单元中间接获得
4
指令的实质:改变IP(或CS)的内容。
指令不会影响标志位。
1.无条件转移指令和过程调用指令
5
1) 无条件转移指令JMP
指令格式: JMP 目的指令功能:无条件地转移到目的地址去执行。
本指令无条件地转移到指定的目标地址,以执行从该地址开始的程序段。
6
指令分成两种类型:
段内转移或近(NEAR)转移。转移指令的目的地址和JMP指令在同一代码段中,转移时仅改变IP的内容,段地址CS的值不变。段间转移,又称远(FAR)转移。转移指令的目的地址和JMP指令不在同一段中,转移时,CS和IP的值都要改变,程序要转移到另一个代码段去执行。
7
按转移地址提供的方式,又可分为两种方式:直接转移。在指令码中直接给出转移的目的地址,目的操作数用一个标号来表示。它又可分为段内直接转移和段间直接转移。间接转移。目的地址包含在某个16位寄存器或存储单元中,CPU必须根据寄存器或存储器寻址方式,间接地求出转移地址。同样,这种转移类型又可分为段内间接转移和段间间接转移。
8
JMP指令4种情况:①段内直接转移: JMP disp指令中给出的8/16位的位移量加到IP,CS保持不变。
②段内间接转移: JMP reg/memreg/mem中的16位偏移地址送IP,CS保持不变。
③段间直接转移 JMP segment:offset
指令中给出的16位的段和16位的偏移地址送到CS和IP。
④段间间接转移 JMP mem32
mem32中的16位的段和16位的偏移地址送到CS和IP。
9
指令格式:
JMP SHORT 标号
JMP NEAR PTR 标号 (或JMP 标号)
段内相对转移指令,目的操作数均用标号表示。
转向的有效地址=IP+8位/16位位移量(DISP)。
若转移范围在-128~+127字节内,称为短转移,指令中只需要用8位位移量,在标号前加说明符SHORT。
若位移量是16位,称为近转移,目的地址与当前IP的距离在 -32768~+32767字节之间。可加说明符NEARPTR,也可省略。这类指令用得最多。
(1)段内直接转移
10
位移量 转移范围 汇编语言中格式
8位 -128~+127 JMP SHORT LABEL
16位 -32768~+32767 JMP NEAR PTR LABEL
位移量用带符号数表示,正值表示向地址增大方向,负数表示向减小方向;
负位移量用补码表示;
8位位移量时要进行符号扩展到16位。
(1)段内直接转移
11
例:
JMP 0120H ;直接转向0120H
JMP SHORT XP ;转向XP
JMP NEAR PTR ABC ;转向ABC
(1)段内直接转移
12
转移的16位目标有效地址由寄存器或存储单元的内容给出。
例1:JMP SI
若(SI)=1200H,则指令执行后:(IP)=1200H,于是转向代码段的偏移地址1200H处开始执行。
(2)段内间接转移
13
例2:JMP [BX+DI]
设指令执行前:
(DS)=3000H,(BX)=1300H,
(DI)=1200H,(32500H)=2350H;
则指令执行后:(IP)=2350H
在汇编语言中,段内间接寻址通常写成:
JMP WORD PTR[BX+DI]
表示所取得的目标地址是一个字。
(2)段内间接转移
14
在指令中直接给出要转移的目的段址和偏移地址。
例:JMP 2000H:1000H
执行时:(IP)←1000H,(CS)←2000H
注:直接地址为符号地址时,段间直接转移指令中的符号地址前应加操作符FAR PTR。
例:JMP FAR PTR far_label
其中的far_label为远类型的标号。
(3)段间直接(远)转移
15
转移的目的地址(段和偏移)在两个相邻的字存储单元中。例如:
JMP DWORD PTR[SI]
执行前:(DS)=4000H,(SI)=1234H,
(41234H)=0100H,(41236H)=8800H
则指令执行后:(IP)=0100H,(CS)=8800H
于是转到88100H处开始执行指令。
DWORD PTR表示转移地址是一个双字。
(3)段间间接转移
16
4000
1234+)
41234
DS
SI
41234412354123641237
0100
8800
IP
CS
段间间接转移操作示意图
000100
88
1111111111101100
JMP DWORD PTR [SI]的
机器码DS:[SI]
17
2)过程调用和返回指令
将特定功能经常被用到的程序段,写成独立的程序模块,被不同主程序反复调用,称为子程序。子程序必须事先定义,然后在主程序中需要的位置调用。其定义以proc开头,endp结束。在endp之前,必须加一条返回指令ret,确保程序返回到产生调用位置的下一条指令地址。若在过程运行中又调用另一过程,称为过程嵌套。
主程序和过程在同一代码段,称为近调用,不在同一段则称为远调用。
过程调用的寻址方式与转移指令类似,但无段内短调用。
由于调用结束后需返回原程序继续运行,要执行保护和恢复返回地址操作,比转移指令复杂。
18
2)过程调用和返回指令
特点:①调用子程序时,IP(CS)的内容被压入堆栈栈顶。从子程序返回时,栈顶的内容又被弹出到IP(CS);②子程序执行结束后一般均要返回调用程序;③一次定义,多次调用;④可带参数调用,以完成不同的功能。
优点:程序代码短,结构清晰,便于编程、调试、修改和阅读。
19
一般格式:CALL sub; sub为子程序的入口地址操作:第一步:返址入栈,将CALL下面指令的地址入栈近调用:SP←SP-2,IP入栈。远调用:SP←SP-2,CS入栈,
SP←SP-2,IP入栈。第二步:转到CALL指令目的操作数指明的入口地址执行子程序。
根据子程序入口的寻址方式,子程序调用有四类。
(1)调用指令CALL
20
CALL指令分成4种类型
CALL near_proc ;段内调用、直接寻址
CALL mem16/reg16 ;段内调用、间接寻址
CALL far_proc ;段间调用、直接寻址
CALL mem32 ;段间调用、间接寻址
CALL指令需要保存返回地址
段内调用——入栈保存偏移地址IP SP←SP-2,SS:[SP]←IP
段间调用——入栈保存偏移地址IP和段地址CS
SP←SP-2,SS:[SP]←CS
SP←SP-2,SS:[SP]←IP
21
①段内直接调用
子程序的偏移地址直接由CALL指令给出。
格式:CALL near_proc
操作:SP←SP-2,
返回地址的IP入栈,
将当前IP和位移量相加,得到新IP,
根据新的IP执行程序。
注:汇编以后的调用地址是相对于CALL的下一条指令的位移量。
22
例:CALL 0120H ;子程序偏移地址由指令给出
位移量由汇编程序在汇编时进行计算,如下:
CS:0102 CALL 0120H ;3字节
CS:0105 ……
则返回地址为CS:0105H,即入栈的IP=0105H。
位移量为: 0120-0105H=001BH
于是CALL 0120H的机器码为E8 1B 00
CS:0102 E8
CS:0103 1B CALL 0120H
CS:0104 00
CS:0105 ……
23
子程序的偏移地址在寄存器或存储器中。格式:CALL mem16/reg16操作:
SP←SP-2IP入栈IP←EA[mem16/reg16]
例:CALL BX ;子程序地址由BX给出CALL WORD PTR[SI] ;子程序地址在存储器中
②段内间接调用
24
CALL
IPH IPL
代码段
数据段
CALL WORD PTR [SI]指令的操作假定:(DS) = 8000H,(SI) = 1200H
81200H
81201H
22
22
33
33
25
子程序的段地址和偏移地址直接由CALL指令给出。
格式:CALL far_proc ;far_proc为远过程的地址
操作:
SP←SP-2
CS压栈
SP←SP-2
IP压栈
CS←段地址
IP←偏移地址
例: CALL 2000H:1000H
CALL TIMER ;TIMER为远过程
③段间直接调用
26
子程序的段和偏移地址为存储器的连续4个单元中的内容。
格式:CALL mem32;前两字节为偏移,后两字节为代码段
操作:
SP←(SP)-2
((SP)+1,(SP))←(CS) ;CS入栈
SP←(SP)-2
((SP)+1,(SP))←(IP) ;IP入栈
IP←(mem32)
CS←(mem32+2)
④段间间接调用
27
CALL
代码段
数据段DS
IPH IPL
CSH CSL
[DI]
[DI]+1
[DI]+2
[DI]+3
段间间接调用
CALL DWORD PTR[DI]
12
12
34
34
56
56
78
78
28
①段内返回指令RET的操作为:
恢复子程序执行前IP的内容。
②段间返回指令RET的操作为:
恢复子程序执行前IP和CS的内容。
③带立即数的返回指令“ RET n ”,其中n为0000 ~
FFFFH之间的偶数。
表示从栈顶弹出地址后另外丢弃的字节数。
即在弹出返回地址后,再弹出n个字节,使得SP再增加n。
例:RET 4 ;返回后再丢弃栈顶的4个字节
(2)返回指令RET
29
根据段内和段间、有无参数,分成4种返回类型:
RET ;无参数段内返回
RET i16 ;有参数段内返回
RET ;无参数段间返回
RET i16 ;有参数段间返回
30
例:下面的程序执行后,(AX)=? (DX)=?CS:2000H MOV AX, 2012H
2003H MOV CX, 200CH2006H PUSH CX 2007H CALL 4000H200AH ADD AX, BX200CH ADD AX, DX200EH HLT
… … … …
CS:4000H MOV BX, 200AHPOP DXRET
31
例:下面的程序执行后,(AX)=? (DX)=?
CS:2000H MOV AX, 2012H;(AX)=2012H
2003H MOV CX, 200CH;(CX)=200CH
2006H PUSH CX;SP1←SP-2,(SP1) ←200CH
2007H CALL 4000H;SP2←SP-4,(SP2)←IP=200AH
200AH ADD AX, BX;
200CH ADD AX, DX;(AX)=2012H,(DX)=200AH
;加法后:(AX)=401CH
200EH HLT
… …
… …
CS:4000H MOV BX, 200AH;(BX)=200AH
POP DX;SP3←SP2+2=SP-2,(DX)=200AH
RET ;SP4←SP3+2=SP,(IP)=200CH
32
条件转移指令可实现程序的条件分支。
条件转移指令根据标志位的状态来决定是否进行分支转移。
格式:
JXX label ;xx为测试条件名称缩写
条件转移均为段内短转移,转移指令与目的地址必须在同一代码段中。转移距离范围为-128~+127字节。8位偏移量需用符号扩展到16位后才能与IP相加。
18条指令,归类成直接标志转移和间接标志转移两大类。
2.条件转移指令JXX
33
①直接标志转移指令
JC ;低于,或CF=1,则转移
JNC ;高于或等于,或CF=0,则转移
JP/JPE ;奇偶标志PF=1(偶),则转移
JNP/JPO ;奇偶标志PF=0(奇),则转移
JZ/JE ;结果为零(ZF=1),则转移
JNZ/JNE ;结果不为零(ZF=0),则转移
JS ;SF=1,则转移
JNS ;SF=0,则转移
JO ;OF=1,则转移
JNO ;OF=0,则转移
34
例 求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: … ;程序继续进行
35
②间接标志转移指令
这类指令主要用来判断两个数的大小。通常放在CMP指令之后。
一般指令序列为:CMP dist,src ;dist-src,比较Jxx label ;根据比较结果转移
36
判断无符号数的高低:利用CF、ZF的状态组合
JA/JNBE:高于/不低于等于则转移(dist>src)转移条件为: CF=0∧ZF=0
JBE/JNA:低于等于/不高于则转移(dist≤src)转移条件为: CF=1∨ZF=1
JAE/JNB:高于等于/不低于则转移转移条件为: CF=0
JB/JNAE:低于/不高于等于则转移转移条件为: CF=1
37
判断有符号数的大小:利用SF、OF、ZF的组合
JG/JNLE:大于/不小于等于则转移(dist>src)转移条件为: (SF⊕OF=0)∧ZF=0
JGE/JNL:大于等于/不小于则转移(dist≥src)转移条件为: (SF⊕OF=0)∨ZF=1
JL/JNGE:小于/不大于等于则转移(dist<src)转移条件为: (SF⊕OF=1)∧ZF=0
JLE/JNG:小于等于/不大于则转移(dist≤src)转移条件为: (SF⊕OF=1)∨ZF=1
38
例:以十六进制数形式显示BX中的内容。
MOV BX, 1234H
MOV CH, 4 ; CH做循环计数器ROT: MOV CL, 4 ; CL做移位计数器
ROL BX, CL ;将最高4位移到低4位MOV AL, BLAND AL, 0FH ;取出低4位ADD AL, 30H ; 转换为ASCII码CMP AL, 39H ; 与 ’9’ 比较JBE DISP ; 若(AL)≤‘9’, 则转显示ADD AL, 7 ; 若(AL)>’9’, 则加7转为‘A’-‘F’
DISP: MOV DL, AL; (DL)←字符MOV AH, 2INT 21H ; 显示输出DEC CH ; 4个十六进制数显示完否?JNZ ROT ; 没有, 循环MOV DL, 48H ; ‘H’MOV AH, 2INT 21H ; 最后显示’H’
39
3.循环控制指令
在重复执行的循环程序中用以确定是否要继续循环。
循环次数通常置于CX中。
转移的目标应在距离本指令-128~+127的范围之内。
循环控制指令不影响标志位。
循环指令共4条。
40
1)LOOP
格式:LOOP label指令功能:重复执行一系列指令。操作:CX←(CX)-1;若(CX)≠0,则转至label处执行;否则退出循环,执行LOOP后面的指令。
注:LOOP指令与下面的指令段等价:DEC CXJNZ label
41
例1:数据块传送(字节)MOV CX,400H
;设置循环次数:1K=1024=400H
MOV SI,OFFSET sbuf
;设置循环初值:SI指向数据段源缓冲区开始
MOV DI,OFFSET dbuf
;DI指向附加段目的缓冲区开始(附加段)
again: MOV AL,[SI] ;循环体:实现数据传送
MOV ES:[DI],AL ;每次传送一个字节
INC SI ;SI和DI指向下一个单元
INC DI
LOOP again
;循环条件判定:循环次数减1,不为0转移
42
例2 商店里有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(?)
…
43
MOV CX,08H ;共8种商品MOV BX,00H ;BX作指针,初值为0
NEXT:MOV AL,OLD[BX] ;读入一个商品的原价ADD AL,7 ;加上提价因子DAA ;调整为十进制数MOV NEW[BX],AL ;存放结果INC BX ;地址指针加1LOOP NEXT ;未加满8次,继续循环
… ;已加完8次
44
2)LOOPZ (LOOPE)
格式:LOOPZ/LOOPE label指令功能: LOOPE是相等时循环,LOOPZ是结果为0时循环。操作:CX←(CX)-1;若(CX)≠0∧ZF=1,则转至label处执行;否则(CX=0∨ZF=0)退出循环,执行OOPZ后面
的指令。
45
3)LOOPNZ (LOOPNE)
格式:LOOPNZ/LOOPNE label指令功能:LOOPNE是不相等循环,而LOOPNZ是结果ZF≠1循环,它们也是一对功能相同但形式不一样的指令。操作:CX←(CX)-1;若(CX)≠0∧ZF=0,则转至label处执行;否则(CX=0∨ZF=1)退出循环,执行LOOPNZ后
面的指令。
46
例3:给1A000H开始的256个内存单元均减去1,若发现某个单元减为0则立即退出循环,其后的单元不再减1。程序段如下:
MOV AX, 1A00H
MOV DS, AX ; 1A00H段
MOV DI, -1
MOV CX, 256
go_on: INC DI
DEC BYTE PTR[DI]
LOOPNZ go_on
HLT
47
例4:在8000H开始的长度为1000字节的字符串中查找‘$’,若找到,把其偏移地址记录在ADDR中,否则ADDR单元置为0FFFFH。
MOV DI, 8000H
MOV CX, 1000
MOV AL, ‘$’
MOV ADDR, 0FFFFH
go_on: SCASB
LOOPNZ go_on
JNZ DONE
DEC DI;SCASB时,DI自动加1,所以,要调整。
MOV ADDR,DI
DONE: HLT
48
4)根据CX内容来决定是否转移的转移指令
格式:JCXZ label
指令功能:若CX寄存器为0,则转移到指令中标号所指定的地址处,否则将往下顺序执行。
用途:
这条指令用在循环程序开始处。为了使程序跳过循环,只要事先把CX寄存器清0。
49
4.中断指令
1) 中断概念计算机在执行正常程序过程中,由于某些事件发生,需要暂时中止当前程序的运行,转到中断服务程序去为临时发生的事件服务。中断服务程序执行完,又返回正常程序继续运行。此过程称为中断。
中断源:外部硬件,内部中断(中断指令、内部事件)
被中断的指令地址处称为“断点”。
有关中断的详细情况将在第七章讨论。
50
4.中断指令
2)中断指令
中断指令共有三条:
(1)INT n 执行类型n的中断服务程序,N=0~255
(2)INTO 执行溢出中断(类型4)的中断服务程序
(3)IRET 从中断服务程序返回调用程序
51
说明:
中断向量
n×4 =向量地址。该向量地址中的内容即为中断服务程序入口地址(段:偏移),入口地址称为“中断向量”。
0000 : n×4 XXHXXHYYHYYH
中断服务程序入口的(IP)
中断服务程序入口的(CS)
中断类型码
n = 0〜255内存
中断向量
中断向量表
(00000-003FFH)格式:
INT n
52
INT指令的操作:
将FR压入堆栈,并清IF、TF;将INT指令下一条指令的地址压栈(CS、IP压
栈);取中断服务程序入口地址送入CS和IP。
INT指令只影响IF和TF,对其余标志位无影响;INT指令可用于调用系统服务程序,如INT 21H
53
INT指令的操作例:
INT 21H
IPL
IPH
CSL
CSH
SP=1200
FLAGSL
FLAGSH
SP=11FA
执行INT 21H指令后
保护断点堆栈段
执行INT 21H指令前
54
INT指令的操作例(续):
0000:0084H 34H12H00H20H
IP
CS
0000 : 21H×4
执行INT 21H指令后, CS=? IP=?
因为n=21H,所以n×4=84H。
下图中,(0:0084H)=2000H:1123H
所以: CS=2000H IP=1234H中断向量表
55
中断类型号为4。
INTO检查溢出标志OF,如果OF=1,则启动一个类型4的中断过程;如果OF=0,不做任何操作。
通常INTO指令安排在有符号数算术运算指令后面。如
IMUL DXINTO ;若溢出,则启动INT 4,否则往下执
行
MOV RESULT,AXMOV RESULT+2,DX……
溢出中断INTO
56
用于从中断服务程序返回被中断的程序。
IRET负责恢复断点(CS和IP)和恢复标志寄存器内容。
IRET指令执行的操作:
栈顶内容弹出到IP
栈顶内容弹出到CS
栈顶内容弹出到FLAG
中断返回指令IRET
→
57
类型号0。
执行除法指令,若除数为0或商超出寄存器最大值范围,自动产生该中断。
(1)除法错中断
专用中断
58
TF位置1,每条指令执行完成,自动产生类型号1的中断,CPU响应后,暂态执行下条指令。
中断服务程序中,可以将寄存器、存储器等内容显示。
(2)单步中断
59
NMI引脚出现由低变高的电平变化,自动产生类型号2的中断。
(3)不可屏蔽中断
60
类型号3。
在程序中,相应的程序位置设置 INT 3,则程序运行到指令位置产生断点中断。
便于调试程序。
(4)断点中断
61
(5)溢出中断INTO
62
3.3.6 处理器控制指令
1.标志操作指令用来设置标志位的状态。(1)CF设置指令
CLC:CF←0STC:CF←1CMC:CF取反
(2)DF设置指令CLD:DF←0 (串操作的指针移动方向从低到高)STD:DF←1 (串操作的指针移动方向从高到低)
(3)IF设置指令CLI:IF←0 (禁止INTR中断)STI:IF←1 (允许INTR中断)
63
1) ESC 换码指令 (Escape)指令格式:ESC 外部操作码,源操作数指令功能:换码指令实现8086对8087协处理器的控制。
2) WAIT 等待指令 (Wait)通常跟在ESC指令之后。ESC指令执行后,8086CPU处于等待状态,不断检测#TEST引脚。若为高,则重复执行WAIT指令,处理器处于等待状态;如变低,退出等待状态,执行下条指令。
3) LOCK 封锁总线指令 (Lock Bus)可加在任何指令的前面。凡带有LOCK前缀的指令在执行过程中,将禁止其它处理器使用总线。
2. 外部同步指令
64
执行HLT指令时,CPU进入暂停状态,设置该指令通常是为了等待中断。
外部中断(包括IF=1时的可屏蔽中断请求INTR及非屏蔽中断请求NMI)或复位信号,可使CPU退出暂停状态。
HLT不影响标志位。
3. 停机和空操作指令
(1)暂停指令HLT
65
(2)空操作指令NOP
NOP指令不做任何实质性的操作,但占用3个时钟周期,然后执行下一条指令。
多用于延时或预留存储空间。
3. 停机和空操作指令
66
本章结束
第三章作业(第五版) pp.120-123
1
3
6
7
9
10
12
13
14
16