汇编语言指令 jmp:jmp short、jmp near ptr、jmp far ptr

引言:

        在8086CPU中,可以修改IP(Instruction Pointer ,指令指针寄存器)或同时修改CS(Code Segment,代码段寄存器)和IP的指令称为转移指令,更通俗的说,转移指令就是控制CPU执行内存中某处代码的指令。jmp 指令就属于转移指令中其中的一员,而且是无条件转移的。

        为了更加清晰明了的解读汇编语言中的转移指令 jmp,我们还需要了解一下CPU执行指令的过程:

(1)从CS:IP指向的内存单元中读取指令,读取的指令放入CPU的指令缓冲区中;

(2)修改IP的值,(IP) = (IP) + 所读取到指令的指令的长度(以字节为单位),从而使IP指向下一条指令;

(3)执行指令缓冲区中的指令

(4)转到步骤(1),重复执行这个过程

1. 根据位移进行转移的 jmp 指令

        根据位移进行转移的 jmp 指令是段内转移指令,即只修改IP的转移指令,位移是相对于当前 IP 的转移位移,根据转移的位移范围,分为段内短转移(jmp short 标号)和段内近转移(jmp near ptr 标号)

1.1 jmp short 标号

        jmp short 标号是段内短转移指令,该汇编指令的功能是转到标号处执行指令,其对应的机器指令码由2个字节表示,低8位表示该指令是段内短转移指令,高8位表示位移,位移范围在 -128 ~ 127 之间,也就是向前转移时,最多越过128个字节,向后转移时最多越过127个字节。基本原理如下:

(1) short指明此处的位移为8位位移,8位位移用补码形式表示,位移范围在 -128 ~ 127 之间;

(2)(IP)=(IP)+8位位移(补码形式表示);

(3)8位位移由编译程序在编译时算出,8位位移 = 标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址(因为根据文章开头所描述的CPU执行指令的过程可以知道,CPU执行存储在指令缓冲区中的 jmp 指令前,IP已经指向 jmp 指令的下一条指令)。

;jmp short 标号     基本原理;1. short指明此处的位移为8位位移,8位位移用补码形式表示,位移范围在 -128 ~ 127 之间;2. (IP)=(IP)+8位位移(补码形式表示);3. 8位位移由编译程序在编译时算出,8位位移 = 标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址
assume cs:code
code segment
start:mov ax, 0       ;机器码:B80000,3字节jmp short s     ;机器码:EB03,2字节add ax, 2       ;机器码:050200, 3字节
s:  inc ax          ;机器码:40h,1字节mov ax, 4c00h   ;机器码:B8004C, 3字节int 21h         ;机器码:CD21, 2字节
code ends
end start

注意到红长方形框出来的机器指令了吧,汇编指令:jmp short s 被编译器预编译后生成:JMP     0008(jmp s标号指令所在的首地址),编译最后生成的机器指令为:03EB,低8位 EBh 代表的是jmp的段内短转移指令(参考8086CPU的对应的指令编码表可知),高8位 03h 就是要转移的位移。

(1)标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址 = 8位位移,

即 0008h - 0005h = 03h;

(2)明白:jmp short 标号 为什么叫段内短转移指令,转移的位移范围为:-128 ~ 127 了吧,因为该汇编指令对应的机器指令的低8位表示的就是段内短转移指令,而且只有一个字节(即8位)来表示位移信息,用补码的形式表示,能够表达的范围就是:-128 ~ 127。

补充知识点

原码:数据在计算机中的二进制表示形式,即用最高位存放符号,正数为0,负数为1。其余位表示值。例如,一个字节的十进制数,3 的原码:0000,0011。 一个字节的十进制数,-3 的原码:1000,0011。 

反码: 正数的反码就是它的原码;

         负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

例如,一个字节的十进制数,3 的反码:0000,0011。 一个字节的十进制数,-3 的反码:1111,1100。

补码:正数的补码就是它的原码;负数的补码 = 反码 + 1

例如,一个字节的十进制数,3 的补码:0000,0011。 一个字节的十进制数:-3 的补码:1111,1100 + 0000,0001 = 1111,1101。

1.2 jmp near ptr 标号

          jmp near ptr 标号是段内近转移指令,该汇编指令的功能是转到标号处执行指令,其对应的机器指令码由3个字节表示,低8位表示该指令是段内近转移指令,高16位表示位移,位移范围在 -32768 ~  32767 之间,也就是向前转移时,最多越过32768 个字节,向后转移时最多越过32767 个字节。其基本原理跟 jmp short 标号 的基本原理差不多:

(1) near ptr 指明此处的位移为16位位移,16位位移用补码形式表示,位移范围在 -32768 ~ 32767 之间;

