[从零学习汇编语言] -寄存器详解

文章目录

  • 前言
  • 一、 存储器与通用寄存器
    • 1. 存储器
    • 2. 寄存器
      • 2.1 通用寄存器
      • 2.2 字在寄存器中的存储
  • 二、地址寄存器
    • 1. 物理地址
      • 1.1 地址寄存器
      • 1.2 8086CPU给出物理地址的方法
      • 1.3 地址加法器与地址
      • 1.4 段寄存器
    • 2. 指令与指令寄存器
      • 2.1 CS和IP
  • 结语

前言

上一章我们曾简单的介绍过计算机中的一些硬件和软件的相关概念,还不熟悉的小伙伴可以点击下面的链接进行预习:

[汇编语言] - 汇编语言基础知识梳理

这里推荐一个学习汇编必须的工具DOSBOX
链接:https://pan.baidu.com/s/1hQr9fYXffE6cVLwh26HFUA
提取码:xlzb

一、 存储器与通用寄存器

1. 存储器

每一天清晨,当我们在梦中醒来的时候,记忆就会填充大脑的空白,我们会想起最近做过的一些重要的事情,当然也有些小的事情无法准确的记忆起,但这并不影响我们能够重新组织新一天的生活,保持生活的连续性。当然由于我们不能过于信赖我们的记忆,所以我们发明了书写,前一天的事情我们可以通过记录日志的形式记录在纸上,这样不管多久,只要书本不被丢失,我们便不会忘掉。计算机和人脑很像,计算机也需要一个硬件结构帮他记录他都做过什么和要做什么,这个结构被我们称为存储器。存储器单元实际上是时序逻辑电路的一种。

时序逻辑电路:
时序逻辑电路是数字电路的一种,简单的形容他的特性就是这种电路逻辑的输出信号并不取决于此刻电路输入的信号值,而是电路原来的状态,想要详细了解的同学可以看下面这个视频:
https://www.bilibili.com/video/BV1EW411u7th?p=6

其实存储器按照使用类型可以分为只读存储器(ROM)和随机存取存储器(RAM)。

首先我们来了解下ROM:
ROM被我们称为只读存储器是由于其早期是不允许被写入修改的,但是显然随着硬件的发展,它已经不是严格的不可写入了。ROM主要记录的是一些计算机必需的指令集,这就相当于我们人类出生就拥有的一些生物本能,比如吃饭,哭喊等等。当然ROM的数据并不会随着计算机的断电而消失。
与之相对的就是RAM:
RAM(随机存取存储器)就是我们平时使用的常说的内存,它的任意存储单元都可能被随机存取,且存取时间和存储单元的物理位置无关。RAM就相当于计算机的记忆,存放到其中的是一些电信号,一旦计算机断电存放在RAM中的数据就会消失。

当然计算机也有类似于日记本的结构,比如磁盘空间,光盘,U盘等等,这些都被我们称为外存,CPU不会直接的去访问存储在外存中的数据,通常都是将其加载进内存中再去获取。

2. 寄存器

2.1 通用寄存器

有些时候我们即使是不久前才发生的事情,可能在需要用到这部分记忆的时候也需要想很久,而此时此刻正在发生的事情却不会有这样的问题。计算机也会遇到这个问题,很多之前执行过的指令结果被我们存入了RAM中,但是如果此时还在进行需要这个结果的运算,CPU就需要再次通过总线连接RAM进行读取,这无疑增加了CPU进行指令运算的时间,为了解决这个问题,CPU在其内部引入了可以保存少量实时数据的硬件架构:寄存器。

寄存器的功能就是存储二进制的数据,这些数据也包括指令数据在内,寄存器的目的就是为了暂时的存放参与运算的数据和结果。

在不同的CPU中,寄存器的个数,种类也都不太相同。比如8086的CPU有14个寄存器,其所有寄存器都是16位的。

16位寄存器是指该寄存器中可以存放2个字节的数据,即2byte,16bit数据。

而在这些寄存器中:AX,BX,CX,DX这四个寄存器通常用来存放一些一般性数据(无特殊含义的数据),所以也被叫做通用寄存器。

