转移指令的原理

来源:互联网 发布:思迅软件合作社区 编辑:程序博客网 时间:2024/05/17 12:48
    可以修改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执行的时机器指令,他必须要处理这些数据或地址。

(http://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。
0 0
原创粉丝点击