2013-7-9 20:57:50
转移指令的原理
可以修改IP,或同时修改CS和IP的指令统称为转移指令,
概括讲:转移指令就是可以控制cpu执行内存中某处代码的指令。
8086cpu转移行为:
1 只修改IP时,称为段内转移,比如 jmp ax
2 同事修改CS和IP时,称为段间转移, 比如 jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移又分为短转移和近转移
短转移IP的修改范围为-128~127
近转移IP的修改范围为-32768~32767
8086cpu的转移指令分为以下几类:
1 无条件转移指令(jmp)
2 条件转移指令()
3 循环指令(loop)
4 过程
5 中断
操作符offset
操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址
jmp指令
jmp为无条件转移指令,可以修改IP,也可以同时修改CS和IP
jmp指令要给出两种信息
1 转移的目的地址
2 转移的距离 (段间转移、段内短转移、段内近转移)
不同的给出目的地址的方法,和不同的转移地址,对应有不同格式的jmp指令。
依据位移进行转移的jmp指令
jmp short 标号(转移到标号处执行指令)
这种格式的jmp指令实现的是段内短转移,它对IP的修改范围为-128~127,
也就是说。它向前转移时可以最多越过128个字节,向后转移最多为127个字节。j
mp指令中的short符号说明指明进行的是短转移,标号是代码中的标号,指明了指令要转移的目的地,转移指令结束后,CS:IP应指向标号处的指令
实际上,指令"jmp short 标号"的功能是:(IP) = (IP) + 8位位移
还有个指令和此指令相识
jmp near ptr 标号,它实现的是段内近转移
指令"jmp near ptr 标号" 的功能:(IP) = (IP) + 16位位移
转移的目的地址在指令中的jmp指令
jmp far ptr 标号 , 实现的是段间转移,又称远转移
功能:(CS) = 标号所在段的段地址,(IP) = 标号在段中的偏移地址
far ptr指明了指令用标号的段地址和偏移地址修改CS和IP
转移地址在寄存器中的jmp指令
指令格式:jmp 16 位寄存器
功能: (IP)=(16位寄存器)
转移地址在内存中的jmp指令
有两种指令格式
1、jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址
2、jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址
jcxz指令
次指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中,包含转移的位移,而不是目的地址,对IP修改的范围都为 -128~127;
指令: jcxz 标号(如果(cx)=0,转移到标号处执行)
操作:当(cx)=0 时,(IP) = (IP) +8 位位移
8位位移 = “标号”处的地址--jcxz指令后的第一个字节地址
8位位移的范围-128~127,
当(cx) ≠0 时,什么也不做,(程序向下执行)
我们从jcxz的功能可以看出 "jcxz 标号"的功能能相当于:
if((cx) == 0) jmp short 标号
loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。
指令格式 loop 指令((cx) = (cx)-1, cx≠0,转移到标号处执行)
操作:1 (cx) = (cx) -1
2 如果(cx)≠0, (IP) =(IP)+ 8位位移
根据位移进行转移的意义
前面讲到的
jmp short 标号, jmp near ptr标号,jcxz 标号, loop 标号 等几种汇编指令,
它们对IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。
在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移。
这种设计,方便了程序段在内存中的浮动装置
call和ret指令
call和ret指令都是转移指令,它们都是修改IP或同时修改CS和IP,
ret指令用栈中的数据,修改IP的内容,从而实现近转移
retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
cpu执行ret指令时,进行下面两步操作:
1 (IP) = ((SS)*16+(SP))
2 (SP)=(SP)+2
cpu执行令retf指令时,进行下面四步操作:
1 (IP) = ((SS)*16+(SP))
2 (SP)=(SP)+2
3 (CS)=((SS)*16+(SP))
4 (SP)=(SP)+2
总结可得:
cpu执行ret指令时,实际上是相当于 pop IP
cpu执行retf指令时,实际上相当于 pop IP, pop CS
call指令:
1将当前的IP或CS和IP压入栈中
2转移
call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相同,
依据位移进行转移的call指令
call 标号(将当前的IP压栈后,转到标号处执行指令)
cpu执行此格式的call指令时,进行如下操作
1 (sp)=(sp)+2
((ss)*16+(sp))=(IP)
2 (IP)=(IP)+16位位移
cpu执行 call 标号指令,实际上是:push IP, jmp near ptr 标号
转移的目的地址在指令中的call指令
call far ptr 标号 实现的是段间转移
cpu执行此格式的call指令时,进行如下操作
1 (sp)=(sp)-2
((ss)*16+(sp))=(CS)
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
2 (CS) = 标号所在段的段地址
(IP) = 标号在段中的偏移地址
cpu执行 call 标号指令,实际上是:push CS, push IP, jmp far ptr 标号
转移地址在寄存器中的call指令
call 16位寄存器
cpu执行此格式的call指令时,进行如下操作
1 (sp)=(sp)-2
2 ((ss)*16+(sp)) = (IP)
3 (IP) = (16位寄存器)
cpu执行 call 标号指令,实际上是:push IP, jmp 16位寄存器
转移地址在内存中的call指令
此call指令有两种格式:
1 call word ptr 内存单元地址
cpu执行此指令时,相当于 push IP, jmp word ptr 内存单元地址
2 call dword ptr 内存单元地址
cpu执行此指令时,相当于 push CS, push IP, jmp dword ptr 内存单元地址
mul指令
1 两个相乘的数:如果是8位的, 一个默认放在AH中,一个放在8位寄存器中或者内存字节单元中;
如果是16位的,一个默认放在AX中,一个放在16位寄存器中或者内存字单元中
2 相乘的结果:如果是8位的,结果默认放在AX中,
如果是16位的,结果高位默认放在DX中,地位默认在AX中存放