【新书推荐】6.3节 指令指针寄存器

8086 CPU内部的指令指针寄存器IP是计算机自动运行程序的关键。指令指针寄存器IP自动指向下一条将要执行的指令。

         本节内容:使用指令指针寄存器读取和执行指令的工作原理和段寄存器的引用。

         ■指令指针: 8086CPU中的指令指针寄存器IP是16位寄存器。指令指针寄存器IP指向将要执行的指令在代码段中的偏移。只有使用控制指令才可以改变CS:IP的值,如JMP指令、JCC指令、CALL指令、RET指令、IRET指令等。

         ■读取、执行指令的工作原理:代码段内汇编指令的逻辑地址采用CS:IP表示,通过地址加法器将CS*16+IP转换为20位物理地址,然后在该物理内存地址处读取指令机器码。

段寄存器的引用:正常引用段寄存器时,使用段超越前缀,比如“DS:[SI]”中的DS表示数据段超越前缀,表示引用数据段DS中的SI偏移地址处存储的值。默认缺省段超越前缀存在两种情形。一是数据段寄存器DS缺省,偏移地址可以使用[BX]、[SI]、[DI]或其组合形式表示。二是堆栈段寄存器SS缺省,偏移地址只可以使用[BP]表示,[BP]等价于SS:[BP]。

6.3.1 指令指针

         当我们的操作系统将计算机可执行程序加载到计算机的内存中之后,IP指令指针寄存器自动指向该程序的入口地址(第一条指令的位置)。然后,按照程序中指令执行的流程和先后顺序,自动执行。

         ■指令编码规则

程序员在编写计算机的源程序时,按照计算机语言的指定编写规则编写源代码。编写程序时,通常按照数据和代码分开的原则编写。数据写在数据段,指令写在代码段。汇编源程序中编写的地址是逻辑地址。代码段的逻辑地址表示为CS:IP,由16位段值和16位偏移组成。当操作系统把编译后的可执行程序加载到计算机的内存中后,CPU读取的指令地址为源程序中编写的逻辑地址,CPU还需要将逻辑地址转换为物理地址后,才可以正确地读写物理内存中的指令或数据。

读取指令时,需要将指令的逻辑地址转换为物理地址:

8086物理地址=段值*16 +偏移。

代码段的逻辑地址: CS:IP。

代码段的物理地址 = CS*16 + IP。

下一条指令的地址=当前指令地址+当前指令机器码的字节数。

动手实验10:测试指令地址

如图6-12所示,在Debug调试器中输入命令a,输入下面三条语句,接着输入u命令,注意观察CS:IP的变化。

图6-12 指令地址

mov ax,1的硬编码为B80100,地址为073f:0100;

mov bx,2的硬编码为B80200,地址为073f:0103;

mov cx,3的硬编码为B90300,地址为073f:0106;

上述3条指令的硬编码都是3个字节,下一条指令的地址等于当前指令地址+3。

         ■指令指针

8086 CPU中的指令指针寄存器IP是16位寄存器。指令指针寄存器IP指向将要执行的指令在代码段中的偏移。实际上,除非发生转移,否则将要执行的指令会被预取到指令预取队列,然后再将一条指令分解为多条微指令,并将微指令提交CPU执行。关于指令队列和指令执行的具体流程,我们将在第三部分32位汇编的第二十八章80386处理器体系结构一章中详细讲解。

CS和IP是8086 CPU两个最关键的寄存器。任意时刻CPU都将CS:IP指向的内容当作指令执行。

6.3.2 读取、执行指令的工作原理

读取执行指令

如图6-13所示:

●8086 CPU当前状态:CS中的内容为2000H,IP中的内容为0000H;

●内存20000H~20009H单元存放着可执行的机器码;

●内存20000H~20009H单元存放的机器码对应的汇编指令如下:

地址:20000H~20002H,内容:B8 21 03,长度:3byte,对应汇编指令:mov ax,0321h。

地址:20003H~20005H,内容:BB 06 00,长度:3byte,对应汇编指令:mov bx,0006h。

地址:20006H~20007H,内容:89 D8,长度:2byte,对应汇编指令:mov ax,bx。

地址:20008H~20009H,内容:01 DB,长度:2byte,对应汇编指令:add ax,bx。

假设当前CPU提取的代码段逻辑地址为2000H:0H,由CPU内的地址加法器将此逻辑地址转换为物理地址20000H。地址总线加载物理地址20000H,该物理地址存储汇编指令“mov ax,0321H”对应的机器语言(也称为硬编码)“B8 21 03”,这条机器语言就是将要执行的指令。

图6-13 读取、执行指令的工作原理

6.3.3 段寄存器的引用

