第九章 转移指令的原理
# 第九章 转移指令的原理
本章主要讲如何控制 CPU 执行指令的顺序。
可以修改 IP,或同时修改 CS 和 IP 的指令统称为转移指令。概括的降,转移指令就是可以控制 CPU 执行内存中某处代码的指令。
8086CPU 的转移指令有以下几类。
- 只修改 IP 时,称为段内转移,比如:jum ax。
- 同时修改 CS 和 IP 时,称为段间转移,比如:jmp 1000:0。
由于转移指令对 IP 的修改范围不同,段内转移又分为:短转移和近转移。
- 短转移 IP 的修改范围为 - 128~127。
- 近转移 IP 的修改范围为 - 32768~32767。
8086CPU 的转移指令分为以下几类。
- 无条件转移指令(如 jmp)
- 条件转移指令
- 循环指令(如 loop)
- 过程
- 中断
这些转移指令的前提条件可能不同,但转移的基本原理是相同的。
# 9.1 操作符 offset
操作符 offset 在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。
# 9.2 jmp 指令
jmp 为无条件转移指令,可以只修改 IP,也可以同时修改 CS 和 IP。
jmp 指令要给出两种信息:
(1)转移的目的地址
(2)转移的距离(段间转移、段内短转移、段内近转移)
下面几节将对 jmp 指令进行详细的介绍。
# 9.3 依据位移进行转移的 jmp 指令
jmp short 标号
实现的是段内短转移,执行后: (IP) = (IP)+ 8 位位移。
(1)8 位位移 = 标号处的地址 - jmp 指令后第一个字节的地址;
(2)short 指明此处的位移为 8 位位移;
(3)8 位位移的范围为 - 128~127,用补码表示;
(4)8 位位移由编译程序在编译时算出。
jmp near ptr 标号
实现的是段内近转移,执行后:(IP) = (IP) + 16 位位移。
(1)16 位位移 = 标号处的地址 - jmp 指令后第一个字节的地址;
(2)near ptr 指明此处的位移为 16 位位移,进行的是段内近转移;
(3)16 位位移的范围为 - 32768~32767,用补码表示;
(4)16 位位移由编译程序在编译时算出。
# 9.4 转移的目的地址在指令中的 jmp 指令
jmp far ptr 标号
实现的是段间转移,又称为远转移。功能如下:
(CS)= 标号所在段的段地址;(IP)= 标号所在段中的偏移地址。
far ptr 指明了指令用标号的段地址和偏移地址修改 CS 和 IP。
该指令与上节学习的段内转移明显不同的是:
段内转移机器指令携带的是位移,段间转移机器指令携带的是目的地址。
# 9.5 转移地址在寄存器中的 jmp 指令
jmp 16 位的 reg
该指令实现的功能为:(IP)= (16 位的 reg)
# 9.6 转移地址在内存中的 jmp 指令
jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放一个字,是转移的目的偏移地址。
内存单元地址可以用之前学过的任一寻址方式给出。
jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的的偏移地址。
# 9.7 jcxz 指令
jcxz 标号
功能:如果(cx)=0,则转移到标号处执行。如果(cx)≠ 0,则程序继续向下执行。
jcxz 指令为有条件转递指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对 IP 的修改范围都为:-128~127。
# 9.8 loop 指令
loop 标号
功能:(cx)=(cx)-1,如果(cx)≠ 0,则转移到标号处执行。
# 9.9 根据位移进行转移的意义
方便了程序段在内存中的浮动装配。
# 9.10 编译器对转移位移超界的检测
根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将报错。