百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

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

liebian365 2024-10-18 09:34 30 浏览 0 评论

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的变化。

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.3.3 段寄存器的引用

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

堆栈段段值存储在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的段值相同,即都属于同一个段。

练习

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

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

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

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

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

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: