HOME

计算机组成原理

20240429162754.png
Published on
/
88 mins read
/
––– views

1 计算机系统概述

1.1 计算机硬件

1.1.1 冯·诺伊曼机

  • 软件和硬件在逻辑上是等效的

冯 · 诺依曼计算机的特点:

  1. 计算机由 5 大部件组成
  2. 指令和数据以同等地位存于存储器,可按地址寻访
  3. 指令和数据用二进制表示
  4. 指令由操作码和地址码组成
  5. 存储程序:冯·诺伊曼提出的概念
  6. ==以运算器为中心==
    1. 输入/输出设备与存储器之间的数据传送通过运算器完成

1.1.2 现代计算机

区别:以存储器为中心

硬件:

  1. 主机
    1. CPU
      1. 运算器
      2. 控制器
    2. 存储器
      1. 主存
      2. 辅存(属于IO设备)
  2. IO设备
    1. 输入
    2. 输出

1.2 硬件工作原理

1.2.1 主存储器

主存储器:

  1. 存储体
  2. MAR 地址寄存器
  3. MDR 数据寄存器

注意,现代计算机的MAR和MDR已集成在CPU中。

读取写入数据的过程类似存取包裹:

  • MAR 存放地址:需要读/取的数据的地址
  • MDR 存放数据

MAR位数MDR位数
地址码长度,可算存储单元个数存储
4位 = 242^4个存储单元16位 = 1个存储单元存放16bit

注意:

  • 字长是可变的,字节是不变的 = 8bit
  • MDR规定存储长,即规定了1个字=16bit

1.2.2 运算器

运算器由 ALU、移位器、状态寄存器(PSW)、通用寄存器组 组成。

  • ALU:算数逻辑单元
    • 核心,其他三个只是寄存器
  • ACC:累加寄存器
  • MQ:乘商寄存器
  • X:通用操作数寄存器

1.2.3 控制器

  • CU:控制单元,核心

1.2.4 硬件工作过程

每一步过程都类似:

  1. 取指令
    1. PC to MAR
    2. MDR to IR:取指令到IR
  2. 分析指令
    1. IR.op to CU:指令的操作码送到 CU,CU分析指令
  3. 执行指令
    1. IR.ad to MAR:指令的地址码送到 MAR
    2. 后续操作看具体的指令

1.3 计算机软件

1.3.1 两类软件

  • 系统软件 管理计算机系统的硬件资源,向上层应用程序提供服务。
  • 应用软件 按应用场景需要编制成的各种程序,直接为用户提供服务。

1.3.2 三个级别的语言

  1. 高级语言
  2. 汇编语言:用助记符编写,以便记忆
  3. 机器语言:计算机唯一可以直接执行的语言
  • 汇编语言和机器语言都与计算机系统结构有关

三种程序:

  • 编译程序/器:将高级语言一次全部翻译为汇编语言/直接翻译为机器语言
  • 汇编程序/器:将汇编语言翻译成机器语言。
  • 解释程序/器:高级语言翻译为机器语言(翻译一句执行一句)。

1.3.3 软件和硬件的逻辑功能等价性

同一个功能,既可以用硬件实现,也可以用软件实现。

1.3.4 指令集体系结构 (ISA)

  • Instruction Set Architecture

一台计算机可以支持哪些指令,以及每条指令的作用是什么、每条指令的用法是什么。

1.3.5 计算机系统的层次结构

计算机系统包含:软件 + 硬件

1.3.6 工作原理

从 源程序 到 可执行文件 的流程:

  1. 编程:程序员编写 C 语言源程序(如 hello.c )。
  2. 预处理
    • 工具:预处理器
    • 输入输出:hello.chello.i
    • 为什么是 .i:因为预处理器最核心的功能之一就是处理 #include 指令,将所有依赖的头文件内容整合到一个文件中
  3. 编译
    • 工具:编译器
    • 输入输出:hello.ihello.s(汇编语言程序 )
  4. 汇编
    • 工具:汇编器
    • 输入输出:hello.shello.o(机器语言程序,即目标模块 )
  5. 链接
    • 工具:链接器
    • 输入:hello.o、其他被引用目标模块(如 print.o
    • 输出:hello.exe(可执行文件)
    • 将多个相关目标模块链接成完整可执行文件

1.4 性能指标

1.4.1 存储器性能指标

1.4.1.1 字长概念辨析

  1. 机器字长
    1. 简称字长
    2. 是 CPU 内部用于整数运算数据通路的宽度
    3. 等于 CPU 内部的运算器位数和通用寄存器宽度
    4. 表示 CPU 一次可以处理的最大二进制位数
  2. 存储字长:一个存储单元中的二进制位数
  3. 指令字长:一个指令字包含的二进制位数

它们必须都是 1 字节的整数倍。

1.4.2 CPU性能指标

  1. CPU时钟周期

  2. CPU主频:

    CPU主频(时钟频率)=1CPU时钟周期\text{CPU主频(时钟频率)} = \frac{1}{\text{CPU时钟周期}}
  3. CPI (Clock cycle Per Instruction):执行一条指令所需的时钟周期数。

  1. IPS:每秒执行多少条指令1. MIPS:每秒执行多少百万条指令

    IPS=主频平均CPIIPS = \frac{\text{主频}}{\text{平均}CPI}
  2. FLOPS:每秒执行多少次浮点运算

    • KFLOPS(Kilo):千,对应 10310^3
    • MFLOPS(Million):百万,对应 10610^6
    • GFLOPS(Giga):十亿,对应 10910^9
    • TFLOPS(Tera):万亿,对应 101210^{12}
    • PFLOPS(Peta):千万亿,对应 101510^{15},考过这种题,😅
    • EFLOPS(Exa):百京,对应 101810^{18}

1.4.3 系统整体性能指标

  1. 数据通路带宽:数据总线一次所能并行传送的位数
  2. 吞吐量:系统在单位时间处理的请求数
  3. 响应时间:发送请求到做出响应的时间

动态测试:可以用基准程序来测量计算机处理速度

1.4.3.1 辨析


2 数据的表示和运算

2.1 数制与编码

常识:

216=655362^{16} = 65536 215=327682^{15} = 32768 FFFFH=11=65535FFFFH = 1 \dots 1 = 65535

2.1.1 进位计数制

基数:每个数码位所用到的不同符号的个数

  • r进制的基数为r

2.1.2 进制转换

2.1.2.1 转十进制

按位权

2.1.2.2 二八六转换

符号对应

2.1.2.3 十进制转换

整数部分:短除法

小数部分:乘r取整

拼凑法:

2.1.3 真值 机器数

真值机器数
+1501111
符合人类习惯数字实际存到机器的形式

注意,机器数的正负需要被数字化,多加一位0/1表示符号。

  • 408中机器数到底是原码还是补码请看题干

2.1.4 定点数

定点数:

  • 无符号数:n位无符号数字的范围是 [0,2n1][0, 2^n-1]
  • 有符号数
    • 原码
    • 反码
    • 补码
    • 移码

2.1.4.1 有符号数的定点表示

2.1.4.2 原码

2.1.4.3 反码

正数的反码 = 原码 负数的反码 = 数值位取反

2.1.4.4 补码

  • C语言数据在内存中,以补码形式存放

正数的补码 = 原码 负数的补码 = 反码末位+1,需要进位

  • 补码 to 原码也是同样的操作
  1. 补码和移码的 0 只有一种表示形式;而原码和反码有两种 1. 故,补码和移码范围 + 1 2. 补码可以额外表示的数字:1. 注意,10000000没有原码对应的真值,因为原码无法表示 272^{-7}
  2. 补码可以把减法转为加法:

补充:

  • [x][x]_{补}补快速求[x][-x_{补}]的方法:符号位、数值位全部取反,末位+1

2.1.4.5 移码

移码 = 补码的符号位取反

  • 移码只能表示整数
  • 移码的真值0也只有一种形式
  • 表示范围和补码相同

移码可以用于比较大小,从最高位开始,先出现1的数大。

  • 移码是单调增,补码是分两个周期线性增大(-128~-1 和 0~127)

或者加偏置值

2.1.5 语言强制转换

short to int:

  • 有符号数:符号扩展,且不改变真值
  • 无符号数:零扩展 int to short:高位截断

2.1.5.1 零扩展 符号扩展

  • 零扩展适用于无符号数,用0扩展高位
  • 符号扩展适用与有符号数,用符号位扩展高位

2.1.6 逻辑门电路基础

2.1.6.1 逻辑门

补充:n个bit进行异或

  • 若有奇数个1则异或结果为1
  • 若有偶数个1则异或结果 0

2.1.6.2 公式

2.1.6.3 多路选择器

2.1.6.4 三态门

三态:高电平、低电平、高阻态

  • 高阻态 = 断线

2.2 运算方法和运算电路

2.2.1 加法器

2.2.1.1 串行进位加法器

  • 串行进位又称为行波进位
  • 但是属于并行加法器,见术语辨析

问题:进位信息串行传递,导致计算速度取决于进位产生和传递速度

2.2.1.2 术语辨析

  1. 由于两个输入端允许并行输入 n bit,因此这种加法器属于:并行加法器
  2. 由于进位信息是串行产生的,因此从“进位方式”看,这种加法器属于:串行进位加法器
  3. 综上,很多教材把这种加法器称为:串行进位并行加法器

2.2.1.3 并行进位加法器

加入了CLA部件,使得所有进位信息同时产生。

2.2.1.4 带标志位的加法器

  • OF(Overflow Flag)溢出标志,用于判断带符号数加减运算是否溢出。
    • OF=1 溢出:OF=0 未溢出
    • 也用于表示有符号/无符号整数乘法是否溢出
  • SF(Sign Flag)符号标志,用于判断有符号数加减运算结果的正负性
    • SF=1 结果负:SF=0 结果为正
  • ZF(Zero Flag)零标志,用于判断加减运算结果是否为0。
    • ZF=1 表示结果0;ZF=0 表示结果不为0
  • CF(Carry Flag)进位/借位标志,用于判断无符号数加减运算是否溢出。
    • CF=1 溢出:CF=0 未溢出

注意,SF 和 OF 对于无符号数运算没有意义!

  • 408p172.27.2011真题

2.2.2 算数逻辑单元 ALU

CPU

  • 控制器
  • 运算器
    • ALU
      • 加法器
    • 通用寄存器
    • 状态寄存器 PSW
    • 移位器

ALU是运算器的核心;加法器是ALU的核心。

2.2.2.1 功能

重点:如果ALU支持 kk 种功能,则控制信号位数 mlog2km \geq \lceil \log_{2}k \rceil

ALU 运算位数 n=机器字长\text{ALU 运算位数 }n = \text{机器字长} PSW 程序状态字寄存器=FR 标志寄存器\text{PSW 程序状态字寄存器} = \text{FR 标志寄存器}

2.2.3 定点数的移位

左右移动 rr 位 约等于 乘除 2r2^r

2.2.3.1 逻辑移位

用于无符号整数

左移:高位丢弃,低位补零

  • 右移类似,但是右移丢弃位 = 1则会损失精度
  • 溢出判断:丢弃位是否为 1

2.2.3.2 算数移位

用于有符号整数

左移:移动与逻辑移位完全相同,符号位一起移动

  • 溢出判断不同,改为判断符号位是否改变

右移高位补充符号位,丢弃位 = 1则也会损失精度

2.2.4 定点数的加减

原码运算麻烦,一般采用补码运算

2.2.4.1 原码加减

绝对值加减,再处理符号

2.2.4.2 补码加减

  1. 减法 = 加负数
  2. 符号位直接参与运算

溢出判断:

由上图易知,溢出情况看符号位即可

  1. 上溢:正 + 正 = 负 0 0 1
  2. 下溢:负 + 负 = 正 1 1 0

2.2.4.3 模4 和 模2 补码

模4:双符号位 模2:单符号位

2.2.5 无符号数的加减

加法:按位相加即可

减法:减数取补码,减法变加法

2.2.5.1 溢出判断

  • 考试时,直接按照十进制算一下即可
  • 注意,无符号数是没有负数的127128=1127-128 = -1 是溢出的!

结合标志位理解:

2.2.6 补码加减运算电路

补码加减运算电路实现了无符号数和有符号数的统一,电路只是计算两个二进制串,并不关心是否有符号。

  • 对于 OF 标志位,当作有符号数理解,判断加/减是否有溢出即可
  • 对于 CF 标志位,当作无符号数理解,判断加/减是否有进位/借位即可 - 可能涉及有符号数到无符号数的转换,快速方法是 x=2kx-x = 2^k-x

当然也可以按公式算,不过就了。

  • 大题写计算过程可能需要公式

sub 信号的两点作用:

  1. 多路选择器由 sub 信号控制,实现了(减法时)减数取反的操作
  2. sub 信号作为 cin (来自低位的进位),实现了取反之后 + 1

注意,加法器的(加数)输入端仅取反,加1操作依靠 cin 的进位(sub信号)

2.2.7 无符号整数的乘法

  • 王道说明:考纲侧重考察在整数的乘除法,而教材以浮点数的乘除法作为引入

2.2.7.1 电路

特殊处理:控制逻辑会先检查两个是否都是 0,如果是则直接结果为 0

循环:

关于乘法溢出判断:

  • 实际上,P Y寄存器共 2n 位,而两个 n 位整数乘法结果一定小于 2n,计算过程中是不可能溢出的
  • 但是,由于计算机只保留 n 位,所以结果上可能溢出

溢出实例 及 2 种溢出处理:

注意:

  • 有/无符号整数乘法都是用 OF 标志位记录溢出
  • 无符号整数乘法时,CF 也会记录

2.2.8 有符号整数的乘法

  • 简单思路是直接算绝对值,符号位异或
  • 王道网课用了纯电路的方式实现
  • 这个方法叫补码一位乘法,Booth乘法

电路的主要区别是:

  1. 在最右侧添加了辅助位,初始为 0
  2. ALU 可以执行加减法
  3. 改为算数右移

另外添加了一个比较繁琐的规则,见左表:

溢出判断:

  • 检查高 n+1n+1 位是否完全相同
  • 不完全相同则溢出

注意,有/无符号整数乘法都是用 OF 标志位记录溢出。

2.2.9 计算机实现乘法电路的三种方式

上一节的电路实现 n bit 无符号数相乘,至少需要 n 个时钟

2.2.9.1 两位乘法

改进方案:可以实现“两位乘法”,每轮处理乘数寄存器Y的末尾2bit,实现,此时仅需 n/2 个时钟即可完成运算

  • 具体如何实现两位乘法没有深入

2.2.9.2 阵列乘法器

  • 快速乘法器

可以在 1 个时钟内完成乘法运算

2.2.9.3 逻辑运算等效

运算速度很慢

2.2.9.4 总结

  • 速度:阵列 > ALU移位 > 逻辑等效
  • 本节的三种方法,对于有无符号整数都适用

2.2.10 无符号整数的除法运算

  • 除法异常包括:商溢出、除数0

2.2.10.1 手算

二进制和十进制差不多,很简单

2.2.10.2 除法电路

被除数作零拓展

特殊情况:

  1. 除数 = 0,异常停止
  2. 被除数 < 除数,商 = 0

具体过程:

  • 判断商溢出:看第一位商(第一轮特殊处理)
    • 1,则商溢出异常,停止
      • 由于默认高4位填充 0,
      • 所以 n 除 n 时(单精度)不可能商溢出,
      • 2n 除 n 时(双精度)可能溢出,
      • 这一点商溢出小节有提到。
    • 0,则这次计算不可能发生溢出
  • 有关ALU加法操作
    • 上商 0 的时候,ALU实际上还是做了 RYR - Y 的操作(发现小于 0 才判断上商 0),所以需要做一次 +Y+ Y 的操作,使得余数恢复为正确的值,之后再左移。
    • 所以,ALU实际上的过程和手算的中间余数不一样,手算是人脑判断之后直接 0000- 0000
    • 称作恢复余数法

2.2.10.3 商溢出

按被除数 n/2n 分为单双精度

  • 双精度可能溢出
  • 单精度不可能溢出

2.3 浮点数

2.3.1 IEEE 754

  • 二进制浮点数算数标准

C语言的 float(单精度 32bit)、double(双精度 64bit)就是符合 IEEE 754 标准的浮点数格式。

二进制科学计数法

  • 引入 符号、尾数、基数、阶码的概念

浮点数由 符号、阶码、尾数 组成

  • 尾数的位数决定了精度
  • 阶码的位数决定了表示范围

2.3.1.1 float 的存储

  1. 尾数省略了小数点前的 1(但是尾数概念本身包含这个 1),省略是因为这是隐含的,不用浪费空间表示;所以,实际上 23 bit 表示的是 24 bit 的精度。
  2. 如何求移码:十进制 + 偏置值,转为二进制

2.3.1.2 double 的存储

基本一致,注意记忆偏置值

2.3.1.3 例题

2.3.2 浮点数表示范围

2.3.2.1 特殊状态的浮点数

  • 阶码全 0 / 1,视为特殊状态

2.3.2.2 规格化浮点数

  • 注意,规格化的阶码不存在全 0 / 1

float 阶码真值表示范围:

float 规格化浮点数表示范围:

  • 理解 22232 - 2^{-23}2232^{-23} 是尾数第23位
  • 正负是对称的,注意,表示范围不包括 0

其实从这个图也可以理解:

  • 阶码全 1 (127+1)表示无穷大
  • 阶码全 0 (-126-1)表示零
  • 注意,127、-126是移码
    • 移码转换:
      • 127 是 127+127=254;
      • 127+1 是 128+127=255;
      • 255 是 全 1

2.3.2.3 下溢处理

2.3.2.4 非规格化浮点数

临界值要记住,最大最小的数

  1. 非规格化表示的阶码固定为 -126
  2. 尾数不能为全零
  3. 尾数解读为 0.xxxx 而不是正常的 1.xxxx

负数同理:

2.3.3 浮点数加减运算

浮点数运算的特点:阶码运算和尾数运算分开。

2.3.3.1 对阶

对阶:使两个操作数的小数点对齐,使得两个数的阶码相同

  • 一般是 小阶向大阶对齐

对阶会导致尾数右移,为保证精度,应该不丢弃移出的尾数,使其参与尾数运算。

2.3.3.2 规格化

规格化:将尾数改写为 ±1.xxx\pm 1.x x x 形式。

  1. 右规:尾数右移(小数点左移),阶码 + 1
  2. 左规:尾数左移(小数点右移),阶码 - 1

2.3.3.3 舍入

对阶和右规时移出的位会保留,在舍入这一步时做具体的舍去操作。

  1. 就近舍入
  2. 正/负向舍入
  3. 截断法

2.3.3.4 溢出判断

  1. 左右规:可能指数下/上溢
  2. 尾数舍入:可能尾数溢出,溢出需要通过右规调整,然后又可能指数上溢。

尾数溢出,结果不一定溢出。

  • 尾数溢出可以通过右规调整,所以不一定溢出
  • 当然调整之后可能指数溢出,最终导致溢出
  • 结果是否溢出主要看指数溢出

2.3.4 数据存储和排列

大端:高字节在低地址 小端:高字节在高地址

  • 注意,以字节(2位16进制)为单位

边界对齐

  • 一般是按字节编址,即一个地址对应一个字节

2.4 补充:C语言

在 C 语言里,类型的长度(字节数)取决于编译器实现和平台架构,但常见的 32 位、64 位主流平台(如 Windows x86/x64、Linux x86_64、macOS ARM64)大致遵循下面的规律:

类型常见字节数(bytes)常见位数(bits)备注
char18保证是 1 字节(标准规定 sizeof(char) 永远是 1)。
short216最少 16 位(标准只保证 ≥16 位)。
int432在现代主流桌面平台几乎都是 32 位。
long4 / 832 或 64Win 平台的 LLP64 模型 vs Unix/Linux 的 LP64 模型。
long long864标准保证 ≥64 位,几乎总是 64 位。
float432IEEE 754 单精度。
double864IEEE 754 双精度。

3 存储系统

3.1 存储器概述

  • 辅存中的数据需要调入主存后才能被 CPU 访问

主存与辅存:实现了虚拟存储系统,解决了主存容量不够的问题

Cache与主存:解决了主存与 CPU 速度不匹配的问题(CPU 速度更快)

3.1.1 存取方式

  1. 随机存取存储器 RAM:支持随机访问
  2. 顺序存取存储器 SAM:只能顺序访问
  3. 直接存取存储器 DAM:支持直接选取区域(随机访问),区域内按顺序访问
    1. 磁盘是 DAM
  4. 相联存储器 CAM:按照内容检索 或者 地址检索
    1. 快表是一种相联存储器

3.1.2 性能指标

  1. 存储容量 存储字数×字长\text{存储字数} \times \text{字长}
  2. 单位成本 总成本总容量\frac{\text{总成本}}{\text{总容量}}
  3. 存储速度 数据传输率=数据宽度存储周期\text{数据传输率} = \frac{\text{数据宽度}}{\text{存储周期}}
    1. 存储周期=存取时间+恢复时间存储周期 = 存取时间 + 恢复时间
    2. 数据传输率也称主存带宽

3.2 主存储器

主存储器是内存,主要有 RAM 和 ROM 两种。

  • RAM:易失性,断电后数据丢失
  • ROM:非易失性

3.2.1 半导体原理

存储字:一次可以读出的 bit 数

存储字长:

  • 存储字的长度
  • 一个存储单元中的二进制位数
  • 一个存储单元中的存储元数量

多个存储单元构成存储体/存储矩阵。

3.2.2 存储器芯片原理

  1. CPU 通过 地址总线 传递地址 to MAR
  2. 控制电路 控制 MAR
  3. MAR to 译码器
  4. 译码器 选择 存储元
  5. 存储元 to MDR

  • 读写线可能有 1 或者 2 根
  • 片选线:选择哪个芯片

引脚数量:

  • 每个线对应一个引脚
  • 读写线可能有 2 根

3.2.3 寻址

3.2.4 DRAM 与 SRAM

RAM 主要有 DRAM、SRAM:

  • Static and Dynamic
  • 上一节的是 DRAM

DRAM芯片:使用栅极电容存储信息,常用作主存 SRAM芯片:使用双稳态触发器存储信息,常用作 Cache

  • 核心区别:存储元不一样
类型特点DRAM(动态RAM)SRAM(静态RAM)
存储信息电容触发器
破坏性读出
读出后需要重写?(再生)需要不用
运行速度
集成度
发热量
存储成本
易失/非易失性存储器?易失(断电后信息消失)易失(断电后信息消失)
需要刷新需要不需要
送行列地址分两次送同时送
  • DRAM 分两次送地址是由于地址线复用,使地址线、地址引脚减半

3.2.4.1 DRAM 芯片的行列计算

  • 重要补充,网课这块不扎实

假定有一个 2n×b2^n \times b 位的 DRAM 芯片,它实际上是一个存储阵列

  • 芯片中每个存储单元包含 bb 位
  • 行数 rr 和列数 cc 满足 r×c=2nr\times c = 2^n
    • 由于按行刷新,所以满足 rcr \leq c
    • 尽量使行列数相同
    • 或者有些题会直接给出 row×column×brow \times column \times b 位的形式

3.2.4.2 DRAM 刷新

为什么 DRAM 需要刷新?

如何刷新:

三种刷新方式:

  1. 分散刷新:刷新太频繁
  2. 集中刷新:有死区
  3. 异步刷新:死区小

刷新由存储器独立完成,无需 CPU 介入。

现在的主存已经抛弃了 DRAM,主要使用 SDRAM,例如 ddr4。

3.2.4.3 SDRAM

  • SDRAM(Synchronous DRAM)

SDRAM 的工作方式与传统的 DRAM 有很大不同。

  • 传统 DRAM 与CPU 之间采用异步方式交换数据,CPU 发出地址和控制信号后,经过一段延迟时间,数据才读出或写入。
    • 在这段时间里,CPU 不断采样 DRAM 的完成信号,在没有完成之前,CPU 插入等待状态而不能做其他工作。
  • SDRAM 采用同步方式

3.2.4.4 行缓冲寄存器

例如,要从图 6-3中 16×816×8 的DRAM中读出超单元(2,1),内存控制器发送行地址2,如下图a所示。

DRAM 的响应是将行 2 的整个内容都复制到一个内部行缓冲区。接下来,内存控制器发送列地址1,如下图b所示。DRAM的响应是从行缓冲区复制出超单元(2,1)中的8位,并把它们发送到内存控制器。

超单元:多位就是超单元

3.2.5 ROM

各种 ROM:

  • MROM(Mask Read Only Memory):
    • 厂家按客户需求在芯片生产时写入信息,不可重写,可靠性高、灵活性差、生产周期长,适合批量定制。
  • PROM(Programmable Read Only Memory):
    • 用户可用专门写入器写入信息,写一次后不可更改
  • EPROM(Erasable Programmable Read Only Memory):
    • 允许用户写入信息,之后可擦除数据并多次重写
    • 支持随机存取
    • UVEPROM:用紫外线照射8 - 20分钟擦除所有信息
    • EEPROM(也记为E^2PROM)可用“电擦除”方式擦除特定的字。
  • Flash Memory(闪速存储器、闪存):
    • U盘、SD卡属于闪存,由EEPROM发展而来,断电能保存信息且可多次快速擦除重写
    • 每个存储元只需单个MOS管,位密度比RAM高,闪存写速度比读速度慢
    • 手机辅存使用Flash芯片,不过相比SSD使用的芯片,集成度低、功耗高、价格便宜。
  • SSD(Solid State Drives):
    • 由控制单元 + 存储单元(Flash芯片)构成,与闪存核心区别在控制单元,存储介质类似,可多次快速擦除重写,速度快、功耗低、价格高,
    • 常用于个人电脑手机

计算机内的 RAM 和 ROM:

  • 操作系统在辅存(ROM)
  • BIOS 属于 ROM
  • RAM 和 ROM 一般统一编址,如图所示

3.2.6 双端口 RAM

  • 作用:优化多核CPU访问一根内存条的速度。
  • 硬件要求:需要有两组完全独立的数据线、地址线、控制线,CPU、RAM中也要有更复杂的控制电路。

两个端口对同一主存操作的4种情况:

  1. 两个端口同时对不同的地址单元存取数据。
  2. 两个端口同时对同一地址单元读出数据。
  3. 两个端口同时对同一地址单元写入数据,会出现写入错误
  4. 两个端口同时对同一地址单元,一个写入数据,另一个读出数据,会出现读出错误

3.2.7 多模块存储器

多模块存储器主要有:多体并行存储器 和 单体多字存储器。

重要概念:

  • 多模块交叉编址
    • 多模块交叉编址是将一个大的存储空间分成多个小的存储模块,并将这些模块按照一定的规则进行编址,使得在访问连续的存储单元时,可以访问到不同的模块,从而实现并行访问
  • 轮流启动
    • 在轮流启动方式下,系统会按照一定的时间间隔(一个存储器周期)依次启动各个存储模块,进行读写操作。这种方式适用于每个存储模块一次读写的位数(一个存储字)正好等于系统总线数据线位数的情况。
  • 同时启动
    • 在同时启动方式下,所有存储模块会同时启动,进行读写操作。这种方式适用于所有存储模块一次并行读写的总位数正好等于系统总线数据线位数的情况。
      • 2022真题:存储器总线宽度 恰好等于 所有模块的总位数,可以判断采用了多模块交叉编址 且 采用了同时启动的方式。

3.2.7.1 多体并行存储器

高位 / 低位交叉编址:

  • 存取周期 T=4rT = 4r 分为 存取时间r+等待时间(恢复)3r存取时间 r + 等待时间(恢复)3r

高位交叉由于连续访问的地址都在同一条内存,所以每次存取完都需要等待 3r3r

  • 理论上多个存储体可以被并行访问,但是由于通常会连续访问,因此高位交叉实际效果相当于单纯的扩容,所以一般不用高位

低位交叉的等待和存取在不同内存条,所以不冲突,可以实现并行访问

流水线方式:

  • 注意,存取时间 = 总线传输周期

注意,题目中提到交叉编址,一般是指低位交叉,因为高位交叉又称连续编址。

3.2.7.2 单体多字存储器

  1. 每个存储单元存储 m 个字
  2. 总线宽度也是 m 个字
  3. 只能一次并行读取 m 个字,灵活性差
  4. 指令和数据在主存必须连续存放

3.3 主存储器与CPU的连接

存储器的输入输出信号:

3.3.1 位扩展

两块存储芯片:

扩展到 n 块:

3.3.2 字扩展

  • 用 A13、14 两位作为片选信号,选择读取指定的芯片

使用1-2 译码器改进:

  • 原来需要占用 2 位作为片选信号,现在只需要 1 位(A13)
    • 在地址中只占用 1 位(最高位)
  • 译码片选法的核心就是 n to 2nn \text{ to } 2^n
  • 注意:
    • 图中 1-2 译码器的输入有一个非门,为了避免产生相同信号(导致同时读)
    • 图中可以看到地址除最高位外,还有 13 位,对应 A0 ~ A12 这 13 位地址

3-8 译码器:

线选法译码片选法
选片信号n 条线 n个选片信号n条线 2n2^n 个选片信号
电路复杂度电路简单电路复杂
地址空间地址空间不连续地址空间连续

3.3.3 字位同时扩展

2个四位存储器芯片叠一起 作为 位扩展,四组叠叠乐 形成 字扩展。

地址如下:

3.4 外部存储器

3.4.1 磁盘的组成

磁头、柱面、扇区:

3.4.2 磁盘的性能指标

3.4.2.1 磁盘的容量

  1. 一个磁盘所能存储的字节总数称为磁盘容量。磁盘容量有非格式化容量和格式化容量之分。
    1. 非格式化容量是指磁记录表面可以利用的磁化单元总数。
    2. 格式化容量是指按照某种特定的记录格式所能存储信息的总量。

3.4.2.2 记录密度

记录密度是指盘片单位面积上记录的二进制的信息量,通常以道密度、位密度和面密度表示。

  1. 道密度是沿磁盘半径方向单位长度上的磁道数;
  2. 位密度是磁道单位长度上能记录的二进制代码位数;
    1. 越内侧的磁道,位密度越大
  3. 面密度是 位密度 和 道密度 的乘积。
    1. 注意:磁盘所有磁道记录的信息量一定是相等的,并不是圆越大信息越多,故每个磁道的位密度都不同。

3.4.2.3 平均存取时间

注意:

  1. 平均旋转延迟=12×转一圈的时间\text{平均旋转延迟} = \frac{1}{2} \times \text{转一圈的时间}
  2. 传输时间可以根据转速计算,约等于扫过一个扇区的时间,即 转一圈的时间/一圈的扇区数\text{转一圈的时间} / \text{一圈的扇区数}

3.4.2.4 数据传输率

磁盘存储器在单位时间内向主机传送数据的字节数,称为数据传输率。

假设磁盘转数为 rr(转/秒),每条磁道容量为 NN 个字节,则数据传输率为 Dr=rND_{r} = rN

3.4.3 磁盘地址

3.4.4 磁盘工作过程

硬盘的主要操作是寻址、读盘、写盘。每个操作都对应一个控制字,硬盘工作时,第一步是取控制字,第二步是执行控制字。

硬盘属于机械式部件,其读写操作是串行的,不可能在同一时刻既读又写,也不可能在同一时刻读两组数据或写两组数据。

3.4.4.1 改进:磁盘阵列

和低位交叉的思想类似,实现并行访问

  • RAID0 把连续多个数据块交替地存放在不同物理磁盘的扇区中,几个磁盘交叉并行读写,不仅扩大了存储容量,而且提高了磁盘数据存取速度
    • 但 RAID0 没有容错能力
  • RAID1 是为了提高可靠性,使两个磁盘同时进行读写,互为备份,提供了容错
    • 但是两个磁盘完全一致,意味着总容量减少一半,成本大。
  • 之后 RAID 通过数据校验,保证安全性,且级数越大,冗余信息越少,成本越低。

3.4.5 固态硬盘

SSD 基于闪存技术(Flash Memory),属于电可擦除ROM(即EEPROM)。

组成:

  1. 有闪存翻译层(负责翻译逻辑块号,找到对应页)
  2. 存储介质为多个闪存芯片
    1. 每个芯片含多个块,每个块含多个页。

SSD 的读写是以为单位的,而磁盘是以 扇区为单位。

  • SSD 的若干页组成的一个块,相当于磁盘中的一个磁道

读写性能特性:

  • 为单位读/写(相当于磁盘“扇区”);
  • 为单位擦除,擦干净的块中每页可写一次、读无限次
  • 支持随机访问,能通过电路由逻辑地址迅速定位物理地址;
  • 读快、写慢
    • 如果写的页若有数据,由于写入需要擦除一整块的数据,所以需将块内其他页复制到新擦除块后,再写入新页
    • 同时,闪存翻译层会把地址映射到新的块

与机械硬盘相比的特点:

  • 读写速度快、随机访问性能高,靠电路控制访问位置
    • 机械硬盘靠移动磁臂和旋转磁盘,有寻道时间和旋转延迟
  • 安静无噪音、耐摔抗震、能耗低但造价更贵
  • SSD的“块”擦除次数过多可能损坏,机械硬盘扇区不会因写次数多损坏。

磨损均衡技术:

  • 思想是将“擦除”平均分布在各块以提升使用寿命
  • 动态磨损均衡是写入数据时优先选累计擦除次数少的新闪存块
  • 静态磨损均衡是SSD监测并自动进行数据分配、迁移,让老闪存块承担以读为主的存储任务,较新闪存块承担更多写任务。

3.5 高速缓冲存储器 Cache

3.5.1 Cache 基本原理

3.5.1.1 局部性原理

时间局部性:一个内存位置被重复引用 空间局部性:一个内存位置被引用后,其附近的位置也很快被引用

由于存在空间局部性,所以 Cache 是一种高效的设置。

对于连续排列的数组数据,按列优先访问的形式 B(会跳着访问),显然空间局部性更差。

而正常连续访问的方式 A 的访问时间会短,因为周围数据都在 Cache 中。

3.5.1.2 性能分析

  1. Cache 和 主存同时访问
  2. Cache 未命中之后,再访问主存

3.5.1.3 按块交换

  1. 将主存的存储空间“分块”,e.g. 每1KB为一块。
  2. 主存与 Cache 之间以为单位进行数据交换。
    1. Cache块大小与主存块大小相同
      1. 但是数量不同,故主存块号和 Cache块号(行号)的位数不同
    2. 注意,CPU 与 Cache或主存 之间以为单位传送信息

自然地,主存地址块号 + 块内地址组成。

  • 主存地址就是主存物理地址

3.5.1.4 Cache 行

  • 计算题:Cache 容量、地址映射表大小

一个 Cache 行分为: 控制算法位 + 数据部分

  • 控制算法位:有效位 + 替换算法位 + 脏位 + 标记位(tag)
    • 地址映射表就是指所有行的控制算法位
    • 脏位也叫一致性维护位
    • 不同的映射算法,标记位长度也不同

Cache 容量=Cache 行位数行数\text{Cache 容量} = \text{Cache 行位数} * \text{行数}

Cache 冲突:两个主存单元映射到同一个 Cache 行

  • 对于组相联,同一组号即算冲突

3.5.2 Cache 与主存的映射

三种映射方式:

  1. 全相联映射:任意位置
  2. 直接映射:每个主存块有一个特定的位置
  3. 组相联映射:每个主存块可以放到一个特定的组

注意,不仅需要标记位,还需要有效位。

3.5.2.1 全相联映射

  1. 主存地址的前22位对比 Cache 中的所有块的标记 1. 主存块号(高22位)在 Cache 中 且有效位 = 1,则 Cache 命中。2. 未命中则正常访问主存

3.5.2.2 直接映射

  1. 根据主存块号的后3位确定 Cache 行
    1. 若主存块号的前19位与Cache标记匹配 且 有效位 = 1,则 Cache 命中
    2. 若未命中或有效位=0,则正常访问主存

  • 缺点:不同主存块对应同一 Cache 位置时,浪费其余空闲空间
  • 由于块在 Cache 中的位置恰对应主存块号的低3位,所以标记位只用存19位。- 主存块号 = 标记位 + Cache行号

3.5.2.3 组相联映射

  1. 根据主存块号的后2位确定所属分组号
    1. 若主存块号的前20位与分组内的某个标记匹配且有效位 = 1, 则 Cache 命中
    2. 若未命中或有效位=0,则正常访问主存

  • 2路组相联映射:2块一组
  • 组相联综合性能最好
  • 主存块号 = 标记位 + Cache组号

3.5.3 Cache 替换算法

  1. 随机算法
  2. 先进先出 FIFO
  3. 近期最少使用 LRU 1. Least Recently Used 2. 基于局部性原理,性能最好 3. 规则 1. 命中时,所命中的行的计数器清零,比其低的计数器加 1,其余不变 2. 未命中且有空闲行时,新装入行的计数器置 0,其余非空闲行全加 1 3. 未命中且无空闲行时,计数值最大的行被淘汰,新装行的计数器置 0,其余全加 1
  4. 最不经常使用 1. Least Frequently Used 2. 规则 1. 新调入的块计数器置 0,之后每被访问一次计数器 + 1 2. 需要替换时,选择计数器最小的一行

实际做题中,不用模拟计数器,替换的时候按照策略很容易判断哪个该替换。

3.5.4 Cache 写策略

CPU 对 Cache 的写操作可能导致 Cache 与主存的数据不一致,为了解决这个一致性问题,引入了以下的写策略。

3.5.4.1 写命中

  1. 写回法
    1. write-back,适合访问密集
    2. 当 CPU 对 Cache 写命中时,只修改 Cache 的内容,而不立即写入主存,只有当此块被换出时才写回主存
      1. 脏位标记 Cache 块是否被修改,修改过的才需要写回
  2. 全写法1. 写直通法,write-through,适合安全性高2. 当CPU对Cache写命中时,必须把数据同时写入Cache和主存 1. 一般使用写缓冲(write buffer)访存次数增加,速度变慢,但更能保证数据一致性 1. 使用写缓冲,CPU 写的速度很快,若写操作不频繁,则效果很好。若写操作很频繁, 可能会因沩写缓冲饱和而发生阻塞

3.5.4.2 写未命中

  1. 写分配法
    1. write-allocate
    2. 当CPU对Cache写不命中时,把主存中的块调入Cache, 在Cache中修改
    3. 搭配写回法使用
  2. 非写分配法
    1. not-write-allocate
    2. 当CPU对Cache写不命中时只写入主存,不调入Cache。
    3. 搭配全写法使用

3.5.5 其他

3.5.5.1 多级 Cache

3.5.5.2 Cache 比较器

  1. 几路组相联需要几个比较器
  2. 比较器位数 = 标记位位数

3.6 虚拟存储器

  • 主存和辅存的关系可类比 Cache 和主存

主存和辅存构成了虚拟存储器,虚拟存储器具有主存的速度和辅存的容量。

  • 虚地址
    • 逻辑地址
    • 用户编程允许涉及的地址
  • 实地址
    • 物理地址
    • 对应主存地址空间

CPU 使用虚地址时,先判断这个虚地址是否在主存中

  • 已在主存中,则通过地址变换,直接访问实际物理地址
  • 不在主存中,则把包含这个地址的一页/段调入主存,再访问
  • 主存已满,则采用替换算法

对于虚拟存储器,访问辅存的代价很大,所以

  • 采用写回法,不用每次访问辅存
  • 采用全相联映射

3.6.1 页式虚拟存储器

  • 以页为基本单位
  • 主存空间的页称作物理页、实页
  • 虚拟空间的页称作虚拟页、虚页

页表实现了虚拟地址物理地址的转换。

3.6.1.1 快表 TLB

快表就是页表的 Cache,存放经常访问的页。

4 指令系统

4.1 指令基础

4.1.1 ISA

指令系统是指令集体系结构(ISA) 中最核心的部分。

ISA 规定的内容主要包括:

  • 指令格式,指令寻址方式,操作类型,以及每种操作对应的操作数的相应规定
  • 操作数的类型,操作数寻址方式,以及是按大端方式还是按小端方式存放
  • 程序可访问的通用寄存器编号、个数和位数,存储空间的大小和编址方式
  • 指令执行过程的控制方式等,包括程序计数器、条件码定义等

4.1.2 指令基本格式

  • 指令 = 操作码 + 地址码
  • 指令一般是字节大小的整数倍!

指令系统主要有以下四种常见的分类。

4.1.2.1 按地址码分类

零地址

一地址

二三地址

四地址

4.1.2.2 按指令长度分类

  • 指令字长:一条指令的总长度(可能会变)
  • 机器字长:CPU进行一次整数运算所能处理的二进制数据的位数(通常和ALU直接相关)
  • 存储字长:一个存储单元中的二进制代码位数(通常和MDR位数相同)

半字长指令、单字长指令、双字长指令:指令长度是机器字长的多少倍。

指令字长会影响取指令所需时间。例如,如果机器字长=存储字长=16bit,则取一条双字长指令需要两次访存

指令字结构:

  • 定长指令字结构:指令系统中所有指令的长度都相等。
  • 变长指令字结构:指令系统中各种指令的长度不等。

4.1.2.3 按操作码长度分类

  1. 定长操作码
    1. 指令系统中所有指令的操作码长度都相同。
    • 特点:n位 \rightarrow 2n2^n 条指令。
    • 优点:控制器的译码电路设计简单。
    • 缺点:灵活性较低。
  2. 可变长操作码
    1. 指令系统中各指令的操作码长度可变。
    • 特点:不同指令的操作码长度不同。
    • 优点:灵活性较高。
    • 缺点:控制器的译码电路设计复杂。

4.1.2.4 扩展操作码指令格式

定长指令字结构 + 可变长操作码 \rightarrow 扩展操作码指令格式

这种格式结合了定长变长操作码的优点,既保持了一定的灵活性,又简化了译码电路的设计。

4.1.2.5 按操作类型分类

  1. 数据传送类
    1. 进行主存与CPU之间的数据传送
      • LOAD:作用是把存储器中的数据放到寄存器中。
      • STORE:作用是把寄存器中的数据放到存储器中。
  2. 运算类
    1. 算术逻辑操作
      • 算术运算:包括加、减、乘、除、增1、减1、求补、浮点运算等
      • 逻辑运算:包括与、或、非、异或、位操作、位测试、位清除、位求反等
    2. 移位操作
      • 包括算术移位、逻辑移位、循环移位(带进位和不带进位)。
  3. 程序控制类
    1. 转移操作,改变程序执行的顺序
      • 无条件转移:JMP
      • 条件转移
        • JZ:结果为0时转移
        • JO:结果溢出时转移
        • JC:结果有进位时转移
      • 调用和返回:CALL和RETURN
      • 循环
      • 陷阱(Trap)与陷阱指令
  4. 输入输出类(I/O)
    1. 输入输出操作:进行CPU和I/O设备之间的数据传送
      • CPU寄存器与IO端口之间的数据传送(端口即IO接口中的寄存器)。

4.1.3 扩展操作码

  • 不允许短码是长码的前缀
  • 设计思路:从地址码最多的开始分配

e.g. 15 15 15 16

e.g. 15 12 62 32

4.2 寻址方式

寻址分为两大类:

  • 指令寻址:找下一条指令
  • 数据寻址:找本条指令的数据

4.2.1 指令寻址

4.2.1.1 PC

程序计数器 PC 指明下一条要执行的指令的存放地址

  • PC 是当程序执行完一步,自动执行下一句指令的物理硬件
  • PC + 1 发生在取指令后

PC 在 x86中也叫作 IP(Instruction Pointer)

位数计算:

  • 若机器按字寻址,PC 给出下一条指令字的访存地址 (指令在内存中的地址),因此 PC 的位数取决于存储器的字数
    • 若存储器有 2162^{16} 个字,则 PC 至少要 16 位。
  • 若机器按字寻址,指令寄存器 IR 用于接收取得的指令,因此 IR 的位数取决于指令字长

4.2.1.2 顺序 跳跃

指令寻址主要有以下两种情况:

  • 顺序寻址
    • 通过程序计数器 PC + 1,自动形成下一条指令的地址
      • “1” 理解为指令字长,实际加的值会因指令长度、编址方式而不同
      • 比如变长指令,需要先读取操作码,判断指令长度,得到“1”是多少
      • 现代计算机通常是按字节编址,若指令字长 16 位,(PC) + 2
  • 跳跃寻址
    • 通过转移类指令(如相对寻址)实现,可用来实现程序的条件或无条件转移
      • 跳跃:
        • 指下条指令的地址不由 PC 自动给出,而由本条指令给出下条指令地址的计算方式
    • 跳跃分为:
      • 绝对转移,地址码直接指出转移目标地址
      • 相对转移,地址码指出转移目的地址相对于当前 PC 值的偏移量
    • 跳跃的结果是当前指令修改 PC 值,下一条指令仍然通过 PC 给出,CPU 总是根据 PC 的内容去主存取指令

4.2.2 数据寻址

确定本条指令的地址码指明的真实地址

  • 表示的是操作数的地址

4.2.2.1 地址码的组成

地址码按照不同的解读方式,分为 10 种,每种有不同的寻址特征。

  • 下图是一地址指令,多地址同理

地址码 = 寻址特征 + 形式地址

  • 寻址特征:指明属于那种寻址方式(其位数决定了寻址方式的种类)
  • 形式地址 A:不代表操作数的真实地址,需要根据寻址特征的要求转换为对应存储器的地址
  • 有效地址 EA:通过寻址特征和形式地址计算出操作数在存储器中的真实地址

A 既可以是寄存器编号,又可以是内存地址;(A) 表示地址为 A 的单元的内容

4.2.2.2 直接寻址

  • 形式地址 A = 真实地址

  • 有效地址EA = A

  • 优点:简单,不需要计算操作数的地址,指令在执行阶段仅需访存 1 次

  • 缺点:A 的位数限制了该指令操作数的寻址范围,操作数的地址不易修改

4.2.2.3 间接寻址

  • 形式地址 A = 操作数有效地址所在的主存单元的地址
  • 有效地址EA = (A)
  • 寻址过程:去该主存单元取操作数的地址,再去找操作数

image.png

是否是多次间接寻址看操作数的内容第一位是否是1

  • 注意,这是区分间接寻址和多次间接寻址的方式;而寄存器寻址和寄存器间接寻址是直接通过寻址特征区分的

  • 优点:可扩大寻址范围,便于编制程序(方便完成子程序的返回)

  • 缺点:指令在执行阶段要多次访存(1 次间址 2 次访存),执行速度较慢

4.2.2.4 寄存器寻址

  • 形式地址 A = 操作数所在寄存器的编号

  • 有效地址 EA = RiR_i

  • 寻址过程:访问该寄存器,取出操作数

    image.png

  • 优点

    • 指令在执行阶段不用访存,只访问寄存器,执行速度快
    • 指令字长较短
      • 因为寄存器数量远小于内存单元数,地址码位数较少
  • 缺点

    • 寄存器价格昂贵
    • CPU 的寄存器数量有限

4.2.2.5 寄存器间接寻址

  • 形式地址 A = 操作数所在的寄存器的地址

  • 有效地址:EA = (Ri)(R_i)

  • 寻址过程:根据该地址去寄存器中找到操作数的有效地址

    image.png

  • 优点:相比间接寻址,既扩大了寻址范围,又减少了访存次数(执行阶段仅访存 1 次)

  • 缺点:相比寄存器访存,执行阶段需要访存(操作数在主存中)

4.2.2.6 隐含寻址

不直接给出操作数的地址,而是在指令中就隐含操作数的地址。

  • 有效地址:程序指定
  • 寻址过程:
    • 形式地址 A 取出对应的一个操作数
    • 另一个操作数通过隐含寻址方式的指令设置,隐含在 ACC 中

  • 优点:有利于缩短指令字长
  • 缺点:需增加存储操作数或隐含地址的硬件

4.2.2.7 立即寻址

  • 与直接寻址区分

操作数本身直接存放在形式地址中

  • 有效地址: A 就是操作数,也称立即数
  • 寻址过程:
    • 寻址特征为#,代表立即寻址的意思
    • 形式地址写的是操作数 3 的补码(011)

  • 优点不访存,指令执行速度最快
  • 缺点:A 的位数限制了立即数的范围

4.2.2.8 基址寻址

  • 以下三种都是偏移寻址:基址、变址、相对
    • 三者的形式地址 A 都表示偏移量
    • 三者的区别在于偏移的起点(基地址)

基地址是基址寄存器(Base address Register)的内容

  • 有效地址 EA = (BR) + A
  • 寻址过程:程序运行前,CPU 将 BR 的值修改为程序的起始地址(存放在操作系统 PCB 中 )

  • 基址寄存器
    • OS中的重定位寄存器 = 基址寄存器
    • 基址寄存器可以是一个专用寄存器,也可以是指定的某个通用寄存器
    • 面向操作系统,内容由操作系统或管理程序确定,用于解决程序逻辑空间与存储器物理空间的无关性
    • 程序执行过程中,基址寄存器内容不变(作为基地址),形式地址可变(作为偏移量)
    • 采用通用寄存器时,可由用户决定哪个寄存器,但其内容仍由操作系统确定
      • 需要额外占用若干bit指明需要哪个通用寄存器
  • 优点
    • 可以扩大寻址范围(基址寄存器的位数大于 A 的位数)
    • 用户不用操心程序的内存位置,只管写程序即可
      • 有利于多道程序设计
        • 多道程序设计:在一台计算机的内存中,同时装入多道程序(多个作业)
      • 可用于编制浮动程序
  • 缺点:偏移量(A)的位数较短

4.2.2.9 变址寻址

与基址类似,区别是:

  1. 变址寄存器的内容可以被用户修改
  2. 形式地址作为基地址,而变址寄存器的内容作为偏移量
  • 有效地址 EA = A + (IX)

  • 优点

    • 可以扩大寻址范围
      • 变址寄存器的位数大于 A 的位数
    • 适合循环程序
      • 数组处理过程中,可设定 A 为数组的首地址,不断改变 IX 的内容,便可很容易形成数组中任意一个数据的地址
    • 偏移量的位数足以表示整个存储空间

基址 + 变址 的复合寻址:

  1. 先基址寻址:EA = (BR) + A
  2. 再变址寻址:EA = A + (IX)
  3. 最终有效地址:EA = ((BR) + A) + (IX)

4.2.2.10 相对寻址

基地址是 PC 的内容

  • 有效地址:EA = (PC) + A
    • A 可正可负,补码表示
    • A 的位数决定操作数的寻址范围

  • 优点
    • 操作数的地址不是固定的,随 PC 值的变化而变化,与指令地址之间总是相差一个固定的偏移量,因此便于程序浮动
      • e.g. 一段for循环代码移动位置
    • 广泛应用于转移指令

4.2.2.11 堆栈寻址

操作数存放在堆栈中,隐含使用堆栈指针 SP 作为操作数地址

  • SP:Stack Pointer 是一个寄存器

e.g. 一次加法操作的堆栈寻址

  • 有效地址:99入栈 / 出栈时 EA 的确定方式不同
  • 堆栈
    • 后进先出的一块存储区
    • 该存储区中被读 / 写单元的地址是用堆栈指针 SP 给出
    • 硬件自动完成 SP 的加减操作
      300
    • 硬堆栈:寄存器堆栈,成本较高,不需要访存,不适合做大容量堆栈
    • 软堆栈:从主存中划出一段区域,执行阶段访存 1 次,通常采用软堆栈

4.2.2.12 总结

  • 速度方面:立即寻址 > 寄存器寻址 > 直接寻址 > 寄存器间接寻址 > 间接寻址

注意,以上的访存次数是指指令执行期间,不包括取指令。

4.2.3 补充:硬件的比较跳转

4.3 机器代码

寄存器:

4.3.1 数据传送类

  • MOV dst, src:传送数据(寄存器/内存/立即数之间)
  • PUSH src:把操作数压栈(SP/ESP 减小,内容写入栈顶)
  • POP dst:把栈顶弹出到寄存器/内存(SP/ESP 增大)
  • XCHG dst, src:交换两个操作数的值
  • LEA reg, mem:取内存操作数的有效地址加载到寄存器(常用来计算地址偏移)

4.3.2 算术运算类

  • ADD dst, src:加法
  • SUB dst, src:减法
  • INC dst:加 1increase
  • DEC dst:减 1decrease
  • MUL src:无符号乘法(默认和 AX/EAX 相乘)
    • IMUL src:有符号乘法
  • DIV src:无符号除法(默认被除数在 AX 或 DX:AX 中)
    • IDIV src有符号除法
    • EDX = EAX / src,商存入 EAX,余数存入 EDX
  • NEG dst:取负数
  • CMP dst, src:比较(本质是 SUB,结果不保存,只改标志位)

4.3.3 逻辑运算类

  • AND dst, src:按位与
  • OR dst, src:按位或
  • XOR dst, src:按位异或
    • Exclusive OR
  • NOT dst:按位取反
  • TEST dst, src:按位与,只影响标志位,不保存结果

4.3.4 移位/循环移位类

  • SHL dst, n:逻辑左移
    • Shift Left
    • 将 dst 左移 n 位,放回 dst
  • SHR dst, n:逻辑右移(高位补 0)
  • SAL dst, n:算术左移
  • SAR dst, n:算术右移(高位补符号位)
  • ROL dst, n:循环左移
  • ROR dst, n:循环右移
  • RCL dst, n:带进位循环左移
  • RCR dst, n:带进位循环右移

4.3.5 转移控制类

4.3.5.1 无条件转移

  • JMP label:无条件跳转

4.3.5.2 条件转移(重点)

根据 标志寄存器(ZF, CF, SF, OF 等) 跳转:

  • JE/JZ label:等于 / 为零时跳转
  • JNE/JNZ label:不等于 / 非零时跳转
  • JC:进位时跳转
  • JNC:无进位时跳转
  • JS:负数(符号位=1)时跳转
  • JNS:非负时跳转
  • JG/JNLE:大于(有符号)
    • Jump when Greater than
  • JGE:大于等于
    • Jump when Greater than or Equal to
  • JL/JNGE:小于(有符号)
  • JLE:小于等于
    • Jump when Less than or Equal to
  • JA:大于(无符号)
  • JB:小于(无符号)

e.g. 一个 if 判断

e.g. 循环

  • LOOP:等价于 自减 + 比较 + 跳转
    • 指定 ECX 作为

4.3.6 子程序调用与返回

  • CALL label:调用子程序(把返回地址压栈,然后跳转)
  • RET:从子程序返回(把返回地址弹栈,跳回调用点)
  • INT n:软中断
  • IRET:中断返回

当前函数的栈帧位于栈顶

  • 栈顶是低地址,栈从高往低增长
  • x86 系统中,默认以4字节为栈的操作单位

call ret 具体过程:

  1. call
    1. 把 IP(原函数下一条指令位置)压栈
    2. 设置新 IP
    3. 显式:这一步可以用 ENTER 命令替代
      1. push 原函数的 EBP
      2. 设置新函数栈底
  2. leave
    1. 效果是让 EBP 和 ESP 指向上一层函数的栈底和顶
  3. ret 1. 把 IP 旧值出栈

4.3.7 栈帧内部详解

区域内部实现从低往高增长:

  • 局部变量区:越先定义的变量,越靠近栈顶,自顶向底是从低往高
  • 调用参数区:越靠前的参数,越靠近栈顶

e.g. 汇编代码过程

4.3.8 其他

  • 非重点
  1. 字符串处理
  • MOVS:内存块传送
  • LODS:装载字符串元素
  • STOS:存储字符串元素
  • SCAS:扫描字符串
  • CMPS:比较字符串
  1. 标志寄存器相关
  • CLC:清进位标志 CF=0
  • STC:置进位标志 CF=1
  • CLD:清方向标志(DF=0,字符串操作自增)
  • STD:置方向标志(DF=1,字符串操作自减)

4.3.9 补充 AT&T 格式

  • 一般不考

4.4 CISC 和 RISC

4.4.1 复杂指令系统计算机(CISC)

  • 设计思路:一条指令完成一个复杂的基本功能
  • 代表:x86 架构,主要用于笔记本、台式机等
  • 指令系统:复杂庞大
  • 指令数目:一般大于 200 条
  • 指令字长:不固定,指令格式多,寻址方式多
  • 可访存指令:不加限制
  • 各种指令执行时间:相差较大,大多数指令需要多个时钟周期才能完成
  • 各种指令使用频度:相差很大
  • 通用寄存器数量:较少
  • 目标代码:难以用优化编译生成高效的目标代码程序
  • 控制方式:绝大多数为微程序控制
  • 指令流水线:可通过一定方式实现
  • 兼容性:可兼容很多不同的高级语言和软件

4.4.2 精简指令系统计算机(RISC)

  • 设计思路:一条指令完成一个基本“动作”,多条指令组合完成一个复杂的基本功能
  • 代表:ARM 架构,主要永远手机、平板等
  • 指令系统:简单精简
  • 指令数目:一般小于 100 条
  • 指令字长:定长,指令种类少,寻址方式种类少
  • 可访存指令:只有 Load / Store 指令
  • 各种指令执行时间:绝大多数在一个周期内完成
  • 各种指令使用频度:都比较常用
  • 通用寄存器数量:多
  • 目标代码:采用优化的编译程序,生成代码较为高效
  • 控制方式:绝大多数为组合逻辑控制,硬布线
  • 指令流水线:必须实现
  • 兼容性:较差

和 CISC 相比,RISC 的优点体现在:

  • RISC 更能充分利用 VLSI(超大规模集成电路)芯片的面积
  • RISC 更能提高运算速度
  • RISC 便于设计,可降低成本,提高可靠性
  • RISC 有利于编译程序代码优化

5 中央处理器 CPU

5.1 CPU概述

5.1.1 CPU 的功能

  1. 指令控制:
    • 完成取指令、分析指令和执行指令的操作,即程序的顺序控制
  2. 操作控制:
    • 管理并产生由内存取出的每条指令的操作信号
    • 把各种操作信号送往相应的部件,从而控制这些部件按指令的要求进行动作
  3. 时间控制:
    • 严格控制各种操作信号的出现时间、持续时间及出现的时间顺序
  4. 数据加工:
    • 对数据进行算术和逻辑运算
  5. 中断处理
    • 对计算机运行过程中出现的异常情况和特殊请求进行处理

5.1.2 CPU 的基本结构

  1. CPU = 运算器 + 控制器
    • 运算器:对数据进行加工
    • 控制器:负责协调并控制计算机各部件执行程序的指令
    • 又可以细分为 ALU + CU + 寄存器 + 中断系统
  2. CPU = 数据通路 + 控制部件

  • 结合后面几个小节理解

5.1.3 运算器

运算器是计算机对数据进行加工处理的中心,接收从控制器送来的命令并执行相应的动作,对数据进行加工和处理。

5.1.3.1 运算器组成

  • 算术逻辑单元(ALU)
    • 进行算术 / 逻辑运算
  • 通用寄存器组(GPRS)
    • 如 AX,BX,CX,DX,SP
    • 用于存放操作数和各种地址信息,所以其位数与机器字长相等
    • SP 是堆栈指针,用于指示栈顶的地址
  • 暂存寄存器
    • 暂存从数据总线或通用寄存器读来的操作数
    • 对应用程序员透明
  • 累加寄存器(ACC)
    • 是一个通用寄存器
    • 暂放 ALU 运算的结果信息,可作为加法运算的输入端
  • 程序状态字寄存器(PSW)
    • PSW 存放程序状态字(标志位的组合),用于保存系统的运行状态
    • PSW 包括状态标志和控制标志
    • 溢出标志 OF,符号标志 SF,零标志 ZF,进位标志 CF
    • 中断标志,陷阱标志
  • 移位寄存器(SR)
    • 对操作数或运算结果进行移位运算
  • 计数器
    • 控制乘除运算的操作步数

5.1.4 控制器

控制器负责协调并控制计算机各部件工作。

控制器的基本功能:

  • 取指令
  • 分析指令
    • 操作码译码(分析本条指令要完成什么操作),产生操作数的有效地址
  • 执行指令
    • 根据分析指令得到的“操作命令”和“操作数地址”,形成操作信号控制序列
  • 中断处理
    • 管理总线及输入输出;处理异常情况(如掉电)和特殊请求(如打印机请求打印一行字符)

5.1.5 CPU 寄存器

按汇编语言(或机器语言)程序是否可以访问

用户可见的寄存器:

  • 可对这类寄存器编程
  • 使用这类寄存器可减少对主存储器的访问次数
  • 如:通用寄存器(含基址 / 变址)、程序状态字寄存器、程序计数器、累加寄存器、移位寄存器

用户不可见的寄存器:

  • 对用户透明,不可编程
  • 被控制部件使用,以控制 CPU 的操作
  • 保留各种状态信息:溢出标志 OF,符号标志 SF,零标志 ZF,进位标志 CF
  • 如:存储器地址寄存器、存储器数据寄存器、指令寄存器、暂存寄存器

5.1.5.1 控制器组成

  • 程序计数器(PC)
    • 用于指出下一条指令在主存中的存放地址(PC 总是存放指令地址)
    • PC 有自增功能
    • PC 的值会根据 CPU 在执行指令过程中自增或转移到程序的某处 (跳转指令)
    • PC 的位数 = 主存储器地址位数,因为 PC 就是存地址的
  • 指令寄存器(IR)
    • 用于保存当前正在执行的那条指令
    • IR 的位数取决于指令字长
  • 指令译码器(ID)
    • 仅对操作码字段进行译码,以确定指令的操作功能
  • 存储器地址寄存器(MAR)
    • 存放要访问的主存储器单元的地址
    • MAR 的位数 = 主存储器地址线位数
  • 存储器数据寄存器(MDR)
    • 存放向主存储器写入的信息或从主存储器读出的信息
    • MDR 的位数 = 存储字长
  • 微操作信号发生器
    • 根据 IR 的内容 (指令),PSW 的内容 (状态信息) 和时序信号产生控制计算机系统所需的各种控制信号
    • 有组合逻辑型和存储逻辑型
  • 时序系统
    • 用于产生各种时序信号,都由统一时钟 CLOCK 分频得到

5.1.6 数据通路简介

5.1.6.1 专用数据通路方式

根据指令执行过程中的数据和地址的流动方向安排连线线路

  • 使用多路选择器控制一路的输出
  • 使用三态门控制输出
  • 优点:性能较高,基本不存在数据冲突现象
  • 缺点:结构复杂,硬件量大,不易实现

5.1.6.2 CPU 内部单总线方式

将所有寄存器的输入端和控制端都连接到一条公共通路

  • 优点:结构简单,容易实现
  • 缺点
    • 传输存在较多冲突现象,性能较低
    • 需要暂存寄存器

5.2 指令执行

5.2.1 指令周期

指令周期 = 取指周期 + 执行周期

5.2.1.1 周期概念辨析

几个周期的关系:

  1. 若干 CPU 时钟周期 / 节拍 / CLK / T周期 组成 一个机器周期
  2. 若干机器周期 组成 一个指令周期

常见指令的指令周期:

5.2.1.2 指令周期流程

  • 用触发器区分是哪个周期

5.2.2 指令周期的数据流

  • 数据流:根据指令要求一次访问的数据序列
  • 指令执行不同阶段,访问的数据序列不同
  • 不同的指令,数据流也不同

5.2.2.1 取指周期

根据 PC 中的内容从主存中取出指令代码并放在 IR 中

数据流向:

  1. PC to MAR to 地址总线 to 主存
  2. CU 发出读命令 to 控制总线 to 主存
  3. 主存 to 数据总线 MDR to IR(存放指令)
  4. CU 发出控制信号 to PC + 1

image.png

5.2.2.2 间址周期

取操作数的有效地址

以一次间址为例,将指令中的地址码送到 MAR 并送至地址总线,此后 CU 向存储器发出读命令,以获取有效地址并存至 MDR。

数据流向:

  1. Ad(IR / MDR) to MAR to 地址总线 to 主存
  2. CU 发出读命令 to 控制总线 to 内存
    1. 用形式地址去读有效地址
  3. 主存 to 数据总线 to MDR
    1. 成功读出有效地址,并存放在MDR
  4. 有效地址 to 指令的地址码字段

image.png

5.2.2.3 执行周期

取操作数,并根据 IR 中的指令字的操作码通过 ALU 操作产出执行结果

数据流向:不同指令操作不同,无统一的数据流向

5.2.2.4 中断周期

处理中断请求

假设程序断点存入堆栈中,并用 SP 指示栈顶指针,而且进栈操作是先修改指针,后存入数据;出栈操作是先删除数据,后修改指针

数据流向:

  1. CU 控制 SP - 1,修改后的 SP to MAR to 地址总线 to 主存
    1. 进栈需要先修改栈顶指针
  2. CU 发出写命令 to 控制总线 to 主存
    1. 保存断点(PC)到栈顶(SP)
  3. PC to MDR to 数据总线 to 主存
    1. 写操作
  4. CU 修改 PC 为中断服务程序的入口

image.png

5.2.3 指令的执行方案

5.2.3.1 单周期处理器

每条指令都在固定的时钟周期内完成,CPI = 1。

指令周期取决于执行时间最长的指令的执行时间。

  • 特点:串行,相同执行时间

5.2.3.2 多周期处理器

指令需要几个周期就为其分配几个周期,可以选用不同个数的时钟周期来完成不同指令的执行过程(CPI > 1)。

  • 特点:串行,不同执行时间

5.2.3.3 流水线处理器

在每一个时钟周期启动一条指令,尽量让多条指令同时运行,但各自处在不同的执行步骤中。

尽量让多条指令同时运行,但各自处在不同的执行步骤中。

  • 特点:并行

5.3 数据通路

5.4 控制器

5.5 异常和中断

5.6 指令流水线

5.7 多处理器

6 总线

6.1 总线概述

6.2 总线事务和定时

7 IO系统

7.1 IO接口

7.2 IO方式

8 REF

← Previous postVibe Coding Guidance