爱了爱了,这篇寄存器讲的有点意思(二)

简介: 物理地址 我们大家都知道, CPU 访问内存时,需要知道访问内存的具体地址,内存单元是内存的基本单位,每一个内存单元在内存中都有唯一的地址,这个地址即是 物理地址。而 CPU 和内存之间的交互有三条总线,即数据总线、控制总线和地址总线。


物理地址

我们大家都知道, CPU 访问内存时,需要知道访问内存的具体地址,内存单元是内存的基本单位,每一个内存单元在内存中都有唯一的地址,这个地址即是 物理地址。而 CPU 和内存之间的交互有三条总线,即数据总线、控制总线和地址总线。


image.png


CPU 通过地址总线将物理地址送入存储器,那么 CPU 是如何形成的物理地址呢?这将是我们接下来的讨论重点。


现在,我们先来讨论一下和 8086 CPU 有关的结构问题。


cxuan 和你聊了这么久,你应该知道 8086 CPU 是 16 位的 CPU 了,那么,什么是 16 位的 CPU 呢?


你可能大致听过这个回答,16 位 CPU 指的是 CPU 一次能处理的数据是 16 位的,能回答这个问题代表你的底层还不错,但是不够全面,其实,16 位的 CPU 指的是


  • CPU 内部的运算器一次最多能处理 16 位的数据

运算器其实就是 ALU,运算控制单元,它是 CPU 内部的三大核心器件之一,主要负责数据的运算。


  • 寄存器的最大宽度为 16 位

这个寄存器的最大宽度值就是通用寄存器能处理的二进制数的最大位数


  • 寄存器和运算器之间的通路为 16 位

这个指的是寄存器和运算器之间的总线,一次能传输 16 位的数据


好了,现在你应该知道为什么叫做 16 位 CPU 了吧。

在你知道上面这个问题的答案之后,我们下面就来聊一聊如何计算物理地址。

8086 CPU 有 20 位地址总线,每一条总线都可以传输一位的地址,所以 8086 CPU 可以传送 20 位地址,也就是说,8086 CPU 可以达到 2^20 次幂的寻址能力,也就是 1MB。8086 CPU 又是 16 位的结构,从 8086 CPU 的结构看,它只能传输 16 位的地址,也就是 2^16 次幂也就是 64 KB,那么它如何达到 1MB 的寻址能力呢?


原来,8086 CPU 的内部采用两个 16 位地址合成的方式来传输一个 20 位的物理地址,如下图所示


image.png


叙述一下上图描述的过程


CPU 相关组件提供两个地址:段地址和偏移地址,这两个地址都是 16 位的,他们经由地址加法器变为 20 位的物理地址,这个地址即是输入输出控制电路传递给内存的物理地址,由此完成物理地址的转换。


地址加法器采用 「物理地址 = 段地址 * 16 + 偏移地址」 的方法用段地址和偏移地址合成物理地址。


下面是地址加法器的工作流程


image.png


其实段地址 * 16 ,就是左移 4 位。在上面的叙述中,物理地址 = 段地址 * 16 + 偏移地址,其实就是「基础地址 + 偏移地址 = 物理地址」 寻址模式的一种具体实现方案。基础地址其实就等于段地址 * 16。


你可能不太清楚 的概念,下面我们就来探讨一下。


什么是段

段这个概念经常出现在操作系统中,比如在内存管理中,操作系统会把不同的数据分成 来存储,比如 「代码段、数据段、bss 段、rodata 段」 等。


但是这些的划分并不是内存干的,cxuan 告诉你是谁干的,这其实是幕后 Boss CPU 搞的,内存当作了声讨的对象。


其实,内存没有进行分段,分段完全是由 CPU 搞的,上面聊过的通过基础地址 + 偏移地址 = 物理地址的方式给出内存单元的物理地址,使得我们可以分段管理 CPU。

如图所示


image.png


这是两个 16 KB 的程序分别被装载进内存的示意图,可以看到,这两个程序的段地址的大小都是 16380。

这里需要注意一点, 8086 CPU 段地址的计算方式是段地址 * 16,所以,16 位的寻址能力是 2^16 次方,所以一个段的长度是 64 KB。


段寄存器

cxuan 在上面只是简单为你介绍了一下段寄存器的概念,介绍的有些浅,而且介绍段寄存器不介绍段也有「不知庐山真面目」的感觉,现在为你详细的介绍一下,相信看完上面的段的概念之后,段寄存器也是手到擒来。


我们在合成物理地址的那张图提到了 相关部件 的概念,这个相关部件其实就是段寄存器,即 「CS、DS、SS、ES」 。8086 的 CPU 在访问内存时,由这四个寄存器提供内存单元的段地址。


CS 寄存器

要聊 CS 寄存器,那么 IP 寄存器是你绕不过去的曾经。CS 和 IP 都是 8086 CPU 非常重要的寄存器,它们指出了 CPU 当前需要读取指令的地址。


CS 的全称是 Code Segment,即代码寄存器;而 IP 的全称是 Instruction Pointer ,即指令指针。现在知道这两个为什么一起出现了吧!


