汇编语言之转移指令和原理

简介: 汇编语言之转移指令和原理

1、引言

可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括地讲,转移指令就是可以控制CPU执行内存


中某处代码的指令。


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


1. 同时修改CS和IP时,称为段间转移,比如:jmp 100:2a7。


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


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


3. 段内短转移IP的修改范围为-128~127。


4. 段内近转移IP的修改范围为-32768~32767。


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


1. 无条件转移指令(比如:jmp)


2. 条件转移指令


3. 循环指令


4. 过程


5. 中断


这些转移指令转移的前提条件可能不同,但转移的基本原理是相同的,我们在这一章主要通过深入学习无条件


转移指令jmp来理解CPU执行转移指令的基本原理。


2、 jmp指令

Jmp为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。


Jmp指令要给出两种信息:


1. 转移的目的地址。


2. 转移的距离(段间转移、段内短转移、段内近转移)。


不同的给出目的地址的方法,和不同的转移位置,对应有不同格式的jmp指令,下面的几节内容中,我们以


给出目的地址的不同方法为主线,讲解jmp指令的主要应用格式和CPU执行转移指令的基本原理。


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

Jmp short 标号(转到标号处执行指令)。


这种格式的jmp指令,实现的是段内短转移,它对IP的修改范围为-128~127,也就是说,它向前转移时可以


最多越过128个字节,向后转移可以最多越过127个字节。Jmp指令中的“short”符号,说明指令进行的是短


转移,jmp指令中的“标号”是代码段中的标号,指明了指令要转移的目的地,转移指令执行结束后,CS:IP应该


指向标号处的指令。


请看下面一段代码:


Mov ax, 0


Jmp short s


Add ax, 1


 S:add ax, 2


最下面那条指令中的S就是标号,jmp short s指令执行后,CS:IP指向s:add ax, 2,上面那条指令add ax,


1已被跳过,没有被CPU执行。


在“jmp short 标号”指令所对应的机器码中,不包含转移的目的地址,而包含的是转移的位移,这个位移是


编译器根据汇编指令中的“标号”计算出来的,具体的计算方法如下图所示:


上图中,标号处的指令s0:inc bx的偏移地址为6,指令jmp s0后的第一个字节的偏移地址为3,位移量就是


6-3=3。


标号处的指令s:inc ax的偏移地址为0,指令jmp s下的第一个字节的偏移地址为9,位移量就是0-9=﹣9。


“Jmp short 标号”的功能为:IP=IP+8位位移:


1.8位位移=标号处的地址-jmp指令后的第一个字节的地址。


2.short指明此处的位移为8位位移。


3.8位位移的范围为﹣128~127,用补码表示(本教程不讲解补码,若你想了解,请看相关书籍)。


4.8位位移由编译程序在编译时算出。


还有一种和“jmp short 标号”功能相近的指令格式:“jmp near ptr 标号”,它实现的是段内近转移。


“jmp near ptr 标号”的功能为:IP=IP+16位位移。


1.16位位移=标号处的地址-jmp指令后的第一个字节的地址。


2.near ptr指明此处的位移为16位位移,进行的是段内近转移。


3.16位位移的范围为﹣32768~32767,用补码表示。


4.16位位移由编译程序在编译时算出。


11.png

11.png

上图中,标号处的指令s0:inc bx的偏移地址为6,指令jmp s0后的第一个字节的偏移地址为3,位移量就是

6-3=3。

标号处的指令s:inc ax的偏移地址为0,指令jmp s下的第一个字节的偏移地址为9,位移量就是0-9=﹣9。

“Jmp short 标号”的功能为:IP=IP+8位位移:

1.8位位移=标号处的地址-jmp指令后的第一个字节的地址。

2.short指明此处的位移为8位位移。

3.8位位移的范围为﹣128~127,用补码表示(本教程不讲解补码,若你想了解,请看相关书籍)。

4.8位位移由编译程序在编译时算出。

还有一种和“jmp short 标号”功能相近的指令格式:“jmp near ptr 标号”,它实现的是段内近转移。

“jmp near ptr 标号”的功能为:IP=IP+16位位移。

1.16位位移=标号处的地址-jmp指令后的第一个字节的地址。

2.near ptr指明此处的位移为16位位移,进行的是段内近转移。

3.16位位移的范围为﹣32768~32767,用补码表示。

4.16位位移由编译程序在编译时算出。


4、 转移地址在指令中或寄存器中的jmp指令

“Jmp far ptr 标号”实现的是段间转移(又称为远转移),功能如下:

CS=标号所在段的段地址,IP=标号在段中的偏移地址;

“Far ptr”指明了指令用标号的段地址和偏移地址修改CS和IP。

在“jmp far ptr 标号”指令所对应的机器码中,包含转移目的地的地址。

转移的目的地在寄存器中的jmp指令,指令格式为:

Jmp 16位通用寄存器。

功能:IP=16位通用寄存器

这种指令我们在前面的内容(参见2.6节)中已经讲过,这里就不再详述。


5、转移地址在内存中的jmp指令

转移地址在内存中的jmp指令有两种格式:

1. “jmp word ptr 内存单元地址”(段内转移)。

功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。内存单元地址可用寻址方式的任一格式

给出,比如,下面的指令:

Mov ax, 123H

Mov DS:[200], ax

Jmp word ptr DS:[200]

执行后,IP=123H

