转移指令的原理
可以修改IP,或同时修改CS和IP的指令通称为转移指令。
8086CPU的转义行为有一下几类。
只修改IP时,称为段内转移,比如:
jmp ax
。同时修改CS和IP时,称为段间转移,比如:
jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移。
短转移IP的修改范围为-128~127。
近转移的IP的修改范围为-32768~32767。
8086CPU的转移指令分为以下几类。
无条件转移指令(如:jmp)
条件转移指令
循环指令(如:loop)
过程
中断
这些转移指令的区别在于前提条件不同,但转移的原理是相同的。
我们在这里通过深入学习无条件转移指令jmp
来理解CPU执行转移指令的基本原理
操作符offset
offset
的功能是取的标号的偏移地址,该指令由编译器执行。
jmp指令
jmp
为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
jmp
指令需要给出两种信息:
转移的目的地址
转移的距离(段间转移、段内段转移、段内近转移)
根据位移进行转移的jmp
指令
jmp short 标号(转到标号处执行指令)
我们从一段汇编程序开始。
观察这段汇编指令对应的机器码,汇编指令中的[idata]立即数,不论是否是数据还是内存单元的偏移地址,都会在对应的机器指令中出现,CPU执行的机器指令,它必须要处理这些数据和地址。
注意jmp
指令一行,机器指令中不包含转移的目的地址。
多次测试可以发现,CPU执行jmp
指令的时候不需要转移的目的地址。
回忆CPU执行指令的过程。
从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
(IP)=(IP)+所读取指令的长度,指向下一条指令
执行指令,跳到第一步,重复这个过程
jmp
指令对应的机器码EB03
中的’03‘其实是转移的位移。
jmp short 标号
的功能为:(IP)=(IP)+8位移。
8位位移=标号处的地址-jmp指令后第一个字节的地址;
short 指明此处的位移长度
8位移范围为-128~127,用补码表示(计算机中没有加法,正数二进制取反加一得到负数的二进制)
8位位移在编译算出
类似的指令jmp near ptr 标号
,实现的是段内近转移,不过它的位移范围是-32768~32767。
这里简单介绍下这个位移范围如何得到,这和补码的含义有关,正数的补码就是其本省,负数的补码是在原码的基础上,符号位(第一位)不变,其余各位取反,最后+1,8位位移的范围只能11111111~01111111(-128~127),16位位移也类似。
转移的目的地址在指令中的jmp
指令
前面说的jmp far ptr 标号
指令,对应的机器码为”EA 0801 6C07”,这里我特意空格分隔开,方便观察。
“EA 0801 6C07”是在指令中的内存中的排列顺序,高地址“6C07”是转移的段地址:076C,低地址的“0801”是偏移地址”0108”
转移地址在寄存器中的jmp
指令
指令格式:jmp 16位 reg
,功能(IP)=(16位reg),这里不在详述。
转移地址在内存中的jmp
指令
jmp word ptr 内存单元地址
(段内转移)
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
内存单元地址可用寻址方式的任一格式给出。
jmp dword ptr 内存单元地址
(段间转移)
功能:从内存中单元地址处存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
jcxz
指令
jcxz指令为有条件转移指令