在代码段的指令代码中,如何引用段寄存器呢?如图6-14所示,8086 CPU内有4个16位的段寄存器CS、DS、SS、ES,分别用于存储代码段、数据段、堆栈段和附加段的段值。这些段是由程序员在编写16位汇编源程序时人为定义的逻辑段。逻辑段的段值在源程序中并不是指定的,而是使用符号表示,称为该逻辑段的段地址标号。

图6-14 段寄存器的引用

堆栈段段值存储在SS段寄存器中,堆栈段使用SP栈顶指针寄存器指向堆栈段的栈顶,BP寄存器作为堆栈段内的基址寄存器。

代码段段值存储在CS段寄存器中,代码段使用IP指令指针寄存器指向将要执行的指令。

数据段段值存储在DS段寄存器中,数据段使用BX、SI、DI、BP四个指针寄存器指向段内偏移,或者使用直接段内地址偏移。在使用内存数据拷贝(字符串指令)时,固定使用DS:[SI]指向源地址。

附加段段值存储在ES段寄存器中,附加段通常用于数据拷贝,在字符串指令中固定使用ES:[DI]指向目的地址。

举例

假设在一个源程序中引用了4个逻辑段,需要在源程序的开始位置做如下声明:

assume cs:code,ds:data,ss:stack,es:edata      

意思是假设“地址标号code”表示代码段,“地址标号data”表示数据段,“地址标号stack”表示堆栈段,“地址标号edata”表示附加段。

16位汇编语言源程序中段的定义如下:

assume cs:code,ds:data,ss:stack,es:edata

stack segment          ;堆栈段定义的起始位置

定义堆栈空间的大小

stack ends                  ;堆栈段到此结束

data segment            ;数据段定义的起始位置

数据段内的数据定义

data ends                   ;数据段到此结束

edata segment         ;附加段定义的起始位置

附加段内的数据定义

data ends                   ;附加段到此结束

code segment           ;代码段定义的起始位置

start:                           ;代码段内的地址标号

汇编指令代码…

code ends                  ;代码段到此结束

end start                    ;指定代码段的入口地址位于地址标号start处

在源程序中,根据实际需要定义一个或多个逻辑段,至少应包含一个代码段

下面分别介绍4个段寄存器的引用方法。

代码段

在汇编语言的源程序中,代码段内存储的是汇编指令代码。代码段的地址标号通常用“code”表示,也可以自定义。当我们编写16位汇编语言源程序时,并不需要真正给段寄存器赋值,只需要声明段地址标号就可以了。当操作系统将编译后的二进制可执行程序(.exe后缀的程序)加载到计算机内存中时,会根据当前计算机系统的配置,自动分配一个段值给段寄存器,替换源代码中的段地址标号。这样的好处是,不需要使用固定的段值,可以将同一个可执行程序加载到不同的计算机系统上运行。

当CPU通过CS:IP读取代码段内的指令时,会自动引用代码段寄存器CS,加上指令指针寄存器IP所给的16位代码段内偏移,得到指令的物理地址。

堆栈段

堆栈段是一个动态分配的内存空间。段寄存器SS存储堆栈段的段值。当涉及堆栈操作时,引用堆栈段SS段寄存器,加上SP栈顶指针寄存器给出的16位堆栈段内偏移,得到堆栈操作的物理地址。

注意

1.编写16位汇编程序时,我们可以自定义堆栈段(小于64KB),也可以使用DOS系统默认分配的64KB堆栈空间。

2.SP栈顶指针寄存器永远指向堆栈段的栈顶。

3.堆栈内的数据存储按照后进先出的原则进行。

4.8086计算机的堆栈空间每次固定分配2个字节空间,即按照16位对齐,不足16位,前面补0。

5.入栈操作时SP寄存器减2,出栈操作时,SP寄存器加2。例如:

push ax    ;将ax寄存器的值压入堆栈栈顶,SP-2

pop ax      ;将堆栈栈顶2个字节的值pop 到ax寄存器中,SP+2

6.BP寄存器是栈内基址指针寄存器,用于堆栈内的寻址。如果是BP寄存器计算偏移时,缺省引用段寄存器,默认为SS段。例如,汇编语句mov ax,[bp+2]是mov ax,ss:[bp+2]的简写形式。

我们将在第七章8086寻址方式第八章8086指令系统详细讲解堆栈内的寻址和堆栈操作指令。

         ■附加段

ES段寄存器存储附加段的段值。通常附加段用于数据拷贝。在16位汇编语言中,使用字符串指令时,ES:[DI]指向目的地址,目的数据字符串只可以使用ES段寄存器。我们将在第十七章字符串处理的章节中学习字符串指令。

注意

         字符串指令LODS、STOS、MOVS、SCANS、CMPS用于字符串的装载、存储、拷贝、扫描和比对。在16位汇编语言中,字符串是以ASCII码字符的形式存储在计算机内存中。对内存中字符串的操作,就是对ASCII数值的操作。因而字符串指令本质上就是内存数据拷贝。所以,我们说ES段寄存器“用于数据拷贝”和“用于字符串指令”的说法是一回事。

