CPU、RAM与外设寄存器

目录

三者本质区别

[内存映射 I/O(MMIO)](#内存映射 I/O(MMIO))

外设寄存器读写不对称

小结


三者本质区别

CPU 是整个系统的运算中枢,负责做加减、逻辑判断、跳转。 CPU 芯片内部自带少量通用寄存器,数量很少,速度极快,就在 CPU 内部,用来临时存放正在计算的数据;通用寄存器没有地址,不能通过内存地址直接访问,只能汇编指令读写。

RAM(内存) 独立的存储芯片,CPU 通过地址总线访问。 程序变量、栈、堆都放在 RAM 中;读写速度慢于 CPU 寄存器,远快于外设;断电数据全部丢失。每一个字节都有独立内存地址。

外设寄存器 属于外设硬件(GPIO、DMA、串口等),不在 CPU 内部,也不属于 RAM。 单片机里外设寄存器被映射成内存地址,CPU 像读写内存一样读写这个地址,以此控制硬件。

💡颜色标注:

  • CPU 通用寄存器:CPU 芯片内部
  • RAM:内存芯片
  • 外设寄存器:各个外设芯片内部

表格

部件 位置 是否有内存地址 断电保留数据 速度
CPU 通用寄存器 CPU 内部 ❌没有 ❌丢失 最快
RAM 内存 内存芯片 ✅有 ❌丢失 中等
外设寄存器 外设硬件 ✅地址映射 视硬件而定 最慢

问题

  1. CPU 通用寄存器存放在 RAM 里面吗?
  2. 我们 C 语言普通局部变量存储在哪?
  3. 单片机读写外设硬件,CPU 是通过什么方式访问外设寄存器?

:

1.不是

2.RAM

3.寻址

:

批改:

  1. ✅不是。通用寄存器在 CPU 芯片内部,不在 RAM。
  2. ✅RAM。局部变量运行时存放在内存 RAM 的栈区。
  3. ⚠️表述不够精确:单片机采用内存地址映射,CPU 把外设寄存器当作一个内存地址,直接读写该地址完成访问,笼统写 "寻址" 不够准确。

内存映射 I/O(MMIO)

单片机里,外设寄存器物理上不在内存芯片。 硬件设计把外设寄存器映射到物理地址空间,给每一个外设寄存器分配专属物理地址。

CPU 不需要专门的硬件指令,直接使用读写内存的指令,就可以读写外设寄存器,这种机制叫内存映射 I/O。

重点区分

  • 读写 RAM:读写真实内存芯片,保存程序数据
  • 读写映射后的外设地址:读写的不是内存,是外设硬件,直接改变硬件状态

⚠️关键细节 访问外设寄存器的 C 指针,必须带上 volatile。 原因:编译器不知道这个地址对应硬件,会认为是普通内存,有可能把读写操作优化删掉,导致硬件控制失效。

表格

对象 地址 访问后作用 是否需要 volatile
RAM 内存单元 物理地址 读写程序数据 一般不需要
外设寄存器 (MMIO) 映射的物理地址 修改硬件状态 ✅必须

问题

  1. 内存映射 I/O,CPU 需要专用 I/O 指令才能操作外设吗?
  2. 同样是对一个地址赋值,写 RAM 和写外设寄存器本质差别是什么?
  3. 操作映射的外设寄存器为什么强制使用 volatile?

:

1.不用

2.一个是写真实的内存 一个是外设寄存器的状态

3.防止地址被优化

:

批改:

  1. ✅不用,复用普通内存读写指令即可。
  2. ✅正确,写 RAM 修改内存里的数据;写外设寄存器修改硬件外设的工作状态。
  3. ⚠️更准确:防止编译器把对外设地址的读写操作给优化消除,不是优化地址本身。

外设寄存器读写不对称

RAM 内存:写进去什么数据,读出来就一定是什么数据。写入 0x05,再读,得到 0x05,读写完全对称。

外设寄存器不一定遵守这个规则:

  1. 只读寄存器:只能读硬件状态,向该地址写入数据无效。例如状态寄存器,用来获取硬件工作情况。
  2. 只写寄存器:只能写入来控制硬件,读取该地址拿到的是无意义垃圾值。
  3. 读写分离:写入某值用来开启硬件,读出来返回的不是刚刚写进去的值,而是硬件实时状态。

重要提醒 volatile 的作用仅仅阻止编译器优化掉读写指令,它不能改变硬件本身特性。硬件是只读寄存器,就算加 volatile,你写它依旧无效。

表格

类型 允许写 允许读 例子
RAM 内存 ✅ ✅ 普通全局、局部变量
只读外设寄存器 ❌ ✅ 硬件状态寄存器
只写外设寄存器 ✅ ❌ 硬件控制寄存器

:

1.一定

2.不能

3.不能

:

批改:

  1. ✅一定,RAM 读写对称,写入什么读取就得到什么。
  2. ✅不能,只写寄存器硬件本身就没有读通路,volatile 改变不了硬件。
  3. ✅不能,volatile 只作用在编译器层面,不修改硬件行为。

小结

把前面三段内容整合,梳理最容易混淆的坑点。

  1. ❗不要把CPU 通用寄存器 和外设寄存器混为一谈
  • CPU 通用寄存器:CPU 芯片内部,汇编使用,C 语言不能直接操作,没有内存地址。
  • 外设寄存器:外设硬件,通过内存映射地址,C 指针操作。
  1. ❗不要把外设寄存器当成 RAM 内存单元 RAM:存储软件数据,写什么读什么。 外设寄存器:用来操控硬件,读写行为由硬件手册决定,会出现只读、只写。

  2. ❗volatile 的边界 volatile 不修复硬件缺陷,只保证编译器不会把读写指令删掉。 硬件是只写寄存器,就算加 volatile,读依旧拿不到有效数据。

表格

知识点 CPU 通用寄存器 RAM 外设寄存器
位置 CPU 内部 内存芯片 外设芯片
C 语言直接访问 ❌ ✅ ✅(MMIO)
读写对称 --- ✅ ❌可能只读 / 只写
需要 volatile --- ❌ ✅
相关推荐
qq_284274051 小时前
机械设计基础·滚动轴承全解(类型·代号·选型·寿命)+轮系与蜗杆蜗轮传动
笔记·学习·自动化·制造
2603_965148116 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
kaixin_啊啊8 小时前
【用于更准确 G×E 基因组预测的大规模作物数据集与基于深度学习的多模态融合框架】论文学习
人工智能·深度学习·学习
xier_ran8 小时前
【infra之路】AI 编译器学习笔记(六):重拾 C++——lambda 与 MLIR 中的回调
c++·笔记·学习
别动我齐刘海10 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
m4Rk_11 小时前
【论文阅读】Agent 记忆机制(99):PrisMem——从整体分数搜索走向能力驱动的记忆自进化
论文阅读·人工智能·学习·开源·github
PC2005-cloud12 小时前
Mysql学习笔记:InnoDB Cluster 集群从零搭建实战,基于 Docker 实现高可用读写分离架构
笔记·学习·mysql
小陈phd13 小时前
深入理解agent学习笔记(七)——动态提示词与Skills
笔记·学习
我命由我1234513 小时前
田野笔记极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
一木 之林13 小时前
微信小程序开发全攻略·文章版|00 总览:74集学习路径与知识地图
人工智能·学习·计算机视觉·微信小程序·小程序