可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括来讲,转移指令就是可以控制CPU执行内存中
某处代码的指令。
8086CPU的转移指令有以下几类。
(1)只修改IP时,称为段内转移,比如:jmp ax。
(2)同时修改CS和IP时,称为段间转移,比如:jmp 1000:0
由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移。
(1)短转移IP的修改范围为-128~127.
(2)近转移IP的修改范围为—32768~32767.
8086CPU的转移指令分为以下几类。
(1)无条件转移指令(如:jmp)
(2)条件转移指令。
(3)循环指令(如:loop)
(4)过程
(5)中断
jmp指令
jmp为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
jmp指令要求给出两种信息:
(1)转移的目的地址
(2)转移的距离(段间转移,段内短转移,短内近转移)
jmp short 标号
转到标号处执行指令,这种格式的jmp指令实现的时段内短转移,他对IP的修改范围为
—128~127,“short”标号说明指令进行的时短转移。
汇编指令中的idata(立即数),不论它是表示一个数据还是内存单元的偏移地址,都会在对应的机器指令
中出现,因为CPU执行的时机器指令,他必须要处理这些数据或地址。
(https://img-blog.csdn.net/20160611135522461)
由图中jmp 0008的机器码可知,cpu在执行jmp指令的时候并不需要转移的目的地址。实际上jmp在机器码
中并未给出转移的目的地址,而是给出了转移的位移。jmp 0008这条指令要使(IP)=0008H,而当前的(IP)
=0005H,而当前IP加0003H正好为目的地址。
ps:
为什么会说当前(IP)为0005H而不是0003H呢.
因为CPU执行指令的步骤如下
(1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲区。
(2)(IP)=(IP)+所读取指令的长度,从而指向下一条指令。
(3)执行指令。转到1,重复执行这个过程。
实际上我们是先增加了当前(IP)之后才执行指令,所以在执行指令时的当前(IP)是下一条指令的
开始处的(IP)。
实际上“jmp short 标号”的功能是:(IP)=(IP)+8位位移(8位位移=标号出地址-jmp指令后的第一个
字节的地址,这8位位移由编译程序在编译时算出)。
而“jmp near ptr标号”的功能为:(IP)=(IP)+16位位移(其它情况同上)。
前面两个均是段内转移,且对应的机器指令中并没有转移的目的地址,而是相对于当前IP的转移地址,
而“jmp far ptr 标号”实现的是段间转移,又称为远转移。far ptr指明了指令用标号的段地址和偏移地址修
改CS和IP。
eg:
assume cs:code
code segment
start:
mov ax,0
mov bx,0
jmp far ptr s ;CS:IP为0BBD:0006 机器指令为:EA0B01BD0B
db 256 dup (0)
s:
add ax,1 ;s对应的CS:IP为0BBD:010B
inc ax
code ends
end start
由上可之,段间转移会给出转移的目的地址,而不同段内转移给出的转移位移。
转移地址在寄存器中的jmp指令
指令格式:jmp 16位reg
功能:(IP)=(16位reg)
转移地址在内存中的jmp指令
(1)jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址开始存放着一个字,是转移的目的偏移地址(内存单元地址可用寻址的任意一
种格式给出)。
eg:
mov ax.0123H
mov [bx],ax
jmp word ptr [bx]
执行后,(IP)=0123H
(2)jmp dword ptr 内存单元地址(段间转移)
功能:
从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移
地址。
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)
eg:
mov ax,0123H
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
执行后,(CS)=0,(IP)=0123H,CS:IP指向0000:0123
汇编编译器(masm.exe)对jmp的相关处理
1.向前转移
编译器中有一个地址计数器(AC),编译器在编译过程中,每读到一个字节AC就加1。再向前转移时,
编译器可以在读到标号s后记下AC的值as,在读到jmp s后记下AC的值aj。编译器用as-aj算出位移disp。
(1)如果disp为[-128,127],则不管汇编指令是:
jmp s
jmp short s
jmp near ptr s
jmp far ptr s
中的哪一种,都将其转换为jmp short s对应的机器码(EB disp)。
(2)如果disp为[-32768,32767],则:
对于jmp short s将产生编译错误。
对于jmp s,jmp near ptr s将产生jmp near ptr s对应的机器码(E9 disp)。
对于jmp far ptr s将产生相应的编码,jmp far ptr s所对应的机器码格式为:
EA 偏移地址 段地址。
2.向后转移
在向后转移的情况下,编译器先读到jmp s指令。由于它还没有读到标号s,所以编译器此时还不能确
定标号s处的AC值。也就是说,编译器不能确定位移量disp的大小。
此时,编译器将jmp s指令都当作jmp short s来读取,记下jmp s指令的位置和AC的值aj,并作如下
处理:
对于jmp short s,编译器生成EB和1个nop指令(相当于预留一个字节的空间,存放8位的disp)。
对于jmp s和jmp near ptr s,编译器生成EB和2个nop指令(相当于预留两个字节的空间,存放16
位的disp)。
对于jmp far ptr s,编译器生成EB和4个nop指令(相当于预留4个字节的空间,存放16位的
disp)。
做完上述处理后,编译器继续运行,当向后读到标号s时,记下AC的值as,并计算出转移的位移量:
disp=as-aj。