数据段

数据段的段值存储于DS段寄存器,用于存储程序所需的数据定义。16位汇编语言程序中,通常我们定义为data segment数据段。数据段作为全局段存在的,整个程序中的任一指令都可以直接引用。

源程序中的引用方法为DS:[SI],缺省DS段寄存器时,默认为DS段。如果一个程序不超过64KB,只需要在程序开始时分别给DS,SS赋值就可以了,程序的其他地方不需要再考虑这些段寄存器,如果程序超过64KB,就需要在两个或者多个段寄存器中存取数据,需要改变段寄存器的值。

段超越前缀:直接明确指定引用的段寄存器,可缺省。如DS:[SI]中,我们将“DS:”称为数据段超越前缀。

数据段和附加段的段内地址偏移可以使用SI、DI、BP、BX寄存器间接方式给出,或者直接给出段内偏移地址的数值,称为直接寻址方式。我们将在第七章8086寻址方式中详细讲解。

         ■段寄存器的引用规则

         表6-8给出了16位汇编语言中段引用的规则。可以分为三种情形:

正常使用段超越前缀

代码段必须使用CS段寄存器存储段值,源程序中使用CS:IP表示代码段内逻辑地址。

堆栈段必须使用SS段寄存器存储段值,源程序中使用SS:[BP] 或SS:[BP+立即数]表示堆栈段内逻辑地址。8086CPU指令集不支持SS:[SP]这样的指令。SP栈顶指针寄存器永远指向堆栈的栈顶。

附加段必须使用ES段寄存器存储段值,在字符串指令中,只能使用ES:[DI]表示附加段内的目的地址。

数据段使用DS段寄存器存储段值。在字符串指令中,只能使用DS:[SI]表示数据段内的目的地址。

缺省段超越前缀只有两种情形

1.数据段寄存器DS缺省,偏移地址可以使用[BX]、[SI]、[DI]或其组合形式表示。

2.是堆栈段寄存器SS缺省,偏移地址只可以使用[BP]表示,[BP]等价于SS:[BP]。

         ●段值相同

DS数据段和SS堆栈段可以与CS、ES的段值相同,即都属于同一个段。

访问存储器涉及的方式

正常使用的段寄存器

可选用的段寄存器

偏移

取指令

CS

IP

堆栈操作

SS

SP

一般数据存取(下来情况除外)

DS

CSESSS

有效地址

源数据串

DS

CSESSS

SI

目的数据串

ES

DI

BP作为指针寄存器使用

SS

CSDSES

有效地址

                                        表6-8 段寄存器的引用规定

练习

1、请举例说明何为段前缀超越。什么场合下要使用段前缀超越?

2、什么情况下,缺省的段寄存器是SS?为什么要这样安排?

3、如何实现数据段与代码段相同?

4、堆栈有哪些用途,请举例说明?

本文摘自编程达人系列教材《X86汇编语言基础教程》。

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

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

相关文章

Swin-UMamba:结合基于ImageNet的预训练和基于Mamba的UNet模型

摘要 https://arxiv.org/pdf/2402.03302v1.pdf 准确的医学图像分割需要整合从局部特征到全局依赖的多尺度信息。然而,现有方法在建模长距离全局信息方面面临挑战,其中卷积神经网络(CNNs)受限于其局部感受野,而视觉转换…

Golang 学习(二)进阶使用

二、进阶使用 性能提升——协程 GoRoutine go f();一个 Go 线程上,可以起多个协程(有独立的栈空间、共享程序堆空间、调度由用户控制)主线程是一个物理线程,直接作用在 cpu 上的。是重量级的,非常耗费 cpu 资源。协…

osg模型的平移、缩放、旋转

加载2个模型,其中一个向上移动28个单位; 加载2个模型,其中一个缩放0.5倍,向下移动22个单位; 加载2个模型,其中一个缩放0.5倍、旋转45度、向右向下移动几个单位; 都是用矩阵实现的; …

Python算法题集_环形链表II

Python算法题集_环形链表II 题142:环形链表II1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【集合检索】2) 改进版一【字典检测】3) 改进版二【双指针】 4. 最优算法 本文为Python算法题集之一的代码示例 题142:环形链…

计算机设计大赛 深度学习+python+opencv实现动物识别 - 图像识别

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 inception_v3网络5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 *…

AJ-Report 【开源的一个BI平台】

AJ-Report是全开源的一个BI平台,酷炫大屏展示,能随时随地掌控业务动态,让每个决策都有数据支撑。     多数据源支持,内置mysql、elasticsearch、kudu驱动,支持自定义数据集省去数据接口开发,目前已支持30…

【安卓跨程序共享数据,探究ContentProvider】

