zoukankan      html  css  js  c++  java
  • 汇编学习笔记(6)转移指令原理

    这一章主要介绍了转移指令jmp的实现原理,个人感觉还是比较重要的一章,这一章就详细摘录书上的例题及练习,已达到巩固的效果。

    offset

    offset是由编译器执行的指令并没有对应的机器码。

    • 语法:offset 标号

    • 功能:获取标号的偏移地址

    书上的例子

     1 ;offset
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,offset start
     8 s:      mov ax,offset s
     9 
    10         mov ax,4c00h
    11         int 21h
    12  
    13 
    14 codesg ends
    15 end start

    可以看到,标号offset偏移地址为0它是第一条指令,标号s的偏移地址为3,这是因为mov ax,offset start占用了三个字节。

    jmp

    转移指令是指可以修改IP,或同时修改IP和CS的指令。

    • 段内转移:只修改IP的值,又分为短转移和近转移。短转移是值IP的修改范围在-128~127之间(内存单元的储值范围),近转移是指IP的修改范围在-32768~32767(寄存器的储值范围)之间。

    • 段间转移:同时修改CS和IP的值。

    jmp指令的格式(目前所学):

    1.jmp short 标号:段内短转移

    2.jmp near ptr 标号:段内近转移

    3.jmp far ptr 标号:段间转移

    4.jmp 寄存器:段内转移

    5.jmp word ptr 内存单元:段内转移

    6.jmp dword ptr 内存单元:段间转移

    jmp short 标号

    书上的例子

     1 ;jmp short 标号
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,0
     8         jmp short s
     9         add ax,2
    10 s:      inc ax
    11 
    12         mov ax,4c00h
    13         int 21h
    14  
    15 
    16 codesg ends
    17 end start

    从上图可以看出,jmp short s已被翻译成jmp 0008即jmp标号s的偏移地址,而对应的机器码为EB03。

    jmp short s执行时不需要目的地的地址,只需要应转移的位移即可,过程是这样的:

    1.(CS)=076AH,(IP)=0003H,CS:IP指向jmp short s(EB03)

    2.读取指令EB03至指令缓冲器,(ip)=(ip)+2(加2是因为jmp short s指令长度为2字节),(ip)=0005H

    3.执行指令EB03向后3个字节,(ip)=(ip)+3,(ip)=0008H

    这是向后转移的例子,我们再来做个向前转移的例子

     1 ;jmp short 标号
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,0
     8 s:      inc ax
     9         add ax,2
    10         jmp short s
    11 
    12         mov ax,4c00h
    13         int 21h
    14  
    15 codesg ends
    16 end start

    jmp short s这次过程是这样的:

    1.(CS)=076AH,(IP)=0007H,CS:IP指向jmp short s(EBFA)

    2.读取指令EBFA至指令缓冲器,(ip)=(ip)+2(加2是因为jmp short s指令长度为2字节),(ip)=0009H

    3.执行指令EBFA向前6个字节,(ip)=(ip)-6,(ip)=0003H

    EBFA表示向前6个字节由补码解释,6H=00000110B,取反+1为11111010B=FAH,有以上两个程序可知jmp指令的位移等于标号处的偏移地址-jmp指令的下一条指令的偏移地址,看上去挺绕的,减去下一条指令的地址是因为在CPU执行指令前先将ip加上jmp的指令长度,所以要减去jmp指令的长度。

    jmp short s只可以转移-128~127的范围那超出会怎样呢?试下就知道了

     1 ;jmp short 标号
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,0
     8         jmp short s
     9         db 128 dup(1)
    10 s:      inc ax
    11 
    12         mov ax,4c00h
    13         int 21h
    14  
    15 codesg ends
    16 end start

    很明显,编译时报错超出1字节

    jmp near ptr 标号

    jmp near ptr和jmp short 功能相似只不过范围变成了-32768~32767

    jmp far ptr 标号

    (CS)=标号所在段的段地址,(ip)=标号在段中的偏移地址

     1 ;jmp far ptr 标号
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,0
     8         jmp far ptr s
     9         db 128 dup(1)
    10 s:      inc ax
    11 
    12         mov ax,4c00h
    13         int 21h
    14  
    15 codesg ends
    16 end start

    机器码EA88006A07,其中低位8800偏移地址,高位6A07为段地址即(cs)=076AH,(IP)=0088H.

    jmp 寄存器

    8086COU是16位寄存器,所以jmp 寄存器所能转移的范围为-32768~32767,属于段内转移。

    jmp word ptr 内存单元

    word是字型数据占2个字节,所以能转移的范围为-32768~32767,属于段内转移,将内存单元开始的字型数据赋给IP。

    jmp dword ptr 内存单元

    dword是双字型数据占4个字节,所以高地址处的字型数据是段地址,低地址处的字型数据是偏移地址。

     1 ;jmp dword ptr
     2 
     3 assume cs:codesg
     4 
     5 codesg segment
     6     
     7 start:  mov ax,0123h
     8         mov ds:[0],ax
     9         mov bx,0
    10         mov ds:[2],bx
    11         jmp dword ptr ds:[0]
    12 
    13         mov ax,4c00h
    14         int 21h
    15  
    16 codesg ends
    17 end start

    jcxz

    jcxz 标号表示当cx等于0时转移到标号处执行。

    if((cx)==0)

      jmp short 标号

  • 相关阅读:
    设计模式_EventObject和EventListener
    设计模式_Observable与Observer
    zooKeeper_《ZooKeeper官方指南》一致性保障
    thread_为什么多线程是个坏主意
    gtk+学习笔记(三)
    linux c下输入密码不回显
    浮点数在计算机内存中的存储方式
    gtk+学习笔记(二)
    linux下c图形化编程之gtk+2.0简单学习
    关于字符串排序合并的问题
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023318.html
Copyright © 2011-2022 走看看