第六周 程序与处理器控制指令
大家好,又是我,沉迷学习无法自拔的小笨蛋康sir。
这个文集(点我)将会同步更新我观看吴宁老师的《微机原理与接口技术》教学视频写的笔记,学习笔记,大概每周一章。
有问题大家可以在评论下面留言讨论,欢迎纠错!
欢迎收藏阅读,动动小手给个硬币点个赞。
——@正能量的康sir
也可移步我的博客(https://blog.csdn.net/qq_33956508)会更新一些其它技术类文章。

程序控制类指令的本质是:控制程序的执行方向
决定程序执行方向的因素:CS,IP
修改IP,会使程序改变在当前代码段中的执行顺序
同时修改CS,IP会使程序走向另一个代码段执行

程序控制类指令以“隐含”的方式修改CS 和IP,以实现控制程序走向的目的(Intel指令集不允许由指令直接修改CS 和IP)
通过修改IP或CS和IP,实现程序的三种基本控制结构:顺序,选择(分支),循环
学习程序控制类指令需要重点关注:如何实现对CS和IP的修改?
程序控制类指令:
转移指令
循环控制
过程调用
中断控制
第29讲 无条件转移指令
转移指令
作用:通过修改指令的偏移地址或段地址及偏移地址实现程序的转移
分类:
无条件转移指令:无条件转移到目标地址
条件转移指令:当具备一定条件(通常指状态标志位)时转移到目标地址
无条件转移指令
格式:JMP OPRD
OPRD是目标地址。可以与JMP在同一代码段 或 与JMP不在同一代码段
可以实现在当前代码段内或段间转移
(1)无条件段内转移
转移的目标地址在当前代码段内,段地址不改变
目标地址是16位偏移地址。
指令中直接给出目标地址(段内直接转移)
由指令中的寄存器或存储器操作数指出目标地址(段内间接转移)
①段内直接转移:转移的目标地址由指令直接给出
格式:JMP Label;Label是标号,标号第四章会讲。
Label和JMP之间没有任何说明,说明这里Label是个近地址标号(段内地址,说明这是段内直接转移)。
下一条要执行指令的偏移地址=当前IP+位移量

②段内间接转移:转移的目标地址存放在某个16位寄存器或存储器的某两个单元中
例子:
MOV BX,1200H
JMP BX
执行完后IP=1200H
例2:
MOV BX,1200
JMP WORD PTR[BX]

总之,JMP后面无论什么表现形式,都是转移的目标地址
(2)无条件段间转移
转移的目标地址不在当前代码段内。
目标地址为32位,包括段地址和偏移地址。
指令中直接给出目标地址(段间直接转移)
由指令中的32位存储器操作数指出目标地址(段间间接转移)
①段间直接转移:转移的目标地址由指令直接给出
JMP FAR Label;FAR说明这里Label是远地址标号(段外地址)

②段间间接转移
段间间接寻址:转移的目标地址由指令中的32 位操作数给出 ;32位目标地址须存放于内存中
例:JMP DWORD PTR[BX];DWORD,double world,说明[BX]是32位存储器操作数

无条件转移指令例
CS: IP
(1) 2000H: 0100H MOV AX,1200H
(2) 2000H: 0103H JMP NEXT
┅
(m) 2000H: 0120H NEXT: MOV BX,1200H
(m+1) JMP BX
┅
(5) 2000H: 1200H
无条件转移指令例2
MOV SI,1122H
MOV WORD PTR[SI],0120H
ADD SI,2
MOV WORD PTR[SI],0122H
JMP WORD PTR[SI];转移1124H,IP=0122H
如果将最后一句换成
JMP DWORD PTR[SI-2];转移到1122H,因为DWORD,32位,所以CS=0122H,IP=0120H

第30讲 条件转移指令
在满足一定条件下,程序转移到目标地址继续执行
条件转移指令均为段内短转移,即转移范围为:-128----- +127

表中:
除了JCXZ是基于CX的状态之外,其他的都是基于一个或两个标志位的状态
表中“/”前后的指令含义相同,表示方式不同
基于1个标志位状态实现转移的指令(这里“/”前后命令相反)
JC/JNC:判断CF的状态。常用于两个无符号数大小比较
JZ/JNZ:判断ZF的状态。常用于循环体的结束判断
JO/JNO:判断OF的状态。常用于有符号数溢出的判断
JP/JPE:判断PF的状态。用于判断运算结果低8位中1的个数是否为偶数
JS /JNS:判断SF的状态。常用于判断数的性质
基于2个或3个标志位状态实现转移的指令:
JA/JAE/JB/JBE:判断CF或CF+ZF的状态。常用于无符号数大小的比较
JG/JGE/JL/JLE:判断SF+OF或SF+OF+ZF的状态。常用于有符号数大小的比较
基于CX内容转移的指令
JCXZ:可根据指令执行后CX的结果实现转移
转移指令例
统计内存数据段中以TABLE为首地址的100个8位带符号数中 正数、负数和零元数的个数。
基本思路:
可先将存放统计值的单元(或寄存器)清零
读取一个数,通过标志位的状态判断数的性质
最高位为1,则为负数
最高位为0,则为正数或零
如何既不改变数本身, 又能影响标志位从而 获得数的性质?(数和本身按位相与 或者 相或)

程序代码
START:XOR AL,AL
MOV PLUS,AL
MOV MINUS,AL
MOV ZERO,AL
LEA SI,TABLE
MOV CL,100
CLD
CHECK:LODSB;(串装入,将SI的内容,写入AL中,再将SI+1.没有重复前缀,所以不会循环)
OR AL,AL
JS X1;SF符号标志位 最高位是1(负数)则跳到X1
JZ X2;ZF零标志位 上一步最高位是0留下的数里,结果是0的
INC PLUS
JMP NEXT
X1:INC MINUS
JMP NEXT
X2:INC ZERO
NEXT:DEC CL
JNZ CHECK;CL不为零跳转CHECK
HLT
第31讲 循环控制指令
循环范围:
以当前IP为中心的-128~+127范围内循环。
循环次数由CX寄存器指定。
循环指令:
无条件循环指令:LOOP
条件循环指令:LOOPZ、LOOPNZ
(1)无条件循环指令
格式: LOOP LABEL
循环条件: CX ≠ 0
操作:完全相当于
DEC CX
JNZ 符号地址
条件循环指令
功能:先使CX-1,再根据CX中的值及ZF值来决定是否继续循环
格式:
LOOPZ Label: 继续循环的条件:CX≠0,且ZF=1
LOOPNZ Label: 继续循环的条件:CX≠0,且ZF=0
例:在以DATA为首地址的内存数据段中,存放有200个16位有符号数,
试找出其中最大和最小的符号数,并分别放在MAX和MIN为首的内存单元中。
题目分析:
先取数据块中第1个数,将其同时暂存于MAX和MIN中;
循环读取其它数并分别与MAX和MIN中的数进行比较
若大于则取代原MAX中的数;若小于MIN内容,则将新数放于MIN中。直到结束。
注:有符号数比较应采用JG和JL等用于符号数的条件转移指令
START:LEA SI,DATA
MOV CX,200
CLD
LODSW; 读取SI为首地址的两个单元内容到AX
MOV MAX,AX
MOV MIN,AX
DEC CX
NEXT: LODSW
CMP AX,MAX
JG LARGE;大于转移
CMP AX,MIN
JL SMALL;小于转移
JMP GOON
LARGE:MOV MAX,AX
JMP GOON ;
SMALL:MOV MIN,AX
GOON:LOOP NEXT
HLT
第32讲 过程调用指令
过程调用指令
用于调用一个子过程
与转移指令的比较
子过程执行结束后要返回原调用处,必须保护返回地址

调用指令的执行过程
① 保护断点。将调用指令的下一条指令的地址(断点)压入堆栈
② 获取子过程的入口地址。子过程第1条指令的偏移地址
③ 执行子过程。功能实现,参数的保存及恢复。(只有这一步是需要程序员做的)
④ 恢复断点,返回原程序。将断点偏移地址由堆栈弹出
断点保护和恢复由系统自动完成,但会影响堆栈的顶栈指针。
过程调用:
段内调用
段内直接调用
段内间接调用
段间调用
段间直接调用
段间间接调用
(直接调用:指令中直接给出子过程的入口地址
间接调用:由内存获得子过程的入口地址)
1. 段内调用
被调用程序与调用程序在同一代码段
调用前只需保护断点的偏移地址
格式: CALL NEAR PROCC;NEAR可以缺省,PROCC近过程名
执行过程:
将断点的偏移地址压入堆栈
根据过程名找子程序入口

例
(1)CALL TIMER;直接调用。调用名字为TIMER 的子程序
(2)CALL WORD PTR[SI];间接调用。 子程序的入口地址在内存中
设:SI=1200H,CS=6000H
执行第(2)条指令后:
CS = 6000H,IP = 3344H

2. 段间调用
子过程与原调用程序不在同一代码段
调用前需保护断点的 段基地址和偏移地址
先将断点的CS内容压栈,再压入IP内容。
格式例:
CALL FAR TIMRE;调用名为TIMER的远过程
CALL DWORD PTR[SI];32位存储器操作数,表示远过程调用

3. 返回指令
功能:从堆栈中弹出断点地址,返回原程序
格式:RET (return的缩写)
子程序的最后一条指令必须是RET
第33讲 中断指令
中断指令
中断的概念某种异常或随机事件(中断源)使处理器暂时停止正在运行的程序,转去执行一段特殊处理程序,并在处理结束后返回原程序被中断处继续执行的过程。
中断指令:引起CPU产生一次中断的指令
中断与过程调用:
相似点:从一个正在执行的过程转向另一个过程(处理程序),并在执行
完后返回原程序继续执行
区别:
中断是随机事件或异常事件引起,调用是事先已在程序中安排好;
调用指令在指令中直接给出子程序入口地址,中断指令只给出中断向量码,入口地址则在向量码指向的内存单元中。
调用可以是近过程调用或远过程调用,中断处理程序均为远过程;
响应中断请求不仅要保护断点地址,还要保护 FLAGS内容。
1. 中断指令
格式:
INT n; 中断类型码n=0~255
说明: n х 4 存放中断服务子程序入口地址的单元的偏移地址。该单元在数据段,段地址=DS
(去中断向量表中查找,后面会学到.中断向量表: 用于存放中断服务程序入口地址)

中断指令的执行过程
① 将FLAGS压入堆栈;
② 将INT指令的下一条指令的CS、IP压栈;
③ 由n×4得到存放中断向量的地址;
④ 将中断向量(中断服务程序入口地址)送CS和IP寄存器;
⑤ 转入中断服务程序。
(①-④自动完成,⑤程序员完成)

中断指令例
执行程序段:
CS IP
┇
6200H:010DH MOV SP,1200H
6200H:0110H INT 21H
6200H:0112H MOV AX,BX
┇

执行INT 21H指令后
IP=[21Hх4]
CS==[(21Hх4)+2]

2. 中断返回指令
格式:IRET
中断服务程序的最后一条指令,负责:
恢复断点
恢复标志寄存器内容
第34讲 处理器控制指令
这类指令用来对CPU进行控制,如修改标志寄存器,使CPU暂停,使CPU与外部设备同步等:
对标志位的操作
与外部设备的同步
处理器控制指令的控制对象是CPU
均为零操作数格式指令
标志位操作指令
置标志位状态

指令系统小结
指令系统
基本概念
指令中的操作数
8种寻址方式
指令系统:数据传送类,算术运算类,逻辑运算和移位,串操作,程序控制,处理器控制
理解:
指令应有的格式
不同类型指令对操作数的要求
不同类型指令的执行对标志位产生的影响
指令的执行原理:串操作指令,程序控制类指令
关注点:
指令格式
单操作数指令,移位指令,串操作指令
操作数字长的一致性
一般情况下,条件转移指令应跟在对相应标志位影响的指令后
输入输出指令格式
程序控制类指令对堆栈区的影响
处理器控制指令