又比如,下面的指令:

Mov ax, 123H

Mov [bx], ax

Jmp word ptr [bx]

执行后,IP=123H

2. “jmp dword ptr 内存单元地址”(段间转移)。

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

偏移地址。

CS=内存单元地址+2

IP=内存单元地址

内存单元地址可用寻址方式的任一格式给出。比如,下面的指令:

Mov ax, 123H

Mov DS:[200], ax

Mov word ptr DS:[202], 100

Jmp dword ptr DS:[200]

执行后,CS=100H,IP=123H,CS:IP指向100:123。

又比如,下面的指令:

Mov ax, 123H

Mov [bx], ax

Mov word ptr [bx+2], 100

Jmp dword ptr [bx]

执行后,CS=100H,IP=123H,CS:IP指向100:123。

在上面的指令中,我们接触到了一个新的符号“dword”,它表示什么意思呢?前面我们已学过,Byte表示字

节,word表示字,dword则表示双字。


6 、CALL指令

Call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP,它们经常被共同用来实现子程序的设

计。这两节,我们讲解call和ret指令的原理。

CPU执行call指令时,进行两步操作:1.将当前的IP或CS和IP压入栈中。2.转移。

Call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相同,下面我们以给出转

移目的地址的不同方法为主线,讲解call指令的主要应用格式。

1. 依据位移进行转移的call指令。

Call 标号(将当前的IP压入栈后,转到标号处执行指令)。指令执行时,它的功能相当于:

Push IP

Jmp near ptr 标号

2. 转移地址在指令中的call指令。

Call far ptr 标号(实现的是段间转移)。

指令执行时,它的功能相当于:

Push CS

Push IP

Jmp far ptr 标号

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

指令格式:call 16位通用寄存器

指令执行时,它的功能相当于:

Push IP

Jmp 16位通用寄存器

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

这种call指令有两种格式:

格式1:call word ptr 内存单元地址

指令执行时,它的功能相当于:

Push IP

Jmp word ptr 内存单元地址

格式2:call dword ptr 内存单元地址

指令执行时,它的功能相当于:

Push CS

Push IP

Jmp dword ptr内存单元地址


7、 子程序

Ret指令用栈中的数据修改IP的数值,从而实现近转移。Ret指令执行时,进行下面两步操作:

1. IP=(SS×16+SP)中的数据

2. SP=SP+2

指令执行时,它的功能相当于:pop IP

学习了call和ret指令,现在来看一下,如何将它们配合使用来实现子程序的机制。请看下面的一段代码:

Mov ax, 1

Mov cx, 3

Call s

Mov bx, ax

Mov ax, 4c00H

Int 21H

S:add ax,ax

  Loop s

  Ret

  我们来分析一下CPU执行这一段代码的过程。

1. CPU执行第一、第二条指令后,CS:IP指向call s。

2. CPU将call s指令的机器码读入,IP指向call s后的指令mov bx, ax。

3. 执行call s指令,将当前IP值(指令mov bx, ax的偏移地址)压入栈中,并将IP的值改变为标号s处的

偏移地址。

4. CPU从标号s处执行指令,直至loop指令循环完毕。

5. CPU指向并执行ret指令,从栈中弹出一个数据(即先前压入栈中的指令mov bx, ax的偏移地址)送入

IP,则CS:IP指向指令mov bx, ax。

6. CPU执行指令mov bx, ax,并向下继续执行,直到执行int 21H后,程序结束。

上面第3、第5项是重点,它揭示了子程序执行完之后,如何让CPU接着call指令向下执行。什么是子程序?

具有一定功能的程序段,我们称之为子程序。比如,上面的那一段代码,s:add ax, bx到ret那3条指令就是一个

简单的子程序,它的功能是把ax中的数值累加3次,累加次数放在cx中,用循环指令loop实现累加。

在需要的时候,我们用call指令转去执行它,执行完子程序后,要让CPU接着call指令向下执行,则需要用

到ret指令,call指令转去执行子程序之前,call指令后面的指令的地址将被存储在栈中,在子程序的后面使用ret

指令,用栈中的数据设置IP的值,从而转到call指令后面的代码处继续执行。

   在上面那一段代码中,int 21H和loop这两条指令可能你看不懂,不过没关系,不影响讨论call和ret指令。

 

相关文章
|
3月前
汇编指令学习(寻址方式)
汇编指令学习(寻址方式)
20 0
|
3月前
汇编指令学习(LOOP)
汇编指令学习(LOOP)
14 0
|
3月前
汇编指令学习(CALL,JMP,RET)
汇编指令学习(CALL,JMP,RET)
26 0
|
3月前
|
JavaScript
汇编指令学习(JMP、JE、JS、JP,JO,JB)
汇编指令学习(JMP、JE、JS、JP,JO,JB)
76 0
|
3月前
汇编指令学习(CMP,TEST)
汇编指令学习(CMP,TEST)
22 0
|
3月前
汇编指令学习(AND,OR,XOR,NOT)
汇编指令学习(AND,OR,XOR,NOT)
37 0
|
3月前
汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
24 0
|
3月前
汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)
汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)
30 0
|
8月前
|
程序员
汇编基础语法和指令总结+案例(用32位汇编实现插入排序)
汇编基础语法和指令总结+案例(用32位汇编实现插入排序)
104 0
|
3月前
|
存储
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间