美文网首页
9.《汇编语言》-王爽第三版学习笔记 转移指令的原理

9.《汇编语言》-王爽第三版学习笔记 转移指令的原理

作者: Nonmfly | 来源:发表于2021-03-16 08:54 被阅读0次

    1.可以修改 IP, 或通知修改 CS 和 IP 的指令 统称为 转移指令。

    概括的讲,转移指令就是可以控制 CPU 执行内存中某处代码的指令。

    8086CPU 的转移行为有一下几类:

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

    由于转移指令对 IP 的修改范围不同,段内转移又分为: 短转移 和 近转移

    • 短转移 IP 的修改范围为 -128~127
    • 近转移 IP 的修改范围 -3287~32767

    8086CPU 的转移指令分为以下几类:

    • 无条件转移指令(如: jmp)
    • 条件转移指令
    • 循环指令(如:loop)
    • 过程
    • 中断

    2. 操作符 offset

    offset在汇编语言中是由编译器处理的符号。他的功能是 取得标号的偏移地址。

    // 将 start 处的第一条指令 复制到 s0处:
    assume cs:codesg
    codesg segment
    start: mov ax,bx 
             mov si,offset start  // 相当于 mov si,0
             mov di,offset s0  // 相当于 mov di, s0代码段的首地址
             mov ax,cs:[si] 
             mov cs:[di],ax
       s0: nop       // nop的机器码占一个字节
             nop
    
           mov ax,4c00H
           int 21H
    codesg ends
    end start
    

    3. jmp 指令

    jmp 指令 为 无条件转移指令,可以只修改 IP,也可以同时修改 CS 和 IP。需要给出两种信息:
    (1)转移的目的地址
    (2)转移的距离(段间转移,段内短转移,段内近转移)

    3. 依据位移进行转移的 jmp 指令

    jmp short 标号 (转移到标号处执行指令)
    这种格式的 jmp 指令实现的是 段内短转移,它对 IP 的修改范围为 -128~127,也就是说,它向前转移时最多越过 128 个字节,向后转移可以最多越过 127 个字节。
    jmp指令中的"标号" 是 代码段中的标号, 指明了指令要转移的目的地,转移指令结束后, CS:IP 应该指向标号处的指令。

    9B6875FF-4A69-419B-9720-5577A42FED9B.png

    CPU在执行 jmp 指令的时候并不需要转移的目的地址。
    ”jmp short 标号“ 指令所对应的机器码中,并不包含转移目的地的地址,而是包含转移的位移。这个位移 是编译器根据汇编指令中的 ”标号“ 计算出来的。

    413F34DB-4766-4814-A820-4C86EEDEC68E.png
    • 实际上 ”jmp short 标号“ 的功能为: (IP) = (IP)+8位位移
      (1) 8位位移 = 标号处的地址 - jump 指令后第一个字节的地址
      (2)short 指明此处的位移位 8位位移
      (3)8位位移的范围为 -128~127,用补码表示。
      (4)8位位移由编译程序在编译时算出。

    • 实际上 ”jmp near ptr 标号“ 的功能为: (IP) = (IP)+16位位移
      (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址
      (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。
      (3)16位位移的范围为 -32768~32787,用补码表示。
      (4)16位位移由编译程序在编译时算出。

    • 实际上 ”jmp far ptr 标号“ 的功能为: 段间转移,又称远转移
      far ptr 指明了用 标号的段地址 和 偏移地址 修改 CS 和 IP。
      (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址
      (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。
      (3)16位位移的范围为 -32768~32787,用补码表示。
      (4)16位位移由编译程序在编译时算出。


      F220E338-FF2C-4744-95DF-5CF4769EA72E.png
    • ”jump16位 reg“ 的功能为: (IP)=(16位reg)
      far ptr 指明了用 标号的段地址 和 偏移地址 修改 CS 和 IP。
      (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址
      (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。
      (3)16位位移的范围为 -32768~32787,用补码表示。

    • ”jmp word ptr 内存单元地址“ 的功能为: 段内转移
      从内存单元地址处开始存放着一个字,是转移的目的偏移地址。

    • ”jmp dword ptr 内存单元地址“ 的功能为: 段间转移
      从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址, 低地址出是转移的目的偏移地址。
      (CS)= (内存单元地址+2)
      (IP)=(内存单元地址)

    4. 练习

    1.若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据?
    
    assume ds:data,cs:code
    data segment
        db 2 dup (0)
    data ends
    code segment
    start: mov ax,data
           mov ds,ax
           mov bx,0
           jmp word ptr [bx+1]
           mov ax,4c00h
           int 21h
    code ends
    end start
    
    2.补全程序,使得jmp指令执行后,CS:IP指向第一条指令
    
    assume ds:data,cs:code
    data segment
        dd 12345678H
    data ends
    code segment
    start: mov ax,data
           mov ds,ax
           mov bx,0
           mov [bx],bx
           mov [bx+2],code
           jmp dword ptr ds:[0]
           mov ax,4c00h
           int 21h
    code ends
    end start
    
    3.;内存数据如下
    2000:1000 BE 00 06 00 00 00 ……
    此时CPU执行指令
    mov ax, 2000H
    mov es, ax
    jmp dword ptr es:[1000H]
     
    后,(CS) = 0006H (IP) = 00BEH
    

    5. jcxz 指令

    指令格式: jcxz 标号 (如果 (cx)=0, 转移到标号处执行)
    (1)操作: 当(cx)= 0 时,(IP)=(IP)+ 8位位移
    (2)8位位移=标号处的地址-jcxz指令后的第一个字节的地址
    (3)8位位移的范围为 -128~127,用补码表示
    (4)8位位移由编译程序在编译时算出。

    • 当 (cx)!= 0 时,什么也不做,程序继续执行
    • jcxz 标号 = if (cx) == 0 jump short 标号

    6. 练习

    补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

    assume cs:code
    
    code segment
    
    start: mov ax,2000H
           mov ds,ax
           mov bx,0
    
        s: mov cl,[bx]
           mov ch,0
           jcxz ok
           inc bx
           jmp short s
    
       ok: mov dx,bx
           mov ax,4c00h
           int 21h
    
    code ends
    
    end start
    

    7. loop 指令

    指令格式:loop 标号
    操作:
    (1)(cx)= (cx)+ 1
    (2)如果(cx)!= 0, (IP)=(IP)+8 位位移

    8. 练习

    补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

    assume cs:code
    
    code segment
    
    start: mov ax,2000H
           mov ds,ax
           mov bx,0
    
        s: mov cl,[bx]
           mov ch,0
           inc cx
           inc bx
           loop s
    
       ok: dec bx
           mov dx,bx
           mov ax,4c00h
           int 21h
    
    code ends
    
    end start
    

    9. 根据位移进行转移的意义

    jmp short 标号
    jmp near ptr 标号
    jcxz 标号
    loop 标号
    他们对IP的修改是根据 转移目的地址和转移起始地址之间的位移来进行。在它们对应的机器码中不包含转移的目的地址,而包含的是目的地之的位移。方便了程序段在内存中的浮动装备,无论目的地址如何变化,指令的转移位移是不变的。

    相关文章

      网友评论

          本文标题:9.《汇编语言》-王爽第三版学习笔记 转移指令的原理

          本文链接:https://www.haomeiwen.com/subject/ccdmfltx.html