在 8086 CPU 中,由 CS:IP 指向的内容当作指令执行。如下图所示


image.png


说明一下上图

在 CPU 内部,由 CS、IP 提供段地址,由加法器负责转换为物理地址,输入输出控制电路负责输入/输出数据,指令缓冲器负责缓冲指令,指令执行器负责执行指令。在内存中有一段连续存储的区域,区域内部存储的是机器码、外面是地址和汇编指令。


上面这幅图的段地址和偏移地址分别是 2000 和 0000,当这两个地址进入地址加法器后,会由地址加法器负责将这两个地址转换为物理地址


image.png


然后地址加法器负责将指令输送到输入输出控制电路中


image.png


输入输出控制电路将 20 位的地址总线送到内存中。


image.png


然后取出对应的数据,也就是 「B8、23、01」,图中的 B8、BB 都是操作数。


image.png


控制输入/输出电路会将 B8 23 01 送入指令缓存器中。


image.png


此时这个指令就已经具备执行条件,此时 IP 也就是指令指针会自动增加。我们上面说到 IP 其实就是从 Code Segment 也就是 CS 处偏移的地址,也就是偏移地址。它会知道下一个需要读取指令的地址,如下图所示


image.png


在这之后,指令执行执行取出的 B8 23 01 这条指令。


然后下面再把 2000 和 0003 送到地址加法器中再进行后续指令的读取。后面的指令读取过程和我们上面探讨的如出一辙,这里 cxuan 就不再赘述啦。


通过对上面的描述,我们能总结一下 8086 CPU 的工作过程

  • 段寄存器提供段地址和偏移地址给地址加法器
  • 由地址加法器计算出物理地址通过输入输出控制电路将物理地址送到内存中
  • 提取物理地址对应的指令,经由控制电路取回并送到指令缓存器中
  • IP 继续指向下一条指令的地址,同时指令执行器执行指令缓冲器中的指令
            </div>
目录
相关文章
|
3月前
汇编指令学习(寻址方式)
汇编指令学习(寻址方式)
20 0
|
3月前
|
Linux
DMA寄存器与代码结合文档笔记
DMA寄存器与代码结合文档笔记
38 0
|
3月前
|
存储 缓存 安全
内存系列学习(一):万字长文带你搞定MMU&TLB&TWU
内存系列学习(一):万字长文带你搞定MMU&TLB&TWU
78 0
|
6月前
|
Windows
[笔记] Windows内核课程:保护模式《二》段寄存器介绍
[笔记] Windows内核课程:保护模式《二》段寄存器介绍
|
7月前
|
存储 缓存 Linux
Linux内核分析与应用2-内存寻址
Linux内核分析与应用2-内存寻址
78 0
|
7月前
|
算法 Linux Shell
我能在不同空间下操作寄存器,快学起来!
我能在不同空间下操作寄存器,快学起来!
|
11月前
|
Windows
实验二用机器指令和汇编指令编程
实验二用机器指令和汇编指令编程
78 0
|
传感器 存储 人工智能
STM32第一章-寄存器你懂吗?
嵌入式系统是小型计算机的一个分支系统。平常用的PC,就属于功能比较专一的计算机,从核心的处理器来说,可以分成嵌入式微处理器和嵌入式微控制器,我们传统意义上的那种单片机,比如说像51、AVR还有按里面比较低配的一些,比如说像Cortex-M系列的这一类,我们都把它划分为微控制器,微处理器呢,就相对来说处理能力,运算能力要强一些,比如ARM9以上的系列和 Cortex-A以及以上系列。STM32属于一个微控制器,请大家牢牢记住微控制器这四个字。STM32自带了各种常用通信接口,比如USART、I2C、SPI等,可接非常多的传感器,可以控制很多的设备。现实生活中,我们接触到的很多电器产品都有STM3
456 0
 STM32第一章-寄存器你懂吗?
|
存储 数据处理 索引
爱了爱了,这篇寄存器讲的有点意思(一)
下面我们就来介绍一下关于寄存器的相关内容。我们知道,寄存器是 CPU 内部的构造,它主要用于信息的存储。除此之外,CPU 内部还有运算器,负责处理数据;控制器控制其他组件;外部总线连接 CPU 和各种部件,进行数据传输;内部总线负责 CPU 内部各种组件的数据处理。 那么对于我们所了解的汇编语言来说,我们的主要关注点就是 寄存器。
91 0
爱了爱了,这篇寄存器讲的有点意思(一)
|
存储 程序员
爱了爱了,这篇寄存器讲的有点意思(三)
什么是 Code Segment Code Segment 即代码段,它就是我们上面聊到就是 CS 寄存器中存储的基础地址,也就是段地址,段地址其本质上就是一组内存单元的地址,例如上面的 「mov ax,0123H 、mov bx, 0003H」。我们可以将长度为 N 的一组代码,存放在一组连续地址、其实地址为 16 的倍数的内存单元中,我们可以认为,这段内存就是用来存放代码的。
80 0
爱了爱了,这篇寄存器讲的有点意思(三)