计算机硬件的组成
开发人员比较关心的硬件,在操作系统中,它们被抽象成了不同的东西。
计算机硬件之间是如何通信的
通俗易懂的方式解释 总线(Bus) 到底是什么:
一句话概括
总线 = 一组共享的"信息高速公路",连接计算机各个硬件部件,让它们能够互相传递数据。
1.总线到底是什么?是电线吗?
是的,但不完全是。
| 层面 | 解释 |
|---|---|
| 物理层面 | 确实是电路板上的铜导线(电线)+ 连接插座 |
| 逻辑层面 | 是一组约定好的通信规则和协议 |
| 功能层面 | 是多个设备共享的公共通道 |
就像高速公路:
- 电线 = 高速公路的路面(物理基础)
- 总线协议 = 交通规则(靠右行驶、限速、红绿灯)
- 总线标准 = 车道宽度、收费站设计标准
2.总线的核心特点:共享
没有总线的情况(点对点):
CPU ──线1──→ 内存
CPU ──线2──→ 硬盘
CPU ──线3──→ 显卡
内存 ──线4──→ 硬盘
... (需要无数条线,复杂混乱)
使用总线的情况(共享通道):
┌──→ 内存
CPU ──总线──┼──→ 硬盘
├──→ 显卡
└──→ USB控制器
(所有设备共用一组线,通过地址区分)
3.总线的组成部分(物理上)
| 组成 | 说明 | 类比 |
|---|---|---|
| 数据总线 (Data Bus) | 传输实际数据 | 高速公路上的货车(运货) |
| 地址总线 (Address Bus) | 传输"去哪里"的地址 | 货车上的导航目的地 |
| 控制总线 (Control Bus) | 传输读写命令、时钟信号 | 交通信号灯、交警指挥 |
| 电源线 | 供电 | 服务区的加油站 |
现代总线还可能包含:时钟线、地线、中断线、复位线 等
生活中的总线类比
| 类比 | 解释 |
|---|---|
| 公交车系统 | 一条线路,多个站点,乘客(数据)按站上下车 |
| 电话总机 | 一条外线,转分机,通过拨号(地址)找到对应分机 |
| 小区快递柜 | 一个柜子(总线),多个格子(地址),快递(数据)按格号存放 |
| 水管系统 | 主管道分支到各个水龙头,通过阀门控制水流 |
4.常见的总线类型
| 总线类型 | 用途 | 速度 | 例子 |
|---|---|---|---|
系统总线 | CPU ↔ 内存 | 最快 | DDR4/DDR5 内存总线 |
PCIe | 扩展显卡、SSD | 很快 | PCIe 4.0/5.0 x16 |
SATA | 连接机械硬盘/SSD | 中等 | SATA III (6Gbps) |
USB | 外设连接 | 中等 | USB 3.2/4.0 |
I2C/SPI | 传感器、小芯片 | 慢 | 温度传感器、EEPROM |
CAN总线 | 汽车电子 | 慢但可靠 | 汽车发动机、ABS系统 |
5.总线 vs 电线 的关键区别
| 普通电线 | 总线 |
|---|---|
| 一对一连接 | 一对多连接 |
| 简单通电 | 传输复杂数据 |
| 无协议 | 有严格的通信协议 |
| 独占使用 | 分时共享使用 |
| 例子:台灯电源线 | 例子:USB线、内存插槽 |
6.为什么需要总线?
| 优势 | 说明 |
|---|---|
| 简化布线 | 减少电线数量,降低成本 |
| 易于扩展 | 新设备只需"挂"到总线上 |
| 标准化 | 不同厂商设备可以互联互通 |
| 降低成本 | 共享通道比专用线路便宜 |
总结:
总线 = 共享的物理线路(电线)+ 通信协议(规则)+ 接口标准(插座形状)
它是计算机硬件之间的"公共道路系统",让CPU、内存、硬盘、显卡等设备能够高效、有序地互相通信。
计算机的内存
1. CPU向内存中写入1字节数据
2. CPU向内存中读取1字节数据
3. 内存可以存储多少数据
通过扩大地址信号引脚,来增大运行内存的存储容量
10个地址引脚 ———— 1KB
32个地址引脚 ———— 4GB
4. 指针 与 引用
开发人员使用C/C++中的指针、引用,它们的本质就是 "运行内存地址" , 有了内存地址,就可以操作其对应的数据了
5. 不同的数据类型
写程序的时候,我们会指定变量的数据类型, 从运行内存的角度来看,就是占用内存不一样的表现!
一个程序的执行过程
程序的运行过程其实就是: CPU根据程序的步骤,对相应的数据进行计算处理的过程
示例:打印两数之和
#include <stdio.h>
void main(){
int a = 3;
int b = 2;
int c = a + b;
printf("%d", c);
}
计算机的CPU
寄存器:负责暂存指令、数据等处理对象,可以将它看做是内存的一种,一个CPU的内部一般有20~100个寄存器
控制器:负责把内存中的指令、数据读入寄存器,并根据指令的执行结果来控制整个计算机
运算器:负责计算(运算)从内存中读入寄存器的数据
1. CPU 常用寄存器分类
一、通用寄存器 (General Purpose Registers)
| 寄存器 | 名称 | 用途 |
|---|---|---|
| EAX / RAX | 累加器 (Accumulator) | 算术运算、函数返回值 |
| EBX / RBX | 基址寄存器 (Base) | 数据指针、通用存储 |
| ECX / RCX | 计数寄存器 (Counter) | 循环计数、字符串操作 |
| EDX / RDX | 数据寄存器 (Data) | I/O操作、乘除法辅助 |
| ESI / RSI | 源变址寄存器 (Source Index) | 字符串/数组源地址 |
| EDI / RDI | 目的变址寄存器 (Destination Index) | 字符串/数组目的地址 |
| EBP / RBP | 基址指针 (Base Pointer) | 栈帧基址,访问局部变量 |
| ESP / RSP | 栈指针 (Stack Pointer) | 指向栈顶 |
注:x86-64架构下前缀加 R(如RAX),32位x86加 E(如EAX)
二、指令指针与标志寄存器
| 寄存器 | 名称 | 用途 |
|---|---|---|
| EIP / RIP | 指令指针 (Instruction Pointer) | 存放下一条要执行的指令地址(这个就是平时我们说的 程序计数器PC) |
| EFLAGS / RFLAGS | 标志寄存器 (Flags) | 存储CPU状态标志(零标志ZF、进位标志CF、符号标志SF等) |
三、段寄存器 (Segment Registers)
| 寄存器 | 用途 |
|---|---|
| CS | 代码段 (Code Segment) |
| DS | 数据段 (Data Segment) |
| SS | 栈段 (Stack Segment) |
| ES / FS / GS | 附加数据段 |
四、x86-64 扩展寄存器
64位架构新增了 R8-R15 共8个通用寄存器,以及扩展的 XMM/YMM/ZMM 向量寄存器(用于SIMD指令集如SSE/AVX)。
五、特殊功能寄存器
| 寄存器 | 用途 |
|---|---|
| CR0-CR4 | 控制寄存器(控制CPU工作模式) |
| DR0-DR7 | 调试寄存器 |
| MSR | 模型特定寄存器(Model Specific Registers) |
快速对比:32位 vs 64位
32位 (x86): EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, EFLAGS
64位 (x64): RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RIP, RFLAGS, R8, R9, R10, R11, R12, R13, R14, R15
这些寄存器是程序执行的基础,RAX/EAX 常用于存储函数返回值,RSP/ESP 管理函数调用栈,RIP/EIP 控制程序执行流程。
2. CPU的执行流程
3. CPU的指令集
一个CPU它会支持很多很多指令(毕竟CPU要执行你的机器语言指令)
指令: 操作码 + 操作数
查看计算机CPU架构方法
指令集 = 指令集合
X86 架构CPU 常用的指令集:
| 序号 | 指令 | 英文全称 | 功能说明 | 使用场景 |
|---|---|---|---|---|
| 1 | mov | Move | 数据传送,将源操作数复制到目标操作数 | 变量赋值、寄存器初始化、内存读写 |
| 2 | call | Call | 调用子程序/函数,将返回地址压栈并跳转 | 函数调用、系统调用 |
| 3 | ret | Return | 从子程序返回,从栈弹出返回地址并跳转 | 函数返回、子程序结束 |
| 4 | add | Add | 加法运算,目的操作数 = 目的操作数 + 源操作数 | 算术运算、指针偏移计算 |
| 5 | sub | Subtract | 减法运算,目的操作数 = 目的操作数 - 源操作数 | 算术运算、栈空间分配 |
| 6 | and | And | 按位与运算 | 掩码操作、清零特定位、权限检查 |
| 7 | jg | Jump if Greater | 大于则跳转(有符号比较) | 条件分支、循环控制、if语句 |
| 8 | leave | Leave | 恢复栈帧,等价于 mov esp, ebp + pop ebp | 函数尾声,清理栈帧 |
| 9 | push | Push | 将操作数压入栈顶,栈指针递减 | 保存寄存器、传递函数参数 |
| 10 | pop | Pop | 从栈顶弹出数据到操作数,栈指针递增 | 恢复寄存器、获取函数参数 |
| 11 | jmp | Jump | 无条件跳转 | 循环、switch-case、goto |
| 12 | cmp | Compare | 比较两个操作数,设置标志位(不保存结果) | 条件判断前置操作 |
| 13 | je/jz | Jump if Equal/Zero | 等于/为零则跳转 | 相等判断、NULL检查 |
| 14 | lea | Load Effective Address | 加载有效地址(不做内存访问) | 获取变量地址、计算指针 |
| 15 | test | Test | 按位与测试,设置标志位(不保存结果) | 快速判断零值、位测试 |
代码中的函数调用栈
完整 x86-64 通用寄存器表(上面已经列举这里再细分一下):
| 64位 | 32位 | 16位 | 8位 | 全称 | 用途 |
|---|---|---|---|---|---|
| rax | eax | ax | al/ah | Accumulator | 累加器,算术运算、函数返回值 |
| rbx | ebx | bx | bl/bh | Base | 基址寄存器,数据指针 |
| rcx | ecx | cx | cl/ch | Counter | 计数器,循环计数、字符串操作 |
| rdx | edx | dx | dl/dh | Data | 数据寄存器,I/O操作、乘除法辅助 |
| rsi | esi | si | sil | Source Index | 源变址寄存器,字符串操作源地址 |
| rdi | edi | di | dil | Destination Index | 目的变址寄存器,字符串操作目的地址 |
| rbp | ebp | bp | bpl | Base Pointer | 栈基址指针,指向栈帧底部 |
| rsp | esp | sp | spl | Stack Pointer | 栈顶指针,指向栈顶 |
| r8-r15 | r8d-r15d | r8w-r15w | r8b-r15b | - | 扩展寄存器(x86-64新增) |