我们打开dosbox输入以下命令:
debug 回车
t 回车
可以看到以下界面:
在这里插入图片描述
在这里我们看到了刚刚提到的四个寄存器,此时四个寄存器右侧保存的数据均为0000。

这里需要注意下,之前提到AX等通用寄存器均为十六位寄存器, 这里显示的AX=0000 是由于DOSBOX默认将二进制数转化为十六进制展示

我们可以输入一些简单的汇编指令进行操作:
mov ax,06(指令含义:将06的值存入ax寄存器中)
观察效果
[从零学习汇编语言] -寄存器详解_第1张图片
这里我们看到已经可以为AX寄存器成功赋值了,同理BX,CX,DX寄存器也可以类推操作。

小扩展:
AX的16位寄存器是由两个八位寄存器构成的,分别是AH和AL,这里我们可以重新看下效果:
[从零学习汇编语言] -寄存器详解_第2张图片
此时AX寄存器的值位0000
然后我们为AH寄存器赋值:
[从零学习汇编语言] -寄存器详解_第3张图片
然后再为AL寄存器赋值:
[从零学习汇编语言] -寄存器详解_第4张图片
可以观察到可以通过分别控制两个8位寄存器来改变AX寄存器中的值。

2.2 字在寄存器中的存储

出于对不同数据的兼容性考虑,8086的CPU可以一次性处理两种尺寸的数据:

  1. 字节: 记为byte,由8个bit组成,可以直接存放到8位寄存器中。
  2. 字: 记为word,一个字由两个字节促成,这两个字节分别称为这个字的高位字节和低位字节。如图所示:

[从零学习汇编语言] -寄存器详解_第5张图片
我们可以直接把一个字存放进16位的CPU中,这个字的高位字节和低位字节自然就存在这个寄存器的高8位和低8位寄存器中。
[从零学习汇编语言] -寄存器详解_第6张图片
上图中一个字型数据:20000,存放在AX寄存器中,其中AX寄存器又可以拆分为高八位和低八位。AH表示高八位,AL表示第八位。AH和AL组成一起表示20000,拆分开又可以分别表示78和32。

二、地址寄存器

1. 物理地址

还记得我们之前有提到的内存单元吗?如果忘记了没关系,我们现在宏观的角度看一下一个简单的RAM结构:
[从零学习汇编语言] -寄存器详解_第7张图片
我们之前有提过到存储器是由很多存储单元构成,而存储单元的编号是由0依次累加。每一个存储单元在空间中都有唯一的地址值。当CPU想要访问内存单元的时候,就需要给出对应存储单元的地址才可以。那么当CPU执行一条指令时是如何完成这个过程的呢?
[从零学习汇编语言] -寄存器详解_第8张图片
我们可以参考上图做一个简单的了解,当CPU想要执行一条指令的时候首先需要将指令存放进指令寄存器(暂时了解即可,后续会讲) , 然后将指定的指令按照编译码表进行翻译后执行,如果此时的指令中需要用到数据,CPU就会按照给定的物理地址进行寻址,而这个寻址过程就是我们接下来要讲的内容。

1.1 地址寄存器

什么是地址寄存器? 地址寄存器是用来保存CPU当前所访问的内存单元的地址,之所以要保存是由于CPU和内存之间存在着操作速度上的差异,由于ALU运算速度远大于内存的读写操作,所以需要用地址寄存器将当前操作的内存地址值进行暂存,直到内存结束读写操作为止。

这里我们还是以8086 CPU举例,8086CPU8个16位的寄存器,其中:

  1. 4个通用数据寄存器: AX,BX,CX,DX
  2. 2个栈寄存器: SP,BP
  3. 2个变址寄存器: SI,DI

当然8086的CPU不止有这8个寄存器,还包含:

  1. 指令寄存器:IP
  2. 控制寄存器: FLAGS
  3. 4个段寄存器

在这里插入图片描述

1.2 8086CPU给出物理地址的方法

物理地址 是指内存单元在内存中的实际地址。这里有个问题就是物理地址的长度是由什么决定的?还记得我们之前在上一篇汇编语言基础中提到过的地址总线吗?CPU是通过其上面的地址总线的条数决定了其寻址能力,而对应的地址总线的条数就是内存物理地址表达的长度范围。以8086CPU举例:
[从零学习汇编语言] -寄存器详解_第9张图片
上图是百度百科上的CPU管脚图,我们可以看到8086CPU拥有20根用来寻址的地址总线,这代表着其寻址范围为:0 - 11111111111111111111 , 也就是其可以表达20位数字,但是问题来了,我们之前介绍过8086的地址寄存器是一个16位寄存器,那么我们该如何查找一个20位的物理地址呢?

1.3 地址加法器与地址

在上述背景下,CPU的设计人员提出了一个地址加法器的概念,其主要是指将CPU中地址寄存器 中存放的16位地址值通过某种算法进行处理而获取到20位的真实物理地址值。 而这个算法详细来说就是:

  1. 将20位的地址拆分为两条16位的地址值分别存放到CPU的寄存器中,这两条地址信息分别被称为段地址偏移地址
  2. 短地址和偏移地址通过内部总线送入地址加法器 中进行运算,合成一个20位的物理地址
  3. 合成规则为: 段地址 * 16 + 偏移地址

这里面 段地址 * 16 这个操作还有个更加常见的说法叫做左移四位。简单来讲就是16等于2的四次幂,段地址乘2的四次幂等于向左移动了四位。

这里面我们可以在提出一个具体的模型:

  1. 从你家到公司的距离是1000米
  2. 从你家到你最喜欢的早餐铺是200米

那么我们可以通过两种方式来表达你每天上班的方式:

  1. 从你家走1000米到公司,这1000米就是物理地址
  2. 从你家走200米到早餐铺,再从早餐普走800米到公司。这里的200米就是段地址,800米是偏移地址。

这里面有个概念:段地址 。什么是段地址?其实CPU中的存储器地址可以分为若干的逻辑段,每个逻辑段的起始地址可以被叫做段地址 。如果还是不懂的话我们可以思考之前提到过的段地址偏移地址 的出现是为了解决16位CPU表达20位数字的问题,那么这里就有个局限就是偏移地址段地址 所表达的最大值不允许超过16位,而最小值不允许小于0。而段地址实际表示的范围段就有偏移地址的取值决定。

1.4 段寄存器

前面说到的,CPU在访问内存时需要相关硬件提供段地址偏移地址 。那么在送入地址加法器合成物理地址前,806CPU是通过什么存放的段地址呢?
8086CPU中由4个专门用来存放段地址的寄存器,叫做段寄存器,分别是CS,DS,SS,ES。当我们需要访问内存时就有这四个寄存器提供内存单元的段地址。今天我们只需要关心其中的CS段寄存器即可。

2. 指令与指令寄存器

2.1 CS和IP

CS寄存器 我们刚刚有介绍过是一个段寄存器 ,其作用就是存放段地址,而IP寄存器 则是CPU中另一个关键的寄存器指令寄存器 ,从其名称上我们就可以简单的推断出其作用就是存放指令。 而我们在结合CPU获取数据的过程来做一个简单推断就是CPU如果想要获取一条指令就需要:
假设CS寄存器此时存放的数据内容为M,IP寄存器中的数据内容为N,那么此时CPU将会从内存M×16 +N的内存单元读取出一条数据作为指令执行。 我们可以参考《汇编语言》中的CPU执行指令原理图:
[从零学习汇编语言] -寄存器详解_第10张图片
执行流程:

  1. CPU从CS:IP所指向的内存单元读取指令,存放到指令缓存其中。
  2. IP = IP + 所读取的指令长度,从而指向下一条指令
  3. 执行指令缓存器中的内存指令。

比如:
[从零学习汇编语言] -寄存器详解_第11张图片
当然我们也可以人为的干涉这个过程,我们可以通过一些赋值指令直接改变IP的值从而改变其指令指向。

结语

好了,今天我们对CPU中常见的寄存器进行了简单的总结,有疑问的小伙伴欢迎评论区留言或者私信博主,博主会在第一时间为你解答。
码字不易,感到有收获的小伙伴记得要关注博主一键三连,不要当白嫖怪哦~
博主在这里祝大家可以在新的一年升职加薪,走上人生巅峰!

你可能感兴趣的:(汇编语言,单片机,汇编语言,CPU,寄存器)