解决做网站问题,WordPress公众号主题,本地搭载wordpress,北京网站开发招聘58#xfeff;#xfeff;1、引言
可以修改IP#xff0c;或同时修改CS和IP的指令统称为转移指令。概括地讲#xff0c;转移指令就是可以控制CPU执行内存
中某处代码的指令。
8086CPU的转移行为有以下几类#xff1a;
1. 同时修改CS和IP时#xff0c;称为段间转移#…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位移量就是
633。
标号处的指令s:inc ax的偏移地址为0指令jmp s下的第一个字节的偏移地址为9位移量就是099。
“Jmp short 标号”的功能为IPIP8位位移
1.8位位移标号处的地址jmp指令后的第一个字节的地址。
2.short指明此处的位移为8位位移。
3.8位位移的范围为128~127用补码表示本教程不讲解补码若你想了解请看相关书籍。
4.8位位移由编译程序在编译时算出。
还有一种和“jmp short 标号”功能相近的指令格式“jmp near ptr 标号”它实现的是段内近转移。
“jmp near ptr 标号”的功能为IPIP16位位移。
1.16位位移标号处的地址jmp指令后的第一个字节的地址。
2.near ptr指明此处的位移为16位位移进行的是段内近转移。
3.16位位移的范围为32768~32767用补码表示。
4.16位位移由编译程序在编译时算出。
上图中标号处的指令s0:inc bx的偏移地址为6指令jmp s0后的第一个字节的偏移地址为3位移量就是633。标号处的指令s:inc ax的偏移地址为0指令jmp s下的第一个字节的偏移地址为9位移量就是099。“Jmp short 标号”的功能为IPIP8位位移1.8位位移标号处的地址jmp指令后的第一个字节的地址。2.short指明此处的位移为8位位移。3.8位位移的范围为128~127用补码表示本教程不讲解补码若你想了解请看相关书籍。4.8位位移由编译程序在编译时算出。还有一种和“jmp short 标号”功能相近的指令格式“jmp near ptr 标号”它实现的是段内近转移。“jmp near ptr 标号”的功能为IPIP16位位移。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位通用寄存器。功能IP16位通用寄存器这种指令我们在前面的内容参见2.6节中已经讲过这里就不再详述。5、转移地址在内存中的jmp指令
转移地址在内存中的jmp指令有两种格式1. “jmp word ptr 内存单元地址”段内转移。功能从内存单元地址处开始存放着一个字是转移的目的偏移地址。内存单元地址可用寻址方式的任一格式给出比如下面的指令Mov ax, 123HMov DS:[200], axJmp word ptr DS:[200]执行后IP123H又比如下面的指令Mov ax, 123HMov [bx], axJmp word ptr [bx]执行后IP123H2. “jmp dword ptr 内存单元地址”段间转移。功能从内存单元地址处开始存放着两个字高地址处的字是转移的目的段地址低地址处的字是转移的目的偏移地址。CS内存单元地址2IP内存单元地址内存单元地址可用寻址方式的任一格式给出。比如下面的指令Mov ax, 123HMov DS:[200], axMov word ptr DS:[202], 100Jmp dword ptr DS:[200]执行后CS100HIP123HCS:IP指向100:123。又比如下面的指令Mov ax, 123HMov [bx], axMov word ptr [bx2], 100Jmp dword ptr [bx]执行后CS100HIP123HCS: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 IPJmp near ptr 标号2. 转移地址在指令中的call指令。Call far ptr 标号实现的是段间转移。指令执行时它的功能相当于Push CSPush IPJmp far ptr 标号3. 转移地址在寄存器中的call指令。指令格式call 16位通用寄存器指令执行时它的功能相当于Push IPJmp 16位通用寄存器4. 转移地址在内存中的call指令。这种call指令有两种格式格式1call word ptr 内存单元地址指令执行时它的功能相当于Push IPJmp word ptr 内存单元地址格式2call dword ptr 内存单元地址指令执行时它的功能相当于Push CSPush IPJmp dword ptr内存单元地址7、 子程序
Ret指令用栈中的数据修改IP的数值从而实现近转移。Ret指令执行时进行下面两步操作1. IPSS×16SP中的数据2. SPSP2指令执行时它的功能相当于pop IP学习了call和ret指令现在来看一下如何将它们配合使用来实现子程序的机制。请看下面的一段代码Mov ax, 1Mov cx, 3Call sMov bx, axMov ax, 4c00HInt 21HS:add ax,axLoop sRet我们来分析一下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指令。