ContentProvider主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。 目前,使用ContentProvider是Android实现跨程序共享数据的标准方…

宠物空气净化器哪个牌子好?养猫家庭如何挑选宠物空气净化器?

养猫的朋友都知道,猫咪掉毛是一个令人头痛的问题。猫毛和皮屑会漂浮在空气中,不仅遍布全屋的各个角落,而且清理起来也非常麻烦,特别是那些难以清除的猫毛。更糟糕的是,这些猫毛还可能引发人们的过敏反应,如…

1896_Linux中free命令小结

1896_Linux中free命令小结 全部学习汇总: little_bits_of_linux: 一星半点的Linux经验 (gitee.com) 查看Linux中存储的使用情况,我经常使用htop,毕竟这个命令提供的信息是十分直观的。我现在常用的一个小主机其实是我的树莓派3B,虽…

怎么用postman调用webservice(反推SoapUI)

<soapenv:Envelope xmlns:soapenv“http://schemas.xmlsoap.org/soap/envelope/” xmlns:lis“LisDataTrasen”> soapenv:Header/ soapenv:Body lis:Test lis:test111111111</lis:test> </lis:Test> </soapenv:Body> </soapenv:Envelope> Conten…

部署VMwareWorkstation和ESXi

文章目录 一、VMware Workstation Pro下载和部署二、安装ESXi三、登录到ESXi四、使用ESXi安装虚拟机 一、VMware Workstation Pro下载和部署 在官网下载VMware Workstation Pro&#xff1a;https://vmware.com/cn.html 找到以下位置 选择试用 然后等待下载完成 正常下载完成…

牛客网SQL:查询每个日期新用户的次日留存率

官网链接&#xff1a; 牛客每个人最近的登录日期(五)_牛客题霸_牛客网牛客每天有很多人登录&#xff0c;请你统计一下牛客每个日期新用户的次日留存率。 有一个登录(login。题目来自【牛客题霸】https://www.nowcoder.com/practice/ea0c56cd700344b590182aad03cc61b8?tpId82 …

SQL,HQL刷题,尚硅谷

目录 相关表数据&#xff1a; 题目及思路解析&#xff1a; 汇总分析 1、查询编号为“02”的课程的总成绩 2、查询参加考试的学生个数 分组 1、查询各科成绩最高和最低的分&#xff0c;以如下的形式显示&#xff1a;课程号&#xff0c;最高分&#xff0c;最低分 2、查询每门课程…

板块一 Servlet编程:第一节 HTTP协议理论与服务器请求响应原理 来自【汤米尼克的JAVAEE全套教程专栏】

板块一 Servlet编程&#xff1a;第一节 HTTP协议理论与服务器请求响应原理 一、HTTP特点二、HTTP中的 URL三、两种 HTTP 请求方法&#xff1a;GET 和 POST四、请求响应的底层请求头在服务器中表现响应头在服务器中表现 在上一个板块中我们完成了所有IDEA的基础配置工作&#xf…

挑战杯 python+大数据校园卡数据分析

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度学习车牌识别系统实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&am…

【PTA选择题/基础夯实/期末复习】链表文件操作

2-1 对于一个头指针为head的带头结点的单链表&#xff0c;判定该表为空表的条件是&#xff08;&#xff09;。 A.headNULL B.head→nextNULL C.head→nexthead D.head!NULL 2-2 链表不具有的特点是&#xff08;&#xff09;。 A.可随机访问任一元素 B.插入、删除不需要移…

第 383 场 LeetCode 周赛题解

A 边界上的蚂蚁 模拟 class Solution { public:int returnToBoundaryCount(vector<int> &nums) {int s 0;int res 0;for (auto x: nums) {s x;if (s 0)res;}return res;} };B 将单词恢复初始状态所需的最短时间 I 枚举&#xff1a;若经过 i i i 秒后 w o r d w…

CTF-show WEB入门--web19

今晚web19也就顺便解决了 老样子我们先打开题目看看题目提示&#xff1a; 可以看到题目提示为&#xff1a; 密钥什么的&#xff0c;就不要放在前端了 然后我们打开题目链接&#xff1a; 然后我们查看网页源代码&#xff1a; 可以发现有用的内容全在网页源代码里。 前端验证…

spring boot(2.4.x之前版本)和spring cloud项目中配置文件的作用

为了防止理解问题&#xff0c;pom.xml 版本依赖如下 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!--…

(十三)springboot实战——springboot前后端分离方式项目集成spring securtity安全框架

前言 Spring Security 是一款强大且高度可定制的认证和访问控制框架&#xff0c;它是为了保护基于Spring的应用程序提供安全性支持。Spring Security提供了全面的安全服务&#xff0c;主要针对企业级应用程序的需求。其核心组件主要包含&#xff1a;Authentication&#xff08…