前言
可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括的说,转移指令就是可以控制CPU执行内存中某处代码的指令。
8086CPU的转移指令分为以下几类:
- 段间转移和段内转移
段内转移分两种:短转移和近转移`
常用的转移指令
操作符offset
操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。
给出下列程序段,填写两条指令,使该程序在运行中将s处的一条指令复制到s0处。1
2
3
4
5
6
7
8
9
10
11assume cs:codesg
codesg segment
s: mov ax,bx
mov si,offset s
mov di,offset s0
__________
__________
s0: nop
nop
codesg ends
end s
提出以下几个问题:
- s和s0处的指令所在的内存单元的地址是多少?
- 将s处的指令复制到s0处,如何进行操作?
- 段地址已知在cs中,偏移地址offset s和offset s0已经送入si和di中。
- 要复制的数据有多长?
思考所得:
- 通过“offset 标号”可以得到标号的地址;
- 在8086CPU中,得到的标号地址是八位数据。
jmp指令
- 根据位移进行转移的jmp指令
jmp short 标号(转到标号处执行指令)
这种情况下执行的jmp指令在机器指令里的跳转数据并不是目标程序(或标号)的地址,而是相对偏移地址,比如jmp的前一句指令的地址为a,跳转的目标指令的地址为b,在机器指令里,只出现b-a的值,并不直接指明地址b。
这说明,CPU在执行jmp指令的时候并不需要转移的目的地址。- 转移的目的地址在指令中的jmp指令
jmp far ptr 标号
上述指令实现的是段间转移,又称为远转移。可以同时修改CS和IP。- 转移地址在寄存器中的jmp指令
指令格式:jmp 16位reg
这种修改方式只能修改IP,并不能修改CS- 转移地址在内存中的jmp指令
a、jmp word ptr 内存单元地址(段内转移)
在内存单元地址处开始存放着一个字
b、jmp dword ptr 内存单元地址(段间转移)
在内存单元地址处开始存放着两个字
我是否可以这么理解?当我提供给jmp16位数据时,只进行IP的修改,即进行段内转移,
当你提供给它32位数据时,它填满了IP,即会填充CS,实现段间转移。
jcxz条件转移指令
jcxz 标号(如果(cx)==0,转移到标号处执行)
loop指令
loop指令为循环指令,所有的循环指令都是“短转移”,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围为:-128~127。
转移指令背后的思考
根据位移进行转移的意义
采用这种位移的设计,方便了程序段在内存中的浮动装配。
如下程序所示:1
2
3
4 mov cx,6 B9 06 00
mo ax,10h B8 10 00
s: add ax,ax 01 C0
loop s E2 FC ;前移了4个字节
这样的程序装在内存的不同位置都可正确执行。
编译器对转移位移超界的检测
看如下代码:1
2
3start: jmp short s
db 128 dup(0)
s: mov ax,offffh
假设程序的入口在start处,那么在进行编译的时候,jmp指令标号s中间存在128字节的距离,而jmp short s的转移范围是-128~127,只能向后跳转127个字节,所以会编译报错。
后记
通过对CPU工作原理的深入学习,实现在底层上真正的自由。
——《编程语言》 王爽 著