410 likes | 560 Views
3.3.5 程序控制指令. 控制转移指令分为: 转移指令 循环控制指令 调用和返回指令 中断指令. 转移指令的实质:改变 IP( 或 CS) 的内容。 所有转移指令不会影响标志位。 分为 无条件转移 和 条件转移 两种。. 1.转移指令. (1) 无条件转移指令 - JMP 本指令无条件转移到指定的目标地址,以执行从该地址开始的程序段。根据设置 CS 、 IP 的方法, JMP 指令分成 4种情况 。 ① 段内 直接转移: JMP disp 指令中给出的 8/16 位的位移量 加到 IP 。 CS 保持不变。
E N D
3.3.5 程序控制指令 控制转移指令分为: • 转移指令 • 循环控制指令 • 调用和返回指令 • 中断指令
转移指令的实质:改变IP(或CS)的内容。 所有转移指令不会影响标志位。 分为无条件转移和条件转移两种。 1.转移指令
(1) 无条件转移指令 - JMP 本指令无条件转移到指定的目标地址,以执行从该地址开始的程序段。根据设置CS、IP的方法,JMP指令分成4种情况。 ① 段内直接转移: JMP disp 指令中给出的8/16位的位移量加到IP。CS保持不变。 ② 段内间接转移: JMP reg/mem reg/mem中的16位偏移地址送IP。CS保持不变。 ③ 段间直接转移 JMP segment:offset 指令中给出的16位的段和16位的偏移地址送到CS和IP。 ④ 段间间接转移 JMP mem32 mem32中的16位的段和16位的偏移地址送到CS和IP。
转移的目标地址由指令直接给出。指令中给出的目标地址实际上是一个相对于IP的位移量:转移的目标地址由指令直接给出。指令中给出的目标地址实际上是一个相对于IP的位移量: 位移量 转移范围 汇编语言中格式 8位 -128~+127JMP SHORT OPRD 16位 -32768~+32767 JMP NEAR PTR OPRD 例:JMP 0120H ;直接转向0120H JMP SHORT LP ;转向LP JMP NEAR PTR BBB ;转向BBB 由于是段内转移,故转移后CS内容保持不变 ① 段内直接转移
②段内间接转移 转移的目标地址由寄存器或存储单元的内容给出。 例1:JMP SI 若(SI)=1200H,则指令执行后,(IP)=1200H,于是转向代码段的偏移地址1200H处开始执行。 注意:目标地址以段内偏移的形式给出,而不是相对于IP的位移量,所以它是一个16位的操作数。
例2:JMP [BX+DI] 设指令执行前: (DS)=3000H,(BX)=1300H, (DI)=1200H,(32500H)=2350H; 则指令执行后:(IP)=2350H 在汇编语言中,段内间接寻址通常写成: JMP WORD PTR[BX+DI] 表示所取得的目标地址是一个字。
③段间直接转移 在指令中直接给出要转移到的目的段地址和偏移地址。 例:JMP 2000H:1000H 执行时,(IP)←1000H,(CS)←2000H 注:直接地址为符号地址时,段间直接转移指令中的符号地址前应加操作符FAR PTR。 例:JMP FAR PTR far_label 其中的far_label为远类型的标号。
转移的目的地址(段和偏移)在两个相邻的字存储单元中。例如:转移的目的地址(段和偏移)在两个相邻的字存储单元中。例如: JMP DWORD PTR[SI] 设指令执行前:(DS)=4000H,(SI)=1212H, (41212H)=1000H,(41214H)=4A00H 则指令执行后:(IP)=1000H,(CS)=4A00H 于是转到4B000H处开始执行指令。 例中的DWORD PTR表示转移地址是一个双字。 ④段间间接转移
JMP DWORD PTR [SI]的机器码 11111111 11101100 DS:[SI] 4000 DS +) 1212 SI 41212 41212 41213 41214 41215 00 1000 IP 10 00 4A00 CS 4A 段间间接转移操作示意图
条件转移指令可实现程序的条件分支。 条件转移指令根据标志位的状态来决定是否进行分支转移。 格式: JXX label;xx为条件名称缩写 指令的转移范围为-128~+127字节。 主要的条件转移指令参见p142表3-7。 (2)条件转移指令 - JXX
① 根据单个标志位设置的条件转移指令 JB/JC ;低于,或CF=1,则转移 JNB/JNC/JAE ;高于或等于,或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,则转移
这类指令主要用来判断两个数的大小。一般指令序列为:这类指令主要用来判断两个数的大小。一般指令序列为: CMP dist,src ;比较 Jxx label ;根据比较结果转移 判断无符号数的大小 JA 高于则转移(dist>src) 转移条件为: CF=0∧ZF=0 JNA/JBE 低于或等于则转移(dist≤src) 转移条件为: CF=1∨ZF=1 ② 根据组合条件设置的条件转移指令
JG ;大于则转移(dist>src) 转移条件为: (SF⊕OF=0)∧ZF=0 JGE ;大于或等于则转移(dist≥src) 转移条件为: (SF⊕OF=0)∨ZF=1 JL ;小于则转移(dist<src) 转移条件为: (SF⊕OF=1)∧ZF=0 JLE ;小于或等于则转移(dist≤src) 转移条件为: (SF⊕OF=1)∨ZF=1 判断有符号数的大小
③根据CX内容来决定是否转移的转移指令 JCXZ label 若(CX)=0,则转移到label处开始执行。
条件转移指令举例:以十六进制数形式显示BX中的内容。条件转移指令举例:以十六进制数形式显示BX中的内容。 MOV BX, 1234H MOV CH, 4 ; CH做循环计数器 ROT: MOV CL, 4 ; CL做移位计数器 ROL BX, CL ; 将最高4位移到低4位 MOV AL, BL AND 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, 2 INT 21H ; 显示输出 DEC CH ; 4个十六进制数显示完否? JNZ ROT ; 没有, 循环 MOV DL, 48H ; ‘H’ MOV AH, 2 INT 21H ; 最后显示’H’
2.循环控制指令 • 用在循环程序中以确定是否要继续循环。 • 循环次数通常置于CX中。 • 转移的目标应在距离本指令-128~+127的范围之内。 • 循环控制指令不影响标志位。
(1)LOOP 格式:LOOP label 操作:(CX)-1→CX; 若(CX)≠0,则转至label处执行; 否则退出循环,执行LOOP后面的指令。 注:LOOP指令与下面的指令段等价: DEC CX JNZ label
(2)LOOPZ (LOOPE) 格式:LOOPZlabel 操作:(CX)-1→CX; 若(CX)≠0∧ZF=1,则转至label处执行; 否则退出循环,执行LOOP后面的指令。 (3)LOOPNZ (LOOPNE) 格式:LOOPNZ label 操作:(CX)-1→CX; 若(CX)≠0∧ZF=0,则转至label处执行; 否则退出循环,执行LOOP后面的指令。
例1:给1A000H开始的256个内存单元均减去1,若 发现某个单元减为0则立即退出循环,其后的单元不再减1。程序段如下:(逻辑地址为1A00:0H) MOV AX, 1A00H MOV DS, AX ; 1A00H段 MOV DI, -1 MOV CX, 256 GOON: INC DI DEC BYTE PTR[DI] LOOPNZGOON HLT
例2:在8000H开始的长度为1000字节的字符串中 查找’S’,若找到,把其偏移地址记录在ADDR中,否则ADDR单元置为0FFFFH。 MOV DI, 8000H MOV CX, 1000 MOV AL, ’S’ MOV ADDR, 0FFFFH GOON: SCASB LOOPNZGOON JNZ DONE DEC DI MOV ADDR,DI DONE: HLT
3. 过程调用和返回指令 • 过程(子程序) 一段具有特定功能的,供其它程序调用的公用程序。 • 特点 • 调用子程序时,IP(CS)的内容被压入堆栈栈顶。从子程序返回时,栈顶的内容又被弹出到IP(CS)。 • 子程序执行结束后一般均要返回调用程序。 • 一次定义,多次调用; • 可带参数调用,以完成不同的功能。 • 优点 程序代码短,结构清晰,便于编程、调试、修改和阅读。 • 两条相关指令: 子程序调用指令 CALL 子程序返回指令 RET
一般格式:CALL sub;sub为子程序的入口 根据子程序入口的寻址方式,子程序调用有四类。 ①段内直接调用 子程序的偏移地址直接由CALL指令给出。 格式:CALL near_proc CALL执行时,它首先将IP内容压栈,然后把指令中给出的位移量加到IP上。 注:汇编以后的调用地址是相对于CALL的下一条指令的位移量。 例:CALL 0120H ;子程序偏移地址由指令给出 (1)调用指令CALL
位移量由汇编程序在汇编时进行计算,如下例: CS:0102 CALL 0120H ;3字节 CS:0105 …… 则位移量为: 0120-0105H=001BH 于是CALL 0120H的机器码为E8 1B 00 CS:0102 E8 CS:0103 1B CALL 0120H CS:0104 00 CS:0105 ……
子程序的偏移地址在寄存器或存储器中。 格式:CALL mem16/reg16 CALL执行时,它首先将IP内容压栈,然后把指定的寄存器/存储器的内容送入IP。 例: CALL BX ;子程序地址由BX给出 CALL WORD PTR[SI] ;子程序地址在存储器中 ②段内间接调用
CALL CALL WORD PTR [SI]指令的操作图示: 假定:(DS)=8000H,(SI)=1200H 代码段 IPH IPL 81200H 81201H 数据段
子程序的段地址和偏移地址直接由CALL指令给出。子程序的段地址和偏移地址直接由CALL指令给出。 格式:CALL far_proc ;far_proc为远过程的地址 指令的操作为: CS内容压栈 IP内容压栈 CS←段地址 IP←偏移地址 例:CALL 2000H:1000H CALL TIMER ;TIMER为远过程 ③段间直接调用
子程序的段和偏移地址为存储器的连续4个单元中的内容。子程序的段和偏移地址为存储器的连续4个单元中的内容。 格式:CALL mem32 指令的操作为: SP←(SP)-2 ((SP)+1,(SP))←(CS) ;CS压栈 CS←(mem32+2) SP←(SP)-2 ((SP)+1,(SP))←(IP) ;IP压栈 IP←(mem32) 例:CALL DWORDPTR[DI] 调用地址在[DI],[DI]+1,[DI]+2,[DI]+3四个存储单元中。低字内容为偏移地址,高字内容为段地址。 ④段间间接调用
CALL DWORDPTR[DI] CALL 代码段 IPH IPL [DI] [DI]+1 [DI]+2 数据段 [DI]+3 CSH CSL 段间间接调用示意图
例:下面的程序执行后,(AX)=? (DX)=? CS:2000H MOV AX, 2012H 2003H MOV CX, 200CH 2006H PUSH CX 2007H CALL 4000H 200AH ADD AX, BX 200CH ADD AX, DX 200EH HLT … … … … CS:4000H MOV BX, 200AH POP DX RET
段内返回指令RET的操作为: 恢复子程序执行前IP的内容。 段间返回指令RET的操作为: 恢复子程序执行前IP和CS的内容。 另有一种带立即数的返回指令 “RET n ”,其中n为偶数,表示从栈顶弹出地址后另外丢弃的字节数。 例:RET 4 ;返回后再丢弃栈顶的4个字节 (2)返回指令RET
4.中断指令 8086/8088 CPU在程序中允许安排一条中断指令来引起一个中断过程,这种中断叫内部中断,或叫软中断。被中断的指令地址处称为“断点”。有关中断的详细情况将在第六章讨论。 中断指令共有三条: (1)INT n 执行类型n的中断服务程序,N=0~255 (2)INTO 执行溢出中断的中断服务程序 (3)IRET 从中断服务程序返回调用程序
(1) INT n 中断类型码 n = 0〜255 • 格式: INT n • 说明: n×4= 向量地址。该向量地址中的内容即为中断服务程序入口地址(段:偏移),入口地址也称为“中断向量”。 内存 0000 : n×4 XXH XXH 中断服务程序入口的偏移地址(IP) YYH YYH 中断向量 中断服务程序入口的段地址(CS)
INT指令的操作: 将FLAGS压入堆栈; 将INT指令下一条指令的地址压栈(即把CS和IP的内容压栈); 取中断服务程序入口地址送入CS和IP。 INT指令只影响IF和TF, 对其余标志位无影响 INT指令可用于调用系统服务程序,如INT 21H
INT指令的操作例: 保护断点 • INT 21H 堆栈 SP=11FA IPL IPH 执行INT 21H指令后 CSL CSH FLAGSL FLAGSH SP=1200 执行INT 21H指令前
INT指令的操作例(续): • 执行INT 21H指令后, CS=?IP=? 因为n=21H,所以n×4=84H。 下图中,(0:0084H)=2000H:1123H 所以: CS=2000H IP=1123H 0000:0084H 23H 0000 : 21H×4 11H IP 00H 20H CS
(2)溢出中断INTO INTO检查溢出标志OF,如果OF=1,则启动一个类型4的中断过程;如果OF=0,不做任何操作。 通常INTO指令安排在有符号数算术运算指令后面。如 IMUL DX INTO ;若溢出,则启动INT 4, 否则往下执行 MOV RESULT,AX MOV RESULT+2,DX ……
用于从中断服务程序返回被中断的程序。IRET负责恢复断点(CS和IP)和恢复标志寄存器内容。用于从中断服务程序返回被中断的程序。IRET负责恢复断点(CS和IP)和恢复标志寄存器内容。 任何中断服务程序不管是外部中断引起的,还是内部中断引起的,最后都要用IRET返回。IRET指令执行的操作为: 栈顶内容弹出到IP 栈顶内容弹出到CS 栈顶内容弹出到FLAG (3)中断返回指令IRET
3.3.6 处理器控制指令 1.标志操作指令 用来设置标志位的状态。 (1)CF设置指令 CLC0→CF STC1→CF CMCCF变反 (2)DF设置指令 CLD0→DF (串操作的指针移动方向从低到高) STD1→DF (串操作的指针移动方向从高到低) (3)IF设置指令 CLI0→IF (禁止INTR中断) STI1→IF (开放INTR中断)
2. 外部同步指令 (1)暂停指令HLT 执行HLT指令时,CPU进入暂停状态,设置该指令通常是为了等待中断。 外部中断(包括IF=1时的可屏蔽中断请求INTR及非屏蔽中断请求NMI)或复位信号可让CPU退出暂停状态。 HLT不影响标志位。
(2)空操作指令NOP NOP指令不做任何实质性的操作,但占用3个时钟周期,然后执行下一条指令。 多用于延时或预留存储空间(占位子)。
作业: • P152 3.3, 3.6, 3.12, 3.15