接下来我们要介绍的是有关汇编语言里面的转移指令,其实对于转移指令我们已经接触过了,那就是之前用来改变CS地址的 jmp 指令,还有循环指令 loop ,其实都属于转移指令,但是之前我们并没有详细介绍原理,所以我们接下来就详细介绍一下他们的原理,并且介绍一些其他的转移指令,帮助我们的程序更加的优美与饱满,好啦,就让我们开始进入今天的学习内容吧!
一般情况下指令是顺序地逐条执行的,而在实际中,经常需要改变程序的执行流程,所以这个时候,转移指令就显得十分重要了。
转移指令,可以控制CPU执行内存中某处代码的指令;也可以修改IP,或同时修改CS和IP的指令。
转移指令可以按照转移行为、转移距离和转移指令去分类,我们就来看看是如何进行分类的吧!
按照转移行为去分类,大致可以分为:
按照转移距离去分类,大概可以分为:
按照转移指令去分类,大概可以分为:
这个操作符offset,主要的功能就是取得标号的偏移地址,我们举个例子。
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指令的话,我们之前简单介绍过,接下来,我们来详细的介绍一下这个指令。
无条件转移,可以只修改IP,也可以同时修改CS和IP。但是呢,我们使用jmp指令的话,需要给出两种信息:第一就是转移的目的地址,其次就是转移的距离,具体分为以下三种:
为了我们讲解关于jmp指令的原理,我们举一个例子来讲解,这样应该比较好理解一点。
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,也就是下一条指令的地址。所以我们说,这个机器码,其实不是地址,而是位移。
我们再来仔细看一下这段代码的执行过程:
远转移:jmp far ptr 标号,实现的是段间转移。far ptr指明了跳转到的目的地址,即包含了标号的段地址CS和偏移地址IP。也就是说,远转移指令的机器码是包含了CS和IP的。
段内转移主要分为两种,一个是短转移,一个就是近转移,接下来我们来介绍一下。
短转移:“jmp short标号”;功能:(IP)=(IP)+8位位移
近转移:指令“jmp near ptr 标号”;功能:(IP)=(IP)+16位位移
这个其实很好理解,比如8位的位移,但是位移距离却是16位的,就会出现这种情况,这种情况是会报错的,程序也无法运行,所以我们选用指令的 时候需要注意。
上面的都是转移地址为标号的情况,接下来我们来介绍一下其他的几种情况。
指令格式:jmp 16位寄存器,这个和标号是类似的,就不再详细介绍了。
也是分为段内转移和段间转移,我们来一一介绍。
jmp word ptr 内存单元地址,就是从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
jmp dword ptr 内存单元地址,就是从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
指令格式:jcxz标号,简而言之,就是如果cx寄存器为0,就跳转。所以我们说jcxz是有条件转移指令。
如果(cx)=0,则转移到标号处执行,当(cx)≠0时,什么也不做(程序向下执行)
当(cx)=0时,(IP)=(IP)+8位位移)
这个之前介绍过了,就简单介绍一下。指令格式:loop 标号
如果(cx)≠0,(IP)=(IP)+8位位移
算出。
这个之前介绍过了,就简单介绍一下。指令格式:loop 标号
如果(cx)≠0,(IP)=(IP)+8位位移
加油,冲冲冲!!!!!!!!!