目录
1. 无条件转移指令 JMP
(1)段内直接转移
(2)段内间接转移
(3)段间直接转移
(4)段间间接转移
2. 条件转移指令
3. 循环控制指令
(1)LOOP 指令
(2)LOOPZ/LOOPE 指令
(3)LOOPNZ/LOOPNE 指令
4. 过程调用和返回
(1)段内直接调用
(2)段内间接调用
(3)段间直接调用
(4)段间间接调用
(5)返回指令 RET
5. 中断指令
(1)中断指令 INT
(2)中断返回指令 IRET
6. 处理器控制指令
1. 无条件转移指令 JMP
功能:无条件地使程序转移到指定的目标地址,并从该地址开始执行新的程序段。
目标地址 = 段地址 + 偏移地址
- 段内转移:CS不变,仅改变IP的值。
- 段间转移:CS、IP寄存器的内容均发生改变。
转移指令对 FLAGS 状态标志位没有影响。
(1)段内直接转移
格式:JMP Label
执行:Label + Disp → IP
写法:JMP XXXXH
Label:段内标号,又称符号地址,它表示转移的目的地。该标号在本程序所在代码段内。
举例
指令被汇编时,汇编程序会计算出 JMP 指令的下一条指令到 NEXT 所指示的目标地址之间的位移量,即相距多少个字节单元。指令的操作是将 IP 当前值加上计算出的地址位移量 Disp 形成新的 IP,并使 CS 保持不变,从而使程序按新地址继续运行,即实现了程序的转移。
(2)段内间接转移
格式:JMP OPRD
执行:OPRD → IP
OPRD:是通用寄存器或存储器根据相应的寻址方式,获得的一个 16 位操作数来作为转移目标的偏移地址。
例题
(3)段间直接转移
格式:JMP FAR PTR Label(FAR PTR 使 Label 成为远标号,PTR 属性修改)
执行:段地址 → CS、偏移地址 → IP
写法:JMP XXXXH:XXXXH
Label:段间标号,又称远标号,该标号在另一个代码段内。Label 直接给出汇编程序转移时需要的 16 位段地址和 16 位偏移地址,即标号所在的代码段及其位置的偏移地址。
(4)段间间接转移
格式:JMP OPRD
执行:OPRD(高 16 位) → CS、OPRD(低 16 位) → IP
OPRD:是一个根据寻址方式得到的 32 位存储器操作数。
因为寄存器位宽只有 16 位,所以 OPRD 不可能是寄存器操作数。
例题
注意:寄存器间接寻址只允许使用 BX、BP、SI、DI 。
2. 条件转移指令
① 根据前一条指令执行后的标志位状态来决定是否转移。
② 若满足转移条件,则转移到指定的地址;否则顺序执行下一条指令。
③ 所有的条件转移都是直接寻址方式的短转移,即只能在以当前 IP 值(转移指令的下一条)为中心的 -128 ∽ 127 字节范围内转移。
由前面关于汇编的介绍可知,汇编时将会计算位移量 Disp 。而为了缩短指令长度,只用了 8 位来存储位移量,因此转移范围为 -128 ∽ 127 字节。
④ 条件转移不影响标志位。
单一条件
复合条件
3. 循环控制指令
① 循环的次数必须先送入CX寄存器中。
② 控制转向的目标地址是以当前 IP 值(循环控制指令的下一条)为中心的 -128 ~ 127 字节范围内标号所代表的偏移地址。
③ 循环控制指令不影响状态标志位,状态标志位主要由循环控制指令之前的指令改变。
(1)LOOP 指令
格式:LOOP Label
执行:① CX - 1 → CX ② 如下
- 若 CX ≠ 0,则 Label → IP 。
- 若 CX = 0,则退出循环、执行下一条指令。
LOOP Label 看似等价于:
① DEC CX
② JZ Label
但实质不一样,因为 LOOP 不会改变 FLAGS 。
例题
(2)LOOPZ/LOOPE 指令
格式:LOOPZ Label 或 LOOPE Label
执行:① CX - 1 → CX ② 如下
- 若 CX ≠ 0、ZF = 1,则 Label → IP 。
- 若 CX = 0 或 ZF = 0,则退出循环、执行下一条指令。
FLAGS 状态标志位(ZF 位)由循环控制指令之前的指令改变。
FLAGS 状态标志位(ZF 位)由重复前缀后的串操作指令改变。
(3)LOOPNZ/LOOPNE 指令
格式:LOOPNZ Label 或 LOOPNE Label
执行:① CX - 1 → CX ② 如下
- 若 CX ≠ 0、ZF = 0,则 Label → IP 。
- 若 CX = 0 或 ZF = 1,则退出循环、执行下一条指令。
4. 过程调用和返回
① 调用指令 CALL
- 保存主程序断点地址,也是返回地址
- 子程序入口地址 → IP 或 CS 和 IP
② 返回指令 RET
- 主程序返回地址 → IP 或 CS 和 IP
过程调用和返回与中断的区别:过程调用和返回直接得到子程序入口地址,而中断需要通过查询中断向量表来得到中断服务程序入口地址。
(1)段内直接调用
格式:CALL PROC
执行:如下
- ① SP - 2 → SP
- ② IP 高 8 位 → SP + 1
- ③ IP 低 8 位 → SP
- ④ PROC → IP
写法:CALL XXXXH
PROC:是一个近过程的符号地址,表示指令调用的过程是在当前代码段内。指令在汇编后会得到 CALL 指令的下一条指令与被调用过程的入口地址之间相差的 16 位相对偏移量。
(2)段内间接调用
格式:CALL OPRD
执行:如下
- ① SP - 2 → SP
- ② IP 高 8 位 → SP + 1
- ③ IP 低 8 位 → SP
- ④ OPRD→ IP
OPRD:是 16 位寄存器或两个存储器单元的内容。这个内容代表的是一个近过程的入口地址。若操作数 OPRD 是一个 16 位通用寄存器,则将寄存器的内容送 IP;若是存储单元,则将存储器的两个单元的内容送 IP。
(3)段间直接调用
格式:CALL FAR PTR PROC(FAR PTR 指明 PROC 是远过程,需要取 CS 和 IP)
执行:如下
- ① SP - 2 → SP,CS →([SP + 1],[SP])
- ② SP - 2 → SP,IP →([SP + 1],[SP])
- ③ 段地址 → CS,偏移地址 → IP
用指令中给出的段地址取代 CS 的内容,偏移地址取代 IP 的内容。
PROC:是一个远过程的符号地址,表示指令调用的过程在另外的代码段内。
(4)段间间接调用
格式:CALL OPRD
执行:如下
- ① SP - 2 → SP,CS →([SP + 1],[SP])
- ② SP - 2 → SP,IP →([SP + 1],[SP])
- ③ OPRD(高 16 位) → CS,OPRD(低 16 位) → IP
OPRD:是一个根据寻址方式而得到的 32 位存储器操作数。
(5)返回指令 RET
格式:RET
执行:
对于段内:([SP + 1],[SP])→ IP,SP + 2 → SP
对于段间:如下
- ① ([SP + 1],[SP])→ IP,SP + 2 → SP
- ② ([SP + 1],[SP])→ CS,SP + 2 → SP
RET 指令一般位于子程序的最后一条,不影响 FLAGS 状态标志位。
5. 中断指令
(1)中断指令 INT
中断指令用于产生软件中断,以执行一段特殊的中断处理过程。
格式:INT n
n 是中断向量码/中断类型码,取指范围为 0 ~ 255 。
中断向量地址 = n × 4
CPU 根据中断向量地址读取内存,取出中断服务子程序的入口地址。
- 中断向量高 16 位 → CS
- 中断向量低 16 位 → IP
操作:
TF 置为 0,即禁止单步跟踪;IF 置为 0,即关闭中断。
没有把它们放在第一步是为了防止它们修改原来的 FLAGS 。
(2)中断返回指令 IRET
中断返回指令位于中断服务子程序的最后一条,用于返回被中断的程序。
格式:IRET
操作: