[toc]
对程序员来说, CPU 是什么
概念
- 程序由数据和指令组成
- 内存地址 - 用来表示指令和数据存储位置的数值
cpu 结构
- 寄存器 - 用于暂存指令, 数据等处理处理对象, 可以看作内存的一种.
- 控制器 - 负责将内存中的指令和数据读入寄存器, 并根据指令执行结果控制计算机.
- 运算器 - 负责运算从内存读入寄存器的数据.
- 时钟 - 负责发出 CPU 开始计时的时钟信号. 1 GHz = 1 亿次 / s 代表处理器运算速度.
内存
通常所说的内存指的是计算机的主存储器(main memory), 通过控制器与 CPU 连接, 负责存储数据和指令, 每个字节(8 位)都带有地址编号.
内存通常使用 DRAM (dynamic Random Access Memory), 动态随机存取储存, 需要保持稳定的电源供给并时常刷新(确保最新数据), 断电清除数据.
运行过程
程序启动后, 根据时钟信号, 控制器从内存读取指令和数据. 运算器运行指令对数据运算, 控制器根据运算结果控制计算机.
控制 - 数据运算之外的处理, 主要指数据的输入输出时机控制.
对程序员来说, CPU 是寄存器的集合
汇编语言
汇编 : 汇编语言 -> 机器语言 的过程.
汇编语言与机器语言基本上是一一对应的.
汇编语言关键字 : 助记符 对应 机器语言指令, 使用指令功能的英语简写.
mov // move 数据存储
add // addition 数据累加
汇编语言以寄存器为单元描述
// 寄存器名称(区分种类)
eax - 累加寄存器
ebp - 基址寄存器
mov eax, dword ptr [ebp-8] // 将数据从内存复制到寄存器 eax
add eax, dword ptr [ebp-oCh] // eax 与内存数据累加
mov dword ptr [ebp-4], eax // 将累加结果存储到内存
寄存器分类
种类 | 功能 | 特点 |
---|---|---|
累加寄存器(accumulator register) | 存储执行运算的数据和运算后的数据 | 唯一 |
标志寄存器(flag register) | 存储运算处理后的 CPU 状态 | 唯一 比较 |
程序计数器(program counter) | 存储下一条指令所在内存地址 | 唯一 执行顺序 |
基址寄存器(base register) | 存储数据内存的起始地址 | 多个 |
变址寄存器(index register) | 存储基址寄存器的相对地址 | 多个 脚标 |
通用寄存器(general purpose register) | 存储任意数据 | 多个 |
指令寄存器(instruction register) | 存储指令,内部使用, 程序员无法控制 | 唯一 不可控 |
栈寄存器(stack register) | 存储站区域起始地址 | 唯一 |
寄存器可用于存储数据和指令, 数据分为 "用于计算的数值" 和 "表示内存地址的数值" . 根据数据种类不同, 所使用的寄存器也不同.
程序流程控制
程序计数器 (program counter) 存储下一条指令所在内存的地址
实际情况中, 一条指令和数据通常被存储在多个地址上. 此处为方便说明简化为单个地址.
CPU 每执行一个指令, 程序计数器就会自动累加(累加数值根据指令所占地址数), CPU 控制器参照程序计数器的数值, 继续从内存读取命令. 也就是说, 程序计数器决定这程序的流程.
条件分支与循环
- 条件分支 - 根据条件执行指定地址指令
- 循环 - 重复执行同一地址指令
以 绝对值计算过程 为例
0102 大于 0 则跳转到 0104 地址
0103 取相反数
0104 直接输出
0102 执行了逻辑判断并根据结果, 执行跳转指令
标志寄存器 比较
标志寄存器 (flag register) 存储运算处理后的 CPU 状态
无论累加寄存器运算结果为正数, 零还是负数. 标志寄存器都会将其保存, 并负责存放结果超出寄存器长度的溢出和对结果奇偶的校验.
条件分支中进行比较运算, 其结果参照标志寄存器的低 3 位.
低 1 位, 结果为正 值为 1
低 2 位, 结果为 0 值为 1
低 1 位, 结果为负 值为 1
比较过程, 内部执行了相减运算, 根据运算结果在标志寄存器的第三位得出结果.
函数调用机制
函数调用通过将程序计数器设定为函数存储地址实现, 但是与条件分支机制不同. 函数执行完成后需要回到函数调用点顺序执行, 单纯的跳转执行无法实现.
通过机器语言的 call 指令 实现函数调用, 而在将程序计数器设值为函数入口地址前, call 指令会将函数调用完成后要执行的指令地址存储在 栈内存
中.
函数处理完成后, 通过函数的出口来执行 return 指令. 将保存在 栈内存
中的地址设值到程序计数器中.
通过地址和索引实现数组
- 基址寄存器 (base register) 存储数据内存的起始地址
- 变址寄存器 (index register) 存储基址寄存器的相对地址
通过两种寄存器的配合使用, 实现在内存上特定内存区域的划分, 以实现类似数组的操作.
使用 十六进制 划分 00000000 ~ FFFFFFFF 区域的内存. 该区域使用 一个32位寄存器 即可查看全部的地址. 而想实现类似数组的分割区域, 连续查看的目的, 使用两种寄存器更加方便.
通过将基址寄存器中的基础地址与变址寄存器中的相对地址相加得到具体的地址. 使用变址寄存器作为 数组
的 index .
CPU 机器语言指令分类
类型 | 功能 |
---|---|
数据转送 | 寄存器-内存, 内存-内存, 寄存器-外围设备 间的数据读写. |
运算 | 使用累加寄存器执行 算数, 逻辑, 比较, 位移 |
跳转 | 条件分支, 循环, 强制跳转 |
call / return | 函数调用 / 返回调用前地址 |
参考资料
<程序是怎样跑起来的>