(2)(IP)=(IP)+16位位移(补码形式表示);

(3)16位位移由编译程序在编译时算出,16位位移 = 标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址(因为根据文章开头所描述的CPU执行指令的过程可以知道,CPU执行存储在指令缓冲区中的 jmp 指令前,IP已经指向 jmp 指令的下一条指令)。

;jmp near ptr 标号   基本原理;1. near ptr 指明此处的位移为16位位移,16位位移用补码形式表示,位移范围在 -32768 ~ 32767 之间;2. (IP)=(IP)+16位位移(补码形式表示);3. 16位位移由编译程序在编译时算出,16位位移 = 标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址
assume cs:code
code segment
start:mov ax, 0       ;机器码:B80000,3字节jmp near ptr s  ;编译器预编译后变成:jmp s标号所在处的地址;编译后生成的机器码有3个字节为:低8位表示段内近转移指令,高16位为转移位移dw 100 dup (0)
s:  inc ax          ;机器码:40h,1字节mov ax, 4c00h   ;机器码:B8004C, 3字节int 21h         ;机器码:CD21, 2字节
code ends
end start

从上面红色圈出的部分细节,我们可以知道,汇编指令:jmp near ptr s 被编译器预编译后生成:JMP     00CE(jmp s标号指令所在的首地址),编译最后生成的机器指令为:00C8E9,低8位 E9h 代表的是jmp的段内近转移指令(参考8086CPU的对应的指令编码表可知),高16位 00C8h 就是要转移的位移。

(1)标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址 = 16位位移,

即 00CEh - 0006h = 00C8h;

(2)明白:jmp near ptr 标号 为什么叫段内近转移指令,转移的位移范围为:-32768 ~ 32767了吧,因为该汇编指令对应的机器指令的低8位表示的就是段内近转移指令,而且用2个字节(即16位)来表示位移信息,用补码的形式表示,能够表达的范围就是:-32768 ~ 32767。

可能好奇心比较强的你,会不会有个疑问,如果 jmp near ptr s 的转移范围在 -128 ~ 127 之间呢,答案是编译器会优化成段内短转移指令 jmp short s(2个字节),同时把多出来的一个高字节单元用 NOP 填充(因为jmp near ptr 标号其对应的机器指令码由3个字节表示,所以多出来的一个没用到的高字节单元用NOP指令填充)。注:NOP(no operation),汇编语言的字节填充指令,该指令占一个字节单元。

;jmp near ptr 标号   基本原理;1. near ptr 指明此处的位移为16位位移,16位位移用补码形式表示,位移范围在 -32768 ~ 32767 之间;2. (IP)=(IP)+16位位移(补码形式表示);3. 16位位移由编译程序在编译时算出,16位位移 = 标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址
assume cs:code
code segment
start:mov ax, 0       ;机器码:B80000,3字节jmp near ptr s  ;转移范围在 -128 ~ 127 之间,编译器会将该指令优化为:;jmp short s;NOPadd ax, 2       ;机器码:050200, 3字节
s:  inc ax          ;机器码:40h,1字节mov ax, 4c00h   ;机器码:B8004C, 3字节int 21h         ;机器码:CD21, 2字节
code ends
end start

(1)标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址 = 8位位移,

即 0009h - 0005h(即NOP指令的首地址) = 0004h;

(2)该汇编指令经过编译器生成的机器指令为:04EBh 和 1个字节填充指令NOP,即 90h 组成。

2. 根据目的地址进行转移的 jmp 指令

2.1 jmp far ptr 标号

        jmp far ptr 标号是段间转移指令(又称远转移指令),该汇编指令的功能是转到标号处执行指令,其对应的机器指令码由5个字节表示,低8位表示该指令是段间近转移指令,高16位表示段地址,中间16位表示偏移地址。其基本原理如下:

(1)far ptr 指明了该指令用标号的段地址和偏移地址修改CS和IP;

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

assume cs:code
code segment
start:mov ax, 0jmp far ptr s   ;转到标号s处执行指令dw 100 dup (0)  ;定义100个dw类型数据,其值为0,占200个字节
s:  inc axmov ax, 4c00hint 21h
code ends
end start

jmp far ptr s 被预编译成了 jmp 204D:00D0,最终生成的机器码为:204D00D0EA,低8位:EA是jmp的段间转移指令编码(参考8086CPU的对应的指令编码表可知),高16位:204D是标号s所在的段地址(CS = 204D),中间16位:00D0是标号S在所在段内的偏移地址(IP = 00D0)

