(九)汇编语言——转义指令的原理

2023-01-09 14:35:55 浏览数 (1)

(九)汇编语言——转移指令的原理

文章目录

  • (九)汇编语言——转移指令的原理
    • 转移指令
      • 作用
      • 分类
        • 转移行为
        • 转移距离
        • 转移指令
    • 操作符offset
    • jmp指令
      • 功能
      • 原理
      • 段间转移
      • 段内转移
        • 短转移
          • 原理
        • 长转移
          • 原理
      • 位移越界
      • 转移地址
        • 寄存器
        • 内存
          • 段内转移
          • 段间转移
    • jcxz指令
      • 功能
    • loop指令
      • 功能
    • loop指令
      • 功能
    • 总结

接下来我们要介绍的是有关汇编语言里面的转移指令,其实对于转移指令我们已经接触过了,那就是之前用来改变CS地址的 jmp 指令,还有循环指令 loop ,其实都属于转移指令,但是之前我们并没有详细介绍原理,所以我们接下来就详细介绍一下他们的原理,并且介绍一些其他的转移指令,帮助我们的程序更加的优美与饱满,好啦,就让我们开始进入今天的学习内容吧!

转移指令

一般情况下指令是顺序地逐条执行的,而在实际中,经常需要改变程序的执行流程,所以这个时候,转移指令就显得十分重要了。

作用

转移指令,可以控制CPU执行内存中某处代码的指令;也可以修改IP,或同时修改CS和IP的指令。

分类

转移指令可以按照转移行为、转移距离和转移指令去分类,我们就来看看是如何进行分类的吧!

转移行为

按照转移行为去分类,大致可以分为:

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

按照转移距离去分类,大概可以分为:

  • 段内短转移:IP修改范围为 -128 ~ 127
  • 段内近转移:IP修改范围为 -32768 ~ 32767
转移指令

按照转移指令去分类,大概可以分为:

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

操作符offset

这个操作符offset,主要的功能就是取得标号的偏移地址,我们举个例子。

代码语言:javascript复制
assume cs:codeseg
codeseg segment
start: mov ax,offset start    ;相当于  mov ax,0
	s: mov ax,offset s        ;相当于  mov ax,3
codeseg ends
end start

jmp指令

jmp指令的话,我们之前简单介绍过,接下来,我们来详细的介绍一下这个指令。

功能

无条件转移,可以只修改IP,也可以同时修改CS和IP。但是呢,我们使用jmp指令的话,需要给出两种信息:第一就是转移的目的地址,其次就是转移的距离,具体分为以下三种:

  • 段间转移(远转移):jmp 2000:1000
  • 段内短转移:jmp short 标号;IP的修改范围为-128~127,8位的位移
  • 段内近转移:jmp near ptr 标号;IP的修改范围为-32768~32767,16位的位移

原理

为了我们讲解关于jmp指令的原理,我们举一个例子来讲解,这样应该比较好理解一点。

代码语言:javascript复制
assume cs:codesg
codesg segment 
start:mov ax,0
	  jmp short s
	  add ax,1
    s:inc ax

    mov ax,4c00h
    int 21h
codesg ends
end start

我们将这段代码放到debug里面去看一下,具体的机器指令。

我们可以看到,jmp的后面跟着的确实是0008,也就是s处的地址,但是机器指令却是EB03,我们主要就是研究一下这个机器指令。 EB03,主要就是03,它代表着什么含义呢?其实这个03的含义是:下一条指令加上03,我们看下一条指令的地址刚好是0005,加上03,刚好就是0008,也就是下一条指令的地址。所以我们说,这个机器码,其实不是地址,而是位移。

我们再来仔细看一下这段代码的执行过程:

  1. (IP)=0003,CS:IP指向EB03(jmp的机器码)
  2. 读取指令码EB03进入指令缓冲器;
  3. (IP)=(IP) 所读取指令的长度=(IP) 2=0005,CS:IP指向add ax,0001;
  4. CPU执行指令缓冲器中的指令EB03;
  5. 指令EB05执行后,(IP)=(IP) 03=0008H,CS:IP指向inc ax

段间转移

远转移:jmp far ptr 标号,实现的是段间转移。far ptr指明了跳转到的目的地址,即包含了标号的段地址CS和偏移地址IP。也就是说,远转移指令的机器码是包含了CS和IP的。

段内转移

段内转移主要分为两种,一个是短转移,一个就是近转移,接下来我们来介绍一下。

短转移

短转移:“jmp short标号”;功能:(IP)=(IP) 8位位移

原理

  1. 8位位移=“标号”处的地址 - jmp指令后的第一个字节的地址(也就是位移);
  2. short指明此处的位移为8位位移;
  3. 8位位移的范围为-128~127,用补码表示;
  4. 8位位移由编译程序在编译时算出。
长转移

近转移:指令“jmp near ptr 标号”;功能:(IP)=(IP) 16位位移

原理

  1. 16位位移=“标号”处的地址 - jmp指令后的第一个字节的地址也就是位移);
  2. near ptr指明此处的位移为16位位移,进行的是段内近转移;
  3. 16位位移的范围为-32769~32767,用补码表示;
  4. 16位位移由编译程序在编译时算出。

位移越界

这个其实很好理解,比如8位的位移,但是位移距离却是16位的,就会出现这种情况,这种情况是会报错的,程序也无法运行,所以我们选用指令的 时候需要注意。

转移地址

上面的都是转移地址为标号的情况,接下来我们来介绍一下其他的几种情况。

寄存器

指令格式:jmp 16位寄存器,这个和标号是类似的,就不再详细介绍了。

内存

也是分为段内转移和段间转移,我们来一一介绍。

段内转移

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

段间转移

jmp dword ptr 内存单元地址,就是从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。

jcxz指令

指令格式:jcxz标号,简而言之,就是如果cx寄存器为0,就跳转。所以我们说jcxz是有条件转移指令。

功能

如果(cx)=0,则转移到标号处执行,当(cx)≠0时,什么也不做(程序向下执行)

当(cx)=0时,(IP)=(IP) 8位位移)

  • 8位位移=“标号”处的地址 - jcxz指令后的第一个字节的地址;
  • 8位位移的范围为-128~127,用补码表示;
  • 8位位移由编译程序在编译时算出。

loop指令

这个之前介绍过了,就简单介绍一下。指令格式:loop 标号

功能

如果(cx)≠0,(IP)=(IP) 8位位移

  • 8位位移=“标号”处的地址-loop指令后的第一个字节的地址
  • 8位位移的范围为-128~127,用补码表示
  • 8位位移由编译程序在编译时算出

算出。

loop指令

这个之前介绍过了,就简单介绍一下。指令格式:loop 标号

功能

如果(cx)≠0,(IP)=(IP) 8位位移

  • 8位位移=“标号”处的地址-loop指令后的第一个字节的地址
  • 8位位移的范围为-128~127,用补码表示
  • 8位位移由编译程序在编译时算出

总结

加油,冲冲冲!!!!!!!!!

0 人点赞