zoukankan      html  css  js  c++  java
  • 转移指令

    转移指令

    修改IP,或者同时修改CS和IP的指令系统称为转移指令

    内转移

    只修改IP时,称为段内转移,比如:jmp ax

    段间转移

    同时修改CS和IP时,称为段间转移, 比如:jmp 1000:0

    短转移

    只修改IP的转移,范围为-128~127

    近转移

    只修改IP的转移,范围为:-32768~32767

    转移指令的分类

    • 无条件转移指令
    • 条件转移指令
    • 循环指令
    • 过程
    • 中断

    操作符offset

    取得标号的偏移地址

    例如:

    assume cs:codesg
    codesg segment
    	start:
    		mov ax, offset start
    	s:
    		mov ax, offset s
    codesg ends
    endstart
    

    nop

    机器码占用一个字节

    根据位移进行转移的jmp指令,short

    jmp short 标号(转到标号处执行指令) (IP) = (IP) - 8位位移

    • 8位位移=标号处的地址-jmp指令后的第一个字节的地址
    • short指明此处的位移为8位位移
    • 8位位移由编译程序在编译时算出

    jmp 标号的机器码可以手动算出来,比如下面的例子

    assume cs:codesg
    codesg segment
    	start:
    		mov ax, offset start
    	s:
    		mov ax, offset s
    		jmp short start  ; 对应的机器码就为 当前语句的IP地址 - start的IP地址,然后转换为补码
    codesg ends
    endstart
    

    jmp near ptr 标号

    它实现的是段内近转移

    1. 16位位移 = 标号处的地址-jmp指令后的第一个字节的地址
    2. near ptr指明此处的位移位16位位移,进行的是段内近转移
    3. 16位位移的范围为-32767~32767
    4. 16位位移由编译程序在编译时算出

    jmp short 标号jmp near ptr都是相对于当前IP的转移位移

    jmp far ptr 标号实现的是段间转移,又称为远转移

    • CS = 标号所在段的段地址
    • IP = 标号在段中的偏移地址
    • far ptr 指明了用标号的短地址和偏移地址修改CS和IP

    指令的地址在寄存器中jmp 16位reg

    jmp 16位reg

    功能:IP = 16位REG

    转移地址在内存中的指令jmp word ptr 地址|[bx|idata]

    从内存单元地址处开始存放着一个字,是转移的目的偏移地址

    例如:

    mov ax, 0123h
    mov ds:[0], ax
    jmp word ptr ds:[0]
    

    执行后IP= 0123h

    又比如

    mov ax, 0132h
    mov [bx], ax
    jmp word ptr [bx]
    

    执行后IP= 0123H

    jmp dwrod ptr内存单元地址(段间转移)

    功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。

    • CS = 内存单元地址 + 2
    • IP = 内存单元地址

    例如:

    mvo ax, 0123h
    mov ds:[0], ax
    mov word ptr ds:[2], 0
    jmp dword ptr ds:[0]
    

    执行后,CS = 0, IP= 0123H,CS:IP指向0000:0123

    又比如

    mov ax, 0123h
    mov [bx], ax
    mov word ptr [bx + 2], 0
    jmp dword ptr [bx]
    

    执行后:CS = 0, IP = 0123H, CS:IP指向:0000:0123

    条件转移指令 jcxz

    jcxz为有条件转移指令,所有的条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围为-128-127

    指令格式: jcxz 标号(如果(cx)=0,转移到标号处执行)

    操作:当(cx)=0时,(IP)=(IP) + 8 位位移

    8位位移=标号处的地址-jcxz指令后的第一个字节地址

    8位位移的范围为-128-127,用补码表示

    8位位移由编译程序在编译时算出

    jcxz 标号相当于

    if ((cx) == 0) jmp short 标号;
    

    例如:

    assume cs:code
    
    data segment
    	db 1, 1, 1, 0
    data ends
    code segment
    	start:
    		mov ax, data
    		mov ds, ax
    		mov bx, 0
    	s:
    		mov cx, [bx]
    		jcxz ok ; 判断cx是否为0
    		inc bx
    		jmp short s
    	ok:
    		mov dx, bx
    		mov ax, 4c00h
    		int 21h
    code ends
    
    end start
    

    loop指令

    loop指令为循环指令,所有的循环指令都是短转移, 在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围为:-128~127

    指令格式: loop 标号((cx) = (cx) - 1, 如果(cx)不等于0,则转移到标号处执行)

    指令相当于

    (cx)--
    if ((cx) != 0) jmp short 标号
    

    根据位移的指令

    1. jmp short 标号
    2. jmp near ptr 标号
    3. jcxz 标号
    4. loop 标号

    位移如果复制到其他地方执行,一定要考虑好距离,否则会发生乱跳的结果

    他们对IP的修改是根据转移目的地址和转移其实地址之间的位移来进行的。他们对应的机器码中不包含转移的目的地址,而包含的是目的地址的位移。这样设计,方便了程序段在内存中的浮动装配。

    CALL 和 RET 指令

    ret指令用栈中的数据,修改IP的内容,从而实现 近转移

    CPU执行RET指令的时候需要进行两步操作

    1. (IP)=((ss) * 16 + (SP))
    2. (sp) = (sp) + 2

    相当于执行

    POP IP

    retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移

    CPU在执行retf指令时,进项下面4步操作

    1. (IP) = ((SS) * 16 + (SP))
    2. (SP) = (SP) + 2
    3. (CS) = ((SS) *16 + (SP))
    4. (SP) = (SP) + 2

    相当于执行

    pop IP
    pop CS
    

    call 指令

    CPU执行call指令时,进行两部操作

    1. 将当前的IPCSIP压入栈中
    2. 转移

    注意:

    • call指令不能实现短转移
    • call和jmp指令的原理相同

    依据位移进行转移的call指令

    call 标号(将当前的IP压栈后,转到标号处执行指令)

    CPU执行此种格式的CALL指令时,进行如下操作

    1. (SP) = (SP) - 2
    2. ((SS) * 16 + (SP)) = (IP)
    3. (IP) = (IP) + 16位位移

    16位位移 = 标号处的地址 - call指令后的第一个字节的地址

    16位位移的范围为-32768~32767, 用补码表示

    16位位移由编译程序在编译时算出

    call 标号相当于执行

    push IP
    jmp near ptr 标号
    

    转移的目的地址在指令中的call指令

    语法

    call far ptr 标号

    CPU执行此种格式的call指令时,进行如下操作

    1. (SP) = (SP) - 2
    2. ((SS) * 16 + (SP)) = (CS)
    3. (SP) = (SP) - 2
    4. ((SS) * 16 + (SP)) = (IP)
    5. (CS) = 标号所在段的段地址
    6. (IP) = 标号在段中的偏移地址

    CPU执行call far ptr 标号时, 相当于进行

    1. PUSH CS
    2. PUSH IP
    3. jmp far ptr 标号

    转移地址在寄存器中的call指令

    指令格式:call 16位reg

    CPU执行此种格式的call指令时,进行如下操作

    1. (sp) = (sp) - 2
    2. ((ss) * 16 + (SP) = (IP))
    3. (IP) = (16位reg)

    相当于执行了

    push IP

    jmp 16位reg

    转移地址在内存中的call指令

    两种格式

    call word ptr 内存单元地址

    相当于执行

    push IP

    jmp word ptr 内存单元地址

    比如下面的指令:

    mov sp, 10h
    mov ax, 0123h
    mov ds:[0], ax
    call word ptr ds:[0]
    
    

    执行后,(IP) = 0123H, (SP) = 0EH

    call dword ptr 内存单元地址

    用汇编语法来解释此种格式的call指令,则:

    CPU执行call dword ptr 内存单元地址时相当于执行:

    1. push CS
    2. push IP
    3. jmp dword ptr 内存单元地址

    比如下面的指令

    mov sp, 10h
    mov ax, 0123h
    mov ds:[0], ax
    mov word ptr ds:[2], 0
    call dword ptr ds:[0]
    
    

    执行后,(CS) = 0, (IP) = 0123H, (SP) = 0CH

  • 相关阅读:
    JavaScript总结(一)
    序列化函数
    random与os,sys模块
    认识模块
    时间模块
    日志处理
    异常处理
    类的约束
    反射
    区分函数以及方法
  • 原文地址:https://www.cnblogs.com/songyaqi/p/11887938.html
Copyright © 2011-2022 走看看