转移指令

可以修改cs:ip或只修改ip的指令称为转移指令;
因为cpu将cs:ip指向的数据当做指令来执行,因此转移指令就是可以控制cpu执行内存中某处代码的指令;
 
转移的分类:
   1】 转移行为的分类:
        只修改ip的称为段内转移;例如:jmp ax
        同时修改cs:ip的称为段间转移;例如:jmp 1000:0
    2】转移指令对ip的修改范围不同,段内转移分为短转移和近转移
        短转移    ->修改ip范围为 -128~127;
        近转移    ->修改ip范围为 -32768~32767;
    3】转移指令的分类:
        无条件转移指令;例如jmp
        条件转移指令;
        循环指令;例如loop
        过程;
        中断;
        
1.伪指令offset
offset由编译器执行,作用是获取标号的偏移地址;
例如:
assume cs:code
code segment
    start:mov ax,offset start    ;相当于mov ax,0
    s:mov ax,offset s    ;相当于mov ax,3
code ends
end start
因为start是第一条指令的标号,其偏移地址为0;
s是第二条指令的标号,第一条指令有3个字节,因此第二条指令的偏移地址是3;
 
2.jmp指令
jmp为无条件转移指令,可以同时修改cs:ip,也可以只修改ip;
jmp指令需要两种信息:
    1】转移的目的地址
    2】转移的距离
 
1)根据位移进行转移的jmp指令
格式:
    jmp short 标号
 
这种格式实现的时段内转移;
对ip的修改范围是-128~127;
转移结束后cs:ip指向标号处的指令;
例如:下面的代码中 ax只会自增一次,跳过了 add ax,1;
start:mov ax,0
    jmp short s
    add ax,1
  s:inc ax
 
cpu在执行jmp指令时,并不需要转移的目的地址;
例如上面的程序转换成机器码:
其中jmp short s 对应的机器码为 EB03,作用是将ip增加3;
而不是跳转到标号“s”对应的偏移地址8;
 
分析指令jmp short s执行过程:
    1】cs:ip指向jmp short s的机器码 EB03;
    2】读取EB03指令到指令缓冲器;
    3】ip增加所读指令的长度,EB03的长度为2字节,因此ip=ip+2;
    4】cs:ip此时指向了指令 add ax,1;也就是下一条指令;
    5】指令EB03执行,ip的值增加3;此时ip=ip+2+3;cs:ip指向了inc ax,也就是标号“s”处的指令,因此add ax,1被跳过了;
 
通过分析可知:指令EB03并没有告诉cpu要转移的目的地址,而是告诉了cpu要转移的位移;
而这个位移是编译器根据汇编指令中的标号计算出来的;
转移位移的计算方法如图:
 
实际上,jmp short 标号 ,的功能是:(ip)=(ip)+8位位移;
short指明了此处的位移为8位;
8位位移范围为 -127~128;
8位位移由程序编译时算出;
例如:
jmp short s
 
类似的,jmp near ptr 标号,功能为:(ip)=(ip)+16位位移;
范围为 -32768~32767;
例如:
jmp near ptr s
 
 2)转移的目的地址在指令中的jmp指令
格式:
    jmp far ptr 标号
jmp far ptr 标号 ;实现的是段间转移,也叫远转移;
功能是:用标号处的cs和ip修改cs和ip的值;
 
例如:
start:mov ax,0
    jmp far ptr s
    dw 256 dup (0)
    add ax,1
    s:inc ax
编译后的机器码:
可以看到 jmp中同时指定了cs和ip,机器码中也包含了cs:ip的值;
 
3)转移的地址在寄存器中的jmp指令
指令格式:
    jmp 16位寄存器
功能:
    (ip)=(16位寄存器)
例如:
jmp ax
 
4)转移地址在内存中的jmp指令
有两种格式:
    1】jmp word ptr 内存单元地址(段内转移)
        功能:偏移地址(ip)=内存单元处字的值
        例如:下面的代码执行完后,ip的值为123h
mov ax,123h
mov [bx],ax
jmp word ptr [bx]
 
    2】jmp dword ptr 内存单元地址(段间转移)
        功能:内存地址处有两个字,高位字存放目标段地址,低位字存放目标偏移地址;
        例如:下面的代码执行完后,cs:ip的值为0:123
mov ax,123h
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
 
3.jcxz指令
jcxz是有条件转移指令;
所有有条件转移指令都是短转移;
对应的机器码中包含转移的位移,而不是地址;
对ip的修改为-128~127;
格式:
    jcxz 标号
jcxz s
操作:
    当寄存器cx的值为0,即(cx)=0时,转移到目标标号处;
    当(cx) != 0 时,什么都不做,程序向下执行;
功能相当于if((cx) == 0) jmp short 标号;
 
4.loop指令
loop指令是循环指令;
所有循环指令都是短转移;
格式:
    loop 标号
loop s
操作:
    (cx) = (cx)-1,如果(cx) != 0转移到标号处;
    如果(cx) = 0,什么都不做;
相当于(cx)--;if((cx) != 0) jmp short 标号;
 
5.根据位移进行转移的意义
例如:
    jmp short 标号
    jmp near 标号
    jcxz 标号
    loop 标号
这些转移指令都只包含了到目标地址ip的位移,而没包含具体目标地址;
作用:
    方便了程序在内存中的浮动装配;
比如说:如果loop s 包含的是标号s的地址,那么对程序段在内存中的偏移地址有了严格的限制;
因为s处的指令如果不在目标地址处,就可能因为找不到目标指令而出错;
而包含的是位移就不存在这种问题,无论s处的指令实际地址是多少,知道了偏移量就能正确找到s处;
 
6.编译器对转移位移超界的检测
比如:
    jmp short s 的转移范围是 -128~127;
    ip最多向后移动127个字节;
    如果转移范围超界,将会报错;
例如:下面的程序将报编译错误
start:jmp short s
    db 128 dup (0)
    s:mov ax,ffffh
 
7.debug专用指令
例如:直接给出目标地址的指令
  jmp 2000:1
这种指令只能在debug中使用;
如果在汇编源程序中使用将会报编译错误;
 
posted @ 2019-07-03 11:09  L丶银甲闪闪  阅读(502)  评论(0编辑  收藏  举报