【汇编语言】寄存器(CPU工作原理)(四)—— “段地址x16 + 偏移地址 = 物理地址”的本质含义以及段的概念和小结
【汇编语言】寄存器(CPU工作原理)(四)—— “段地址x16 + 偏移地址 = 物理地址”的本质含义以及段的概念和小结
前言
📌
汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。
本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。
文章主要内容:"段地址x16 + 偏移地址 = 物理地址"的本质含义以及段的概念
1. "段地址x16 + 偏移地址 = 物理地址"的本质含义
了解其本质含义有助于我们未来更加灵活地分析解决问题
“段地址x16+偏移地址=物理地址”的本质含义是:CPU在访问内存时,用一个基础地址(段地址x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
更一般地说,8086CPU的这种寻址功能是“基础地址+偏移地址=物理地址”寻址模式的一种具体实现方案。8086CPU中,段地址x16可看作是基础地址。
下面,我们用两个与CPU无关的例子做进一步的比喻说明。
🎈第一个比喻说明“基础地址+偏移地址=物理地址”的思想:
比如说,学校、体育馆、图书馆同在一条笔直的单行路上(参考下图),学校位于路的起点(从路的起点到学校距离是0米)。
你要去图书馆,问我那里的地址,我可以用两种方式告诉你图书馆的地址:
(1)从学校走 2826m 到图书馆。这 2826m可以认为是图书馆的物理地址。
(2)从学校走 2000m到体育馆,从体育馆再走826m 到图书馆。第一个距离 2000m,是相对于起点的基础地址,第二个距离826m是相对于基础地址的偏移地址(以基础地址为起点的地址)。
第(1)种方式是直接给出物理地址 2826m,而第(2)种方式是用基础地址和偏移地址相加来得到物理地址的。
🎈第二个比喻进一步说明“段地址x16+偏移地址=物理地址”的思想。
我们为上面的例子加一些限制条件,比如,只能通过纸条来互相通信,你问我图书馆的地址我只能将它写在纸上告诉你。显然,我必须有一张可以容纳4位数据的纸条,才能写下 2826 这个数据。
可不巧的是,我没有能容纳4位数据的纸条,仅有两张可以容纳3位数据的纸条。这样我只能以下面这种方式告诉你 2826 这个数据。
在第一张纸上写上 200(段地址),在第二张纸上写上826(偏移地址)。假设我们事前对这种情况又有过相关的约定:你得到这两张纸后,做这样的运算:200(段地址)x10+826(偏移地址)=2826(物理地址)。
8086CPU就是这样一个只能提供两张3位数据纸条的CPU。
2. 段的概念
“段地址”这个名称中包含着“段”的概念。这种说法可能对一些学习者产生了误导,使人误以为内存被划分成了一个一个的段,每一个段有一个段地址。如果我们在一开始形成了这种认识,将影响以后对汇编语言的深入理解和灵活应用。
其实,内存并没有分段,段的划分来自于CPU,由于8086CPU用“基础地址(段地址x16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。如下图所示,我们可以认为:
- 地址10000H~100FFH的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H。(大小指的是这个段的长度)
- 也可以认为地址10000H1007FH、10080H100FFH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,大小都为80H。(大小指的是这个段的长度)
以后,在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址x16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
有两点需要注意
- 段地址x16必然是16的倍数,所以一个段的起始地址也一定是16的倍数
- 偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。(因为一个段是通过“基础地址(段地址x16)+偏移地址=物理地址”来寻找地址的,所以当一个段的起始地址由段地址确定后,大小也就是范围就会由偏移地址的寻址能力决定)
3. 内存单元地址小结
CPU访问内存单元时,必须向内存提供内存单元的物理地址。8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址。
那么现在请你思考下面的两个问题:
(1)观察下面的地址,你有什么发现?
✍结论:CPU可以用不同的段地址和偏移地址形成同一个物理地址。
比如 CPU 要访问 21F60H 单元,则它给出的段地址 SA 和偏移地址 EA 满足 SAX16+EA=21F60H 即可。
(2)如果给定一个段地址,仅通过变化偏移地址来进行寻址,最多可以定位多少内存单元?
✍结论:偏移地址16位,变化范围为0~FFFFH,仅用偏移地址来寻址最多可寻64K个内存单元。
比如:给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH。
补充:
在8086PC机中,存储单元的地址用两个元素来描述,即段地址和偏移地址。
“数据在 21F60H内存单元中。”这句话对于8086PC机一般不这样讲,取而代之的是两种类似的说法:
-
数据存在内存2000:1F60单元中
-
数据存在内存的2000H段中的1F60H单元中
这两种描述都表示“数据在内存21F60H单元中”
可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
结语
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。
也可以点点关注,避免以后找不到我哦!
Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)