现在有个疑问,如果 jmp far ptr s 的转移范围在 -128 ~ 127 之间呢,答案是编译器会优化成段内短转移指令 jmp short s(2个字节),同时把多出来的3个高字节单元用 NOP 填充(因为jmp far ptr 标号其对应的机器指令码由5个字节表示,所以多出来的3个没用到的高字节单元用NOP指令填充)。注:NOP(no operation),汇编语言的字节填充指令,该指令占一个字节单元。

assume cs:code
code segment
start:mov ax, 0jmp far ptr s   ;转到标号s处执行指令add ax, 2
s:  inc axmov ax, 4c00hint 21h
code ends
end start

(1)标号所在处的指令的首地址 - jmp指令所在处的下一条指令的首地址 = 8位位移,

即 000Bh - 0005h(即NOP指令的首地址) = 0006h;

(2)该汇编指令经过编译器生成的机器指令为:06EBh 和 3个字节填充指令NOP,即 90h 90h 90h 组成。

3.总结

1. jmp short 标号 是根据位移进行转移的段内短转移指令,只修改IP的值,其机器码有2个字节,低8位是用于表示jmp的段内短转移指令的指令编码,高8位是用补码形式表示的位移信息,转移的范围:-128 ~ 127

2. jmp near ptr 标号 是根据位移进行转移的段内近转移指令,只修改IP的值,其机器码有3个字节,低8位是用于表示jmp的段内近转移指令的指令编码,高16位是用补码形式表示的位移信息,转移的范围:-32768 ~ 32767

3. jmp far ptr 标号 是根据目的地址进行转移的段间转移指令(又称为远转移指令),可以同时修改CS和IP,其机器码有5个字节,低8位用于表示jmp的段间转移指令的指令编码,高16位用于表示转移的目的段地址CS,中间16位用于表示转移的偏移地址IP

所以,在实际开发过程中

1. 如果只段内转移(只修改IP)时

(1)相对于当前 IP 的转移位移在 -128 ~ 127 之间时,选择用段内短转移指令 jmp short 标号,CPU的执行效率是最高的。

(2)相对于当前 IP 的转移位移在 -32768 ~ 32767 之间时,选择用段内近转移指令 jmp near ptr 标号,CPU的执行效率是最高的。

2. 如果是段间转移(同时修改CS和IP)时,那就选择用段间转移指令(远转移)jmp far ptr 标号

参考文献

《汇编语言(第4版)》王爽

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399961.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React H5设置企业级v6版本路由的配置

路由配置是项目开发的必要一环,尤其是目前流行SPA,下面看看如何使用v6版本路由进行合理的H5路由配置 一、基本页面结构(目录根据开发要求建,下面仅用于展示配置路由) 二、具体文件实现 1. index.tsx import React f…

用python的manim库实现表格格式操作【table 下】

1.Table 是 Manim 中用于创建一个包含文本或其他 数学符号的表格的类 Table 是 Manim 中用于创建一个包含文本或其他 数学符号的表格的类它能够帮助你在场景中清晰地展示数据或信息。 参数解释 table: 一个二维数组或列表,表示表格中的内容。每个子列表代表表格的…

Spring Web MVC

1. Spring Web MVC Spring Web MVC是⼀个Web框架 1.1 MVC 举个例子理解: Controller相当于前台,接送请求,传给相关部门,部门派人处理,此时这就是Model MVC是一种思想,Spring进行了实现,称为Spring MVC Spring Boot是创建Spring MVC项目的一种方式而已 1.2 Spring MVC 而…

(第二十七天)

上午 核心:内核中的 ipvs , ipvsadm 1 、安装 ipvsadm [rootnat ~] # yum -y install ipvsadm 2 、配置规则 查看所有的规则,如果已经配置好规则,重启之后也就没有了 [rootnat ~] # ipvsadm -L -n 1 、配置 vip 网卡 &…

如何用Python进行数据可视化、科技图表绘制?

目录 写在前面 推荐图书 推荐理由 写在最后 写在前面 有了它,科技图表绘制、数据可视化真的毫无难度! 推荐图书 《Python数据可视化:科技图表绘制》(芯智)【摘要 书评 试读】- 京东图书 图书简介 《Python数据可视化:科技图表绘制》结…

生成式人工智能(大语言模型)上线备案材料

材料总体一览 生成式人工智能(大语言模型)上线备案,除申请表外还需要提交五份材料: 《生成式人工智能 (大语言模型)上线备案申请表》 《附件1:安全自评估报告》 《附件2:模型服务协议…

Python(TensorFlow)衍射光学层卷积算法模拟(英伟达GPU)

🎯要点 🎯衍射光学卷积算法模拟 | 🎯模拟或数字电子计算之前加入一层光学计算 | 🎯前馈卷积神经网络计算成像系统对输入图像进行分类 | 🎯相位掩模利用线性空间不变成像系统执行固有卷积 📜用例 Python非…

大语言模型与多模态大模型loss计算

文章目录 前言一、大语言模型loss计算1、loss计算代码解读2、构建模型输入内容与label标签3、input_ids与labels格式 二、多模态大模型loss计算方法1、多模态loss计算代码解读2、多模态输入内容2、大语言模型输入内容3、图像embending如何嵌入文本embeding 前言 如果看了我前面…

MySQL学习[4] ——MySQL锁

四、MySQL锁 4.1 MySQL有哪些锁? 4.1.1 全局锁 全局锁就是**对整个数据库实例加锁,主要用于全库逻辑备份**等场景。 flush tables with read lock # 加全局锁unlock tables # 解锁加上全局(读)锁后,整个数据库都…

css实现水滴效果图

效果图&#xff1a; <template><div style"width: 100%;height:500px;padding:20px;"><div class"water"></div></div> </template> <script> export default {data() {return {};},watch: {},created() {},me…

spring mvc工作流程

Spring MVC 是基于模型-视图-控制器&#xff08;MVC&#xff09;设计模式的 Web 框架&#xff0c;它简化了开发 Web 应用程序的流程。下面是 Spring MVC 的工作流程详细介绍&#xff1a; 客户端请求 --> DispatcherServlet --> HandlerMapping --> Controller --&…

Win10 创建新的桌面2,并实现桌面切换

1. Win10 创建新的桌面2 Win - Tab 2. Win10 桌面切换 Ctrl - Win - ←/→ 我们下期见&#xff0c;拜拜&#xff01;

【大模型从入门到精通14】openAI API 构建和评估大型语言模型(LLM)应用2

这里写目录标题 评估大型语言模型&#xff08;LLM&#xff09;输出的方法构建评估标准实施评估协议利用专家比较案例研究评估客户服务聊天机器人学术文本摘要高级评估技术 评估大型语言模型&#xff08;LLM&#xff09;输出的方法 评估大型语言模型&#xff08;LLM&#xff09…

开源免费的表单收集系统TDuck

TDuck&#xff08;填鸭表单&#xff09;是一款开源免费的表单收集系统&#xff0c;它基于Apache 2.0协议开源&#xff0c;用户可以随时下载源码&#xff0c;自由修改和定制&#xff0c;也可以参与到项目的贡献和反馈中。TDuck表单系统不仅支持私有化部署&#xff0c;还提供了丰…

快排/堆排/归并/冒泡/

常见的内排序算法 插入排序 直接插入排序 原理&#xff1a;相当于扑克牌变成有序&#xff0c;先拿第一张&#xff0c;把他调节成有序&#xff0c;再拿第二张&#xff0c;与第一张相比找到第二张的位置&#xff0c;再继续拿第三张&#xff0c;以此类推。 void InsertSort(in…

【C++二分查找 贪心】792. 匹配子序列的单词数

本文涉及的基础知识点 C二分查找 贪心 LeetCode792. 匹配子序列的单词数 给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。 字符串的 子序列 是从原始字符串中生成的新字符串&#xff0c;可以从中删去一些字符(可以是none)&#xff0c;而不改变其…

关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法

1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题&#xff1a; npm i npm run dev 由于是刚刚从gitlab新拉的前端代码&#xff0c;可能没有用命令install过类似于没有编译过&#xff0c;所以执行一下上面的命令 结果报错如下&#xff1a; F:\tbyf\qjyy\hip-manager-ui&…

密探 -- 渗透测试工具 v1.14 版

1.如何运行 在jdk8环境下&#xff08;在jdk8以上的高版本请参考常见问题1的处理方案&#xff09;运行以下语句运行: java -jar mitan-jar-with-dependencies.jar 若不想输入这么长太长语句&#xff0c;可以通过以下脚本的方式启动&#xff1a; Mac/Linux 环境下&#xff0c;…

计算机网络——HTTP协议详解(上)

一、HTTP协议简单介绍 1.1 什么是HTTP协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于在Web浏览器和Web服务器之间传输数据的应用层协议。它是一种无状态协议&#xff0c;即服务器不会保留与客户端的任何连接状态信息&#xff0c;每个请求都被视为一个独立的事务。…

Mysql-约束

概念&#xff1a; 约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a; 保存数据库中数据的正确&#xff0c;有效性和完整性。 分类&#xff1a; 注意事项&#xff1a;约束是作用在数据表中的字段上的&#xff0c;可以在创建表或修改表的时候…