27 408考研

计算机组成原理

part1: 计算机发展历程

  • 硬件:指计算机系统中由电子元器件和机械装置构成的实体。根据冯·诺依曼结构,经典硬件包含五大部分:运算器、控制器、存储器、输入设备、输出设备

  • 软件:指为解决特定问题而编制的程序及其相关文档。分为:

    • 系统软件:用于管理计算机资源(如操作系统、数据库管理系统、编译器)。
    • 应用软件:解决用户具体需求的程序(如微信、Civilization VI)。
  • 核心公式

    计算机系统 = 硬件 + 软件

    软硬件逻辑等效性:任何由软件完成的动作,逻辑上也可以通过硬件实现;反之亦然(例如:乘法可以用专门的乘法器硬件实现,也可以用软件多次加法模拟)。

选择题常见陷阱

  • 陷阱一:系统软件和应用软件的区分。

    • 纠正编译器、汇编器、解释器属于系统软件,不是应用。
  • 陷阱二:硬件和软件的界限是绝对的吗?

    • 考点逻辑等效性。硬件实现通常速度快、成本高;软件实现速度慢、灵活性高
  • 陷阱三:翻译程序的区别。

    • 考点编译程序(生成目标代码) vs 解释程序(逐句翻译不生成目标代码)。

part2: 冯·诺依曼机体系结构

冯·诺依曼机最核心的思想是 “存储程序”。其体系结构包含以下五个要点:

  1. 五大部件:运算器、控制器、存储器、输入设备、输出设备。
  2. 指令与数据同等地位:指令和数据都以二进制形式存放在存储器中, CPU 根据指令周期的不同阶段来区分它们(取指阶段取的是指令,执行阶段取的是数据)。
  3. 按地址寻址:指令在存储器中按顺序存放,由程序计数器(PC)指明执行顺序。
  4. 指令结构:由 操作码(OP)地址码(AD) 组成。
  5. 以运算器为中心:这是早期冯·诺依曼机的典型特征(现代计算机已改为以存储器为中心)。

我们可以把早期的冯·诺依曼机比作一个 “极其死板的加工厂”

  • 存储器(仓库):里面堆满了盒子。有的盒子里装的是“零件”(数据),有的盒子里装的是“说明书”(指令)。最离谱的是,这些盒子外观一模一样!
  • 控制器(调度员):他只认“地址”。他去 1 号盒子拿说明书,看一眼,发现写着“去 5 号盒子拿零件”。
  • 运算器(加工车间):由于它是中心,所有进出的货(数据)都必须先经过这个车间。
  • 输入/输出(大门):原材料进来,成品出去。

💡 直觉解释: 为什么叫“存储程序”?因为在冯氏机之前,改个功能得重新接电线(硬连线);有了它,只需要换一下“仓库”里的指令序列(软件),机器就能变功能。

选择题陷阱(高频!)

  • 区分指令和数据:计算机靠什么区分存储器里的二进制是指令还是数据?

    • 错误答案:靠标志位、靠不同的存储空间。
    • 正确答案:靠指令周期的不同阶段(取指阶段取的是指令,执行阶段取的是数据)。
  • 中心地位的演变

    • 早期:以运算器为中心(数据传输都要经过运算器,效率低)。
    • 现代:以存储器为中心(为了解放 CPU,发展出了 DMA 等技术)。

2. 大题常见问法

  • 在分析指令执行流时,会让你写出数据流经哪些部件。记住:在早期模型中,数据从输入设备进来,必须先去运算器,不能直接去存储器。

3. 容易丢分的地方

  • 忽略了二进制表示。考纲要求明确:冯·诺依曼机的所有信息均采用二进制表示。

主存储器

主存储器主要由 存储体(Storage Body)地址寄存器(MAR)数据寄存器(MDR) 以及 时序控制逻辑 组成。

  1. 存储体:由许多存储单元(Storage Unit)组成,每个单元包含若干个存储元(存放 0 或 1 的电容/触发器)。
  2. 存储单元:存放一串二进制代码,这串代码称为存储字(Storage Word)
  3. 存储字长:一个存储单元中二进制代码的位数。
  4. MAR(Memory Address Register):主存地址寄存器。其位数对应存储单元的个数(若 MAR 为 n 位,则有 2^n 个单元)。
  5. MDR(Memory Data Register):主存数据寄存器。其位数等于存储字长

主存储器就像一栋巨大的 “酒店大楼”

  • 存储体 = 整个大楼:里面有很多房间(存储单元)。
  • 存储单元 = 具体的房间:每个房间里住着几个客人(二进制位)。
  • 存储字长 = 每个房间能住几个人:如果字长是 16 位,那每个房间就标配 16 个床位。
  • MAR(地址寄存器) = 楼层索引表:如果你要找某个房间,你需要知道它的门牌号。如果门牌号是 10 位的二进制数,那这栋楼最多有 2^10 = 1024 个房间。
  • MDR(数据寄存器) = 搬运工手里的推车:要把房间里的客人(数据)接出来或者送进去,推车的尺寸(MDR 位数)必须和房间里的床位(存储字长)对齐。

选择题核心计算(送分必拿)

  • 公式 1:存储单元个数 = 2^(MAR位数)

    • 例题:某机器 MAR 为 32 位,则其最大寻址空间为 2^32 = 4GB(假设按字节寻址)。
  • 公式 2:总容量 = 存储单元个数 × 存储字长。

    • 注意:区分“位(bit)”和“字节(Byte)”。1 Byte = 8 bit。

2. 易错点提醒

  • MAR/MDR 的位置:在 408 不同的教材体系里,有的说 MAR/MDR 在 CPU 内部,有的说在主存内部。现代 CPU 已经把 MAR 和 MDR 集成在内部了,但在逻辑结构图里,它们依然被视为 CPU 与主存交互的桥梁。

  • 按字节寻址 vs 按字寻址

    • 大部分时候默认 按字节(Byte) 寻址。
    • 如果题目说“按字寻址”,你必须把总位数除以字长。

运算器

核心组成部件:

  1. ALU(算术逻辑单元):运算器的“心脏”,负责具体的计算逻辑。
  2. ACC(累加寄存器):最重要的寄存器。用于暂时存放操作数或运算结果。
  3. MQ(乘商寄存器):在乘、除法运算时,用于存放乘数、商或余数。
  4. X(操作数寄存器):存放除被乘数、被除数之外的操作数。
  5. PSW(状态条件寄存器/程序状态字):存放运算结果的特征(如是否溢出、是否有进位、结果是否为负)。

想象运算器是一个 “全自动厨卫加工机”

  • ALU(灶台/炒锅):真正生火做菜的地方,不管是炒(加法)还是煮(减法),都在这儿发生。
  • ACC(主餐盘):它是最忙的。刚炒好的菜(结果)先放在这儿,准备下锅的肉(被乘数)也先放在这儿。
  • MQ(备用盘):当要做大菜(乘除法)时,主餐盘装不下了,就把剩下的材料临时堆在 MQ 里。
  • X(调料碟):放第二个配料的地方。
  • PSW(质检报告):菜做好了,它是咸了(溢出)还是淡了(结果为 0),由 PSW 记录。

控制器

核心组成部件:

  • PC(程序计数器,Program Counter):存放下一条将要执行指令的地址。具有自增功能((PC)+1→PC)。
  • IR(指令寄存器,Instruction Register):存放当前正在执行的指令。
  • CU(控制单元,Control Unit):分析 IR 中的指令,发出微操作控制信号序列,指挥全机动作。
  • MAR 和 MDR:虽然逻辑上属于主存,但在现代 CPU 中,MAR 和 MDR 是由控制器直接控制的。

控制器就像是加工厂里的 “总调度室”

  • PC(待办清单索引):调度员手里的小本子,上面只写着:“下一个任务在仓库的第几个货架”。每领走一个任务,他就把号码加 1,指向下一个。
  • IR(正在处理的图纸):从仓库取回来的指令(图纸)就摊在桌子上看。这就是 IR。
  • CU(调度总监):总监盯着 IR 里的图纸看(译码),然后拿起大喇叭喊:“运算器,你去做加法!”“主存,把你那个数传过来!”

考试怎么考?

选择题陷阱:PC 的变化时机(极高频!)

  • 陷阱:PC 是在指令执行完才加 1 吗?
  • 纠正不是! CPU 一旦取出指令,PC 就会立即自增,指向下一条地址。这样在执行当前指令的同时,就已经为下一条做好了准备。

2. 指令执行过程(数据流大题必考)

你要能闭眼写出“取指周期”的动作:

  1. (PC)→MAR(把地址给仓库索引)
  2. M(MAR)→MDR(从仓库取出指令到推车)
  3. (MDR)→IR(把指令放到调度室桌上)
  4. (PC)+1→PC(小本子翻页)
  5. CU 译码,发出信号。

3. 容易丢分的地方

  • 区分“地址”和“内容”:PC 存的是地址,IR 存的是指令本身。

  • 程序员可见性

    • 可见:PC(你可以通过跳转指令改它)。
    • 不可见:IR、MAR、MDR(这些是硬件自动流转的,程序员写代码控制不了)。

计算机的多级层次结构

想象一个 “跨国公司” 的运作流程:

  • M4 高级语言(老板):只发口令:“我们要增加利润!”(一行代码 profit++)。
  • M3 汇编语言(经理):把老板的口令翻译成具体步骤:“去查账目,去收余款,把钱加起来”。
  • M2 操作系统(秘书):处理杂事,比如申请办公场地(内存)、调用打印机(I/O)。
  • M1 机器语言(员工):只认死理,动作只有 0 和 1(搬东西、放东西)。
  • M0 微程序(员工的肌肉纤维):控制手部肌肉如何收缩来完成搬东西的动作。

直觉解释: 每一层都为上一层提供了 “遮蔽层”(封装)。高级语言程序员不需要知道 CPU 里的寄存器叫什么,因为编译器和操作系统帮你处理好了。

【考试怎么考】

1. 选择题陷阱:程序员的视角
  • 考点:机器语言、汇编语言程序员能看到什么?
  • 真相:他们能看到 PC(程序计数器)通用寄存器状态位
  • 陷阱:高级语言程序员(C/Java)看不见寄存器。微程序程序员能看到微指令,但机器语言程序员看不见微指令。
2. 翻译程序的区别
  • 汇编程序:M3 → M1(助记符转二进制)。
  • 编译程序:M4 → M3 或 M1(整本翻译)。
  • 解释程序:M4 → 立即执行(同声传译)。
3. 容易丢分的地方
  • 虚拟机(Virtual Machine):M2、M3、M4 实际上都是虚拟机,因为它们并不是真实存在的硬件,是通过软件包装出来的“逻辑机器”。

计算机的性能指标

【二、核心概念(专业版)】

计算性能指标主要分为时间指标速度指标

1. 基本时间单位

  • 机器字长:计算机一次整数运算能处理的二进制位数。
  • 主频 (f):CPU 内部主时钟的频率。单位:Hz(如 3.0GHz)。
  • 时钟周期 (T):主频的倒数,T = 1/f。它是 CPU 最小的时间单位

2. 核心性能公式(背诵核心!)

  • CPI (Cycles Per Instruction):执行一条指令所需的时钟周期数

    • 注意:一条指令可能由多个微动作组成,所以 CPI 往往大于 1。
  • CPU 执行时间:执行一段程序所需的时间。

    CPU 时间 = CPU 时钟周期数 ÷ 主频 = (指令条数 × CPI) ÷ 主频

  • MIPS (Million Instructions Per Second):每秒执行多少百万条指令。

    MIPS = 指令条数 ÷ (执行时间 × 10^6) = 主频 ÷ (CPI × 10^6)

  • MFLOPS (Million Floating-point Operations Per Second):每秒执行多少百万次浮点运算

    • 注意:现在的超算通常用 TFLOPS (1012) 或 PFLOPS (1015)。

【三、通俗理解版】

我们可以把“完成一项工作”比作“搬砖”:

  • 主频:你挥动铲子的速度(每秒挥几次)。
  • 时钟周期:挥一次铲子用的时间。
  • CPI:搬一块砖需要挥几次铲子。
  • MIPS:你平均每秒钟能搬多少块砖。

💡 直觉解释: 为什么主频高的电脑不一定快?因为如果它的 CPI 特别高(搬一块砖要挥 100 遍铲子),那即便它挥得快,搬砖效率(MIPS)依然很低。真正的性能看的是“主频 / CPI”的综合结果。


【四、考试怎么考】

1. 选择题常见陷阱(避坑指南)

  • 单位陷阱:408 极其喜欢在单位上做文章。

    • 在描述频率/速度时:K = 10^3M = 10^6G = 10^9
    • 在描述容量/存储时:K = 2^10 (1024)M = 2^20G = 2^30
    • 纠正:计算 MIPS 时,M 必须取 10^6,绝不能取 1024×1024
  • 吞吐量 vs 响应时间

    • 吞吐量:单位时间内完成的工作量(搬了多少砖)。
    • 响应时间:从任务提交到完成的时间(搬完这块砖用了多久)。

2. 典型计算步骤

题目: 已知某机主频为 1GHz,某程序包含 100 条指令,平均 CPI 为 4,求执行时间。

  1. 写出总时钟周期数:100 × 4 = 400 个周期。
  2. 写出周期长度:T = 1/1GHz = 10^-9 s
  3. 得出时间:400 × 10^-9 s = 400 ns

3. 容易丢分的地方

  • 基准测试程序(Benchmark):如 SPECmarks。记住它是用来综合评价性能的,单一的 MIPS 不能代表所有性能。

数制与编码

进位计数制

  • 进位计数制与转换

    • 任意进制转十进制:按位权展开相加。Value=∑(Di​×Ri)。

    • 十进制转R进制

      • 整数部分:“除基取余,逆序排列”。
      • 小数部分:“乘基取整,顺序排列”。
    • 2、8、16进制互转:3位二进制对应1位八进制(23=8),4位二进制对应1位十六进制(24=16)。

  • BCD码(Binary-Coded Decimal)

    • 4位二进制 来表示 1位十进制 数字。
    • 8421码:最常用的BCD码,权值从高到低分别是 8、4、2、1。有效范围是 00001001(即 0~9)。
  • 字符与字符串编码

    • ASCII码:7位有效位表示 128 个字符。存入一个字节时,最高位通常为 0(或用作奇偶校验位)。
    • 汉字机内码:为了和 ASCII 码区分,国标码(GB2312)转机内码时,会将两个字节的最高位都置为 1(即机内码 = 国标码 + 8080H)。
  • 字节序(大小端存储,高频核心!)

    • 当一个多字节数据(如 32 位 int 0x12345678)存入按字节编址的主存时:
    • 大端模式(Big-Endian):最高有效字节(MSB,0x12)存放在低地址。
    • 小端模式(Little-Endian):最低有效字节(LSB,0x78)存放在低地址。

通俗理解

我们可以用生活中的例子来建立直觉:

  • 进制转换的本质:就像打包苹果。十进制是“满 10 个苹果装一箱”,二进制是“满 2 个苹果装一箱”。底层物理器件(电路高低电平)最容易表达 2 种状态,所以机器用二进制。

  • BCD码的直觉(给十进制穿马甲):人类看二进制太反人类了,还是习惯十进制。BCD码就是给 0~9 这十个数字,强行套上一件“4位二进制”的马甲。比如 9 穿上马甲就是 1001。它本质上按十进制逢十进一,只是表面长得像二进制。

  • 大小端存储的直觉(排队进小房间): 假设数据 0x12345678 是一个大胖子,12 是头,78 是脚。主存是一排只能挤进一个部位的单间(1个字节)。

    • 大端:符合人类从左到右的阅读习惯,“头”先挤进 0 号房(低地址),“脚”最后进 3 号房。这叫**“头重脚轻”**。
    • 小端:“脚”先踏进 0 号房,依次往上。这叫**“脚踏实地”**。x86 架构的电脑大多是小端。

考试怎么考

. 选择题陷阱:十进制小数转换的“无底洞”

  • 坑点:题目问“任何十进制小数都能精确转换为二进制小数吗?”
  • 纠正绝对不能! 例如十进制的 0.1,你不断乘 2 取整,会得到 0.0001100110011... 这是一个无限循环小数。因此,浮点数表示十进制小数必定伴随精度丢失。

2. 选择题陷阱:BCD码的加法“加 6 修正”

  • 坑点:4位二进制有 16 种状态,但 BCD码只用了前 10 个(0~9)。剩下的 1010 (10) 到 1111 (15) 是非法状态
  • 考法:如果两个 BCD 码相加,结果大于 9(落入了非法区),或者产生了向高位的进位,必须给结果**加上 6(即二进制的 0110)**进行修正,才能把多余的 6 个状态跳过去。

3. 大题杀手:大端小端的数据倒置

  • 坑点:给你一段内存地址的数据(低地址到高地址为:78 56 34 12),告诉你这是小端存储,问你原来的 32 位数据是多少。
  • 纠正:很多同学一激动,连字节内部的位也给反转了。记住,大小端只改变“字节”的顺序,绝不改变字节内部的 bit 顺序! 原数据就是 0x12345678

4. 常识记忆:ASCII 与汉字编码的界限

  • 死记硬背:数字 '0' 的 ASCII 是 480x30);大写 'A'650x41);小写 'a'970x61)。
  • 界限:ASCII 码最高位是 0;汉字机内码每个字节最高位必须是 1(防冲突)。只要看到最高位是 1 的字符,大概率是汉字。

定点数的表示

定点数:小数点位置“固定”的数。在计算机中,小数点不占存储空间,是人为约定的(定点整数小数点在最低位之后,定点小数在符号位之后)。

长度为 n(包含 1 位符号位)的四种编码定义:

  1. 原码(Sign-Magnitude)

    • 规则:最高位为符号位(0正,1负),其余各位为数值的绝对值。
    • 范围:−(2n−1−1)∼2n−1−1。
  2. 反码(Ones’ Complement)

    • 规则:正数同原码;负数符号位为 1,数值位全部按位取反
    • 范围:同原码。
  3. 补码(Two’s Complement)(🌟 绝对核心):

    • 规则:正数同原码;负数符号位为 1,数值位反码加 1
    • 范围−2n−1∼2n−1−1(注意!比原码多表示一个极小值)。
  4. 移码(Offset Binary)

    • 规则:只用于表示整数!在真值上加上一个偏置值(通常是 2n−1)。捷径:将补码的符号位取反,即得移码
    • 范围:同补码。

通俗解释

这四种码为什么会被发明出来?咱们从“进化论”的角度秒懂:

  • 原码 = 人类直觉: 就像我们平时写 +5 和 −5。人类看着最爽,但 ALU(运算器)看着想骂人。因为做加法时,如果两数符号不同,ALU 还得比较绝对值大小,再去用大数减小数。太复杂了!
  • 反码 = 失败的试验品: 为了把减法变成加法,科学家发明了反码。但它有个致命缺陷:有两个零(+0 和 -0)。这在数学上是不可忍受的。如今它只是求补码的垫脚石。
  • 补码 = 终极黑客科技: 借用“钟表”的直觉:现在是 10 点,你想拨到 8 点,可以往回拨 2 格(−2),也可以往前拨 10 格(+10),因为钟表一圈是 12(模)。 计算机的位宽也是有模的!用补码,ALU 就不需要减法器了,所有减法都可以转换成加法! 而且,它神奇地把 −0 变成了底限负数(比如 8 位下的 −128),完美利用了所有编码空间。
  • 移码 = 垫高底线的尺子: 补码虽然好算,但不利于比较大小(符号位是 1 的负数反而比 0 的正数小,硬件比对起来很麻烦)。移码就是强行给所有数加上一个很大的正数,把水面垫高,让所有数都变成“非负数”。这样硬件直接从高位到低位逐位比较,谁大谁就真大。所以它专门用来做浮点数的“阶码”(用来比对指数大小)。

考试怎么考

1. 选择题陷阱:零的表示

  • 考点:问你哪些码对 0 的表示是唯一的?
  • 秒杀:原码有 000...0100...0;反码有 000...0111...1只有补码和移码的 0 是唯一的!

2. 大题杀手:不对称的范围(极高频!)

  • 陷阱:8 位补码的范围是 [−128,127]。408 极度喜欢拿 -128 搞事情。
  • 真题套路:问你一个函数 abs(x) 求绝对值,如果传入 x = -128 会怎样?
  • 导师纠错:−128 没有对应的正数(最大只有 127)!所以 −128 求绝对值,补码反转后依然是 -128 自身(引发溢出)。这就是补码的不对称性!

3. 秒杀技巧:负数真值推导(导师独门绝招:负权值法)

不要再去“减一取反”了,慢且容易错! 对于补码 1011 0000,直接把符号位当成负权重,其余位当成正权重: 算式:−128+32+16=−80。三秒钟直接出真值!

4. 常考动作:符号扩展

  • 短位变长位(如 8位 short 强转 16位 int):

    • 无符号数:高位无脑补 0
    • 有符号数(补码):正数补 0负数高位全部补 1!(比如 1011 扩展成 8 位就是 1111 1011)。

定点数的移位运算

把移位想象成**“传送带上的流水线作业”**:

  • 逻辑移位(无情传送带):传送带往前开(左移)或者往后退(右移),掉下边缘的货(比特位)直接扔进垃圾桶,空出来的位置全部放空箱子(补 0)
  • 算术右移(拉伸橡皮筋):对于负数补码,最高位是 1(代表负号)。右移相当于把这个数变小(除以 2),但它必须还是个负数!所以你往右拉扯的时候,最高位的 1 就像粘住了一样,被拉出一长串的 1 来填补高位。这就叫“符号扩展”。
  • 为什么负数补码左移补 0?:因为补码的构造法则是“从右往左数,遇到第一个 1 之前,跟原码一模一样(全是 0)”。既然尾巴跟原码一样,那左移时空出来的低位当然跟原码一样补 0

考试怎么考

1. 选择题陷阱:补码算术左移的“溢出”判定

  • 考点:左移会把高位挤掉,如果挤掉的数包含了有效信息,就会导致数值面目全非(溢出)。

  • 秒杀判定:只要最高数值位和符号位不一致(即 X0​=X1​),左移就一定会溢出!

    • 例如1011 0000(补码,负数)。最高数值位是 0,符号位是 1。左移一位变成 0110 0000,符号变成正数了,严重溢出报错

2. 大题结合 C 语言:<<>> 的猫腻

  • 考点:C 语言代码翻译成底层机器语言。

  • 规则

    • C 语言的左移 <<:不管是 int 还是 unsigned,底层一律是丢高位,低位补 0

    • C 语言的右移 >>

      • 如果是 unsigned(无符号),底层调用逻辑右移(补 0)
      • 如果是 int/short(有符号),底层调用算术右移(补符号位)。这是大题分析数据的死穴!

3. 容易丢分的地方:精度丢失与负数除法的区别

  • 陷阱:算术右移 1 位完全等同于除以 2 吗?
  • 纠正:不完全等同!对于负数奇数(如 -5,补码 1111 1011),算术右移 1 位变成 1111 1101(-3)。但在 C 语言里 -5 / 2 的结果是 -2算术右移是向 −∞ 取整,而 C 语言除法是向 0 取整。遇到这种极品细节题,不要想当然

定点数的加减运算

一】核心概念(用考研语言解释)

1. 原码的加减运算
  • 本质:原码的符号位和数值位是分开处理的。
  • 规则:加法运算时,同号求和,异号求差;减法运算时,将其转化为加法(改变减数的符号位,再按加法规则计算)。求差时,必须先比较绝对值的大小,用绝对值大的减去绝对值小的,最后再决定符号位。
  • 考研视角:在现代计算机中,ALU根本不用原码做加减法,因为逻辑太复杂,需要比较大小还要单独处理符号。408中如果考原码加减法,通常是在概念辨析题里作为干扰项出现,或者考察浮点数的尾数运算(浮点数尾数有时用原码表示并隐藏最高位)。
2. 补码的加减运算
  • 本质:补码的最大优势就是把减法化为加法,并且符号位连同数值位一起参与运算,无需单列逻辑。

  • 核心公式

    • 加法:X+Y 的补码 = X 的补码 + Y 的补码
    • 减法:X−Y 的补码 = X 的补码 + (−Y) 的补码
  • 关键动作:求 (−Y) 的补码:无论 Y 是正数还是负数,已知 Y 的补码求 (−Y) 的补码的方法都是:连同符号位在内,全部按位取反,末位加 1。这是机器底层的硬件实现逻辑(通过一个多路选择器加一个反相器,最后在加法器最低位进位输入设为 1)。

3. 溢出判断
  • 本质:两个数进行加减运算时,运算结果超出了该数据类型所能表示的范围

  • 大前提只有”同号相加”或”异号相减”才可能发生溢出! 正数加负数,或者正数减正数,绝不可能溢出。

  • 三种判断方法(408要求全部掌握):

    1. 单符号位判断法:设 A 的符号为 AS,B 的符号为 BS,结果的符号为 SS。若 AS=BS 且 AS≠SS,则溢出。正+正=负(上溢),负+负=正(下溢)。
    2. 双符号位判断法(变形补码):将符号位扩展为两位。00表示正,11表示负。运算后若符号位为01,则上溢(正变负);若为10,则下溢(负变正)。记住:最高位代表真实的符号,次高位代表错误的运算结果符号。
    3. 进位判断法(最接近硬件本质):设 CS 为符号位产生的进位,C1 为最高数值位向符号位产生的进位。溢出标志 OF = CS ⊕ C1。如果这两个进位不同,说明溢出了。

二】考试常考点(408常怎么出题)

  1. 单纯的补码计算与溢出判断:给出两个十六进制或十进制数,问你运算结果及是否溢出(多出现在选择题前3题)。

  2. 与条件标志位结合考察(高频!):这是命题人最爱的套路。给你一段加减运算,让你判断底层的标志位:

    • OF (Overflow Flag):有符号数的溢出标志。
    • CF (Carry Flag):无符号数的进位/借位标志。
    • SF (Sign Flag):结果的符号位(就是结果的最高位)。
    • ZF (Zero Flag):结果是否全为0。
    • 陷阱:408极爱把 OF 和 CF 混在一起考,一定要死死记住:OF只管有符号数,CF只管无符号数。硬件不管你是什么数,它会同时生成OF和CF,看你怎么解释!
  3. C语言类型转换结合考:把 shortint 混在一起加减,或者把 unsignedint 混在一起,先让你做符号扩展(或者零扩展),然后再算补码加减。


【典型例题】

题目: 某计算机字长为 8 位,采用补码表示。已知 [x]补​=01010101,[y]补​=01000110。计算 x+y 后,结果的符号位是多少?是否发生了溢出?

【一】 题目考察知识点

  1. 补码加法运算规则:[x+y]补​=[x]补​+[y]补​(mod2n) 。+1
  2. 溢出判断的三种逻辑
  • 单符号位法:看操作数与结果符号的一致性。
  • 双符号位法(变形补码):看双符号位是否一致 。+1
  • 进位判断法:比较符号位进位与最高数值位进位 。

【二】 解题思路分析

判断符号位不能只看“加出来的第一位”,必须先判断是否溢出

  • 如果无溢出:加法结果的最高位就是正确的符号位。
  • 如果有溢出:计算出的最高位是“错误”的符号,真实结果超出了表数范围。

【三】 逐步推导过程

  1. 列出算式
1
2
3
4
5
  0101 0101  (正数)
+ 0100 0110 (正数)
------------
1001 1011

  1. 符号位判断(逻辑推演)
  • 方法一:单符号位特征。两个正数(符号位为 0)相加,结果变成了负数(符号位为 1)。
  • 结论:发生了正溢出
  1. 方法二:进位判断法(408最爱考)
  • 最高数值位(第 6 位向第 7 位)的进位 C1​=0。
  • 符号位(第 7 位)向更高位的进位 C0​=0。
  • 计算:V=C0​⊕C1​=0⊕0=0?不对,让我们重新看进位:01010101 的数值高位是 101…01000110 的数值高位是 100…1+1 产生进位到符号位,所以 C1​=1;符号位是 0+0,加上进位 1,结果为 1,不产生向外的进位,所以 C0​=0。
  • 判断:V=C0​⊕C1​=0⊕1=1。V=1 表示有溢出 。+1

【四】 正确答案

  • 计算出的符号位:1
  • 实际意义:发生了正溢出,结果本应为正,但因溢出表现为负。

【五】 考研避坑指南(套路总结)

  1. 符号位“变脸”即溢出
  • 正 + 正 = 负 → 正溢出。
  • 负 + 负 = 正 → 负溢出。
  • 注意:正 + 负 永远不会发生溢出 。
  1. 双符号位(变形补码)判别法
  • 00:结果为正,无溢出 。
  • 11:结果为负,无溢出 。
  • 01:正溢出(第一个 0 表示本应为正,第二个 1 表示实际算成了负) 。
  • 10:负溢出(第一个 1 表示本应为负,第二个 0 表示实际算成了正) 。+1
  1. 硬件实现:在 ALU 中,溢出判断通常由一个异或门实现 。

【六】 举一反三(课后练习)

老师考考你:
若 [x]补​=10000111,[y]补​=10111010,进行 x+y 运算。

  1. 计算出的符号位是多少?
  2. 是否发生溢出?
  3. 这种溢出叫什么?
    请尝试回答,我会根据你的答案给出点评!

三】典型例题分析

题目:设机器字长为 8 位(含 1 位符号位),X=+60, Y=−80。请用补码计算 X−Y,并判断是否发生溢出,同时给出底层 ALU 运算后的 OF 和 CF 标志位的值。

【一】题目考察什么知识点

考察补码的减法运算、求 (−Y) 的补码的规则、溢出判断以及 OF 和 CF 的硬件生成逻辑。

【二】解题思路分析
  1. 先写出 X 和 Y 的原码和补码。
  2. 因为是算 X−Y,我们需要根据 Y 的补码求出 (−Y) 的补码。
  3. 将 X 的补码与 (−Y) 的补码相加,记录符号位进位和最高数值位进位。
  4. 根据进位判断 OF,根据减法规则判断 CF。
【三】逐步推导过程
  1. X=+60,真值二进制为 +011 1100。X 的补码= 00111100

  2. Y=−80,真值二进制为 -101 0000。Y 的原码= 11010000 → Y 的补码= 10110000

  3. 求 (−Y) 的补码:将 Y 的补码连同符号位全部取反,末位加 1。
    10110000 取反 → 01001111,再 +1 → 01010000(其实就是 +80 的补码)。

  4. 计算 X−Y 的补码 = X 的补码 + (−Y) 的补码:

    0011 1100
    
    • 0101 0000

    1000 1100
    
  5. 分析进位与标志

    • 符号位的相加:0+0=0,没有向前进位,所以符号位进位 CS=0。
    • 最高数值位的相加:次高位 0+1=1,没有向符号位进位,即 C1=1。
    • 结果符号位为 1(负数)。
【四】正确答案
  • 计算结果:10001100
  • 是否溢出:发生溢出。两个正数相加(60 和 80),结果变成了负数(最高位为 1),显然发生了上溢。或者用公式 OF = CS ⊕ C1 = 0 ⊕ 1 = 1,OF 为 1 表示溢出。
  • CF 标志:对于减法,CF = Cout ⊕ 1(Cout 是加法器最高位的实际进位,这里是 0)。所以 CF = 0 ⊕ 1 = 1。说明如果当做无符号数看,发生了借位。
【七】如何举一反三

做这类题,切忌在脑子里用心算!一定要老老实实写出 8 位二进制的竖式加法。标出 CS(最高位往外的进位)和 C1(次高位往最高位的进位)。只要 CS 不等于 C1,OF 必然等于 1(溢出)。


四】易错点总结

  1. 求 (−Y) 的补码时忘记取反符号位:很多同学只取反数值位,这是致命错误!在 ALU 中,不管符号位还是数值位,一视同仁过反相器。口诀:连同符号位一起,全部取反,末位加 1。
  2. 混淆无符号数的范围与有符号数的范围:8 位字长,无符号数范围是 0~255,有符号数(补码)范围是 -128~127。上面的例题 60−(−80)=140,140 在无符号数里是合法的,但在有符号数里超过了 127,所以必然溢出。
  3. 变形补码(双符号位)的存储误区:双符号位仅仅是在 ALU进行加减运算时 临时扩展出来的逻辑,在主存和寄存器中存储时,依然只存 1 个符号位!千万别以为内存里也存两个符号位。
  4. CF 的计算陷阱:加法时 CF = Cout;减法时 CF = Cout ⊕ 1。减法运算时加法器算出的最高位进位还要取反才是 CF!这是 408 极其爱考的硬件细节。

五】记忆技巧或理解方法

  • 溢出公式记忆口诀:”同异必溢“。两个号的数相加,如果结果的符号跟它们号,必然溢出。

  • 双符号位记忆口诀:”头真次假“。最高位代表真实的符号,次高位代表计算出来的(错误的)符号。01 上溢(本该是 0,算出来变 1 了);10 下溢(本该是 1,算出来变 0 了)。

  • ALU视角理解 CF 与 OF(终极必杀技)

    • ALU 是个“瞎子”,它根本不知道你传进来的这串 01 代码是有符号数还是无符号数。
    • 所以,ALU 做完加法后,会同时置位 CF 和 OF!
    • 如果你(程序员/编译器)把数据当无符号数,你就去查 CF 标志。
    • 如果你把数据当有符号数int / short),你就去查 OF 标志。

数据存储和排列

你好!今天我们来攻克408计组和C语言结合最紧密、也是每年必考的硬骨头——数据的存储和排列。这部分内容主要包含大小端存储(Endianness)边界对齐(Boundary Alignment)

在408考试中,这部分是“送分题”也是“送命题”。如果你不懂底层规则,遇到 sizeof(struct) 或者内存地址推导就会全军覆没。

请紧跟我的思路,我们立刻开始:


【一】核心概念(用考研语言解释)

1. 大端与小端存储 (Big-endian vs Little-endian)

在计算机中,基本编址单位通常是字节(Byte),但很多数据类型(如 intshort)占多个字节。多字节数据在内存中的存放顺序就产生了“大小端”之分。

  • 大端模式(Big-endian)有效字节存放在地址,有效字节存放在地址。

    • 本质:这符合我们人类从左到右阅读的自然顺序。TCP/IP 网络字节序规定的就是大端。
  • 小端模式(Little-endian)有效字节存放在地址,有效字节存放在地址。

    • 本质:这是给机器看的,方便计算机从低位开始处理运算(比如加法进位)。Intel x86 架构就是典型的小端机器。

2. 边界对齐 (Boundary Alignment)

  • 本质:空间换时间。现代 CPU 每次访存并不是读一个字节,而是读取一个“字”(比如 32 位机器一次读 4 字节)。如果数据跨越了字边界,CPU 就需要访存两次拼接才能取出一个数据,效率会下降。

  • 对齐规则(以 32 位机器,按自身对齐为例)

    1. 成员对齐:结构体(struct)内部的每个基本成员,其存放的起始偏移量(Offset)必须是该成员自身大小的整数倍
      (如 int 占 4 字节,它的起始地址必须是 4 的倍数,不够的话前面填充空白字节。)

    2. 整体对齐:结构体的总大小(sizeof)必须是其内部最大基本数据类型成员大小的整数倍
      (不够的话在末尾填充空白字节。)


【二】考试常考点(408 常怎么出题)

  1. 给数据求内存内容(大小端)
    告诉你一个 int 型十六进制数(如 0x12345678),存放在起始地址为 0x0800 的内存中,问在小端机器上,0x0801 单元存的是什么?

  2. 求结构体大小(边界对齐,极高频!)
    给你一个定义好的 struct,里面塞满了 charshortint 甚至数组,问这个结构体占多少字节?

  3. 成员调整优化空间
    考查是否知道把结构体中占用空间小的成员紧凑写在一起,减少填充字节,缩小整体大小。

  4. 与计网结合
    题目告诉你本地主机是小端,发送数据到网络,问在网络传输中(大端)抓包看到的字节流顺序。


【三】典型例题分析】

题目:假设在 32 位系统中,按字节编址,采用小端方式存储。有如下 C 语言结构体定义:

1
2
3
4
5
struct Record {
char a;
int b;
short c;
};

已知结构体变量 rec 的起始地址为 0x1000,成员 rec.b 的值为 0x11223344。请问:

  1. 该结构体 rec 占用的总字节数是多少?
  2. 成员 rec.c 的起始地址是多少?
  3. 内存地址 0x1005 中存放的具体内容(十六进制格式)是什么?

【一】题目考察什么知识点

考察结构体边界对齐(计算总大小和偏移量)以及小端模式下的字节存储。


【二】解题思路分析

  1. 画出内存排布图,利用边界对齐的“两步走”规则(成员对齐、整体对齐)推导每个成员的起始偏移量。
  2. 结合起始地址 0x1000,算出具体地址。
  3. 0x11223344 按照小端规则填入对应的内存单元,定位 0x1005

【三】逐步推导过程

  1. 分析偏移与大小

    • achar(1 字节),起始偏移量为 0,占据 [0]
    • bint(4 字节),要求偏移量必须是 4 的倍数。当前偏移量为 1,需要填充 3 字节。
      b 的偏移量为 4,占据 [4, 5, 6, 7]
    • cshort(2 字节),要求偏移量是 2 的倍数。当前偏移量为 8,满足条件。
      占据 [8, 9]
    • 当前总大小为 10 字节。

    整体对齐检查:最大基本成员是 int(4 字节),总大小必须是 4 的倍数。
    10 不是 4 的倍数,补齐到 12 字节(即 [10, 11] 为填充字节)。

  2. 回答第 (1) 问:结构体总大小为 12 字节

  3. 回答第 (2) 问
    c 的偏移量是 8,因此起始地址为:

    0x1000 + 8 = 0x1008

  4. 回答第 (3) 问

    b 占据地址 0x10040x1007
    b = 0x11223344

    • 最高有效字节:0x11
    • 最低有效字节:0x44

    小端模式(低字节放低地址)

    地址 内容
    0x1004 0x44
    0x1005 0x33
    0x1006 0x22
    0x1007 0x11

    所以:

    0x1005 存放的是:0x33


【四】正确答案

  1. 12 字节
  2. 0x1008
  3. 0x33

【五】如何举一反三

遇到结构体:

  1. 先写出每个成员的类型大小。
  2. 在草稿纸画格子,标偏移量。
  3. 不满足倍数就填充。
  4. 最后一定检查:整体大小是否满足最大成员对齐。

【四】易错点总结

  1. 结构体包含数组时的对齐

    如果结构体里有:

    C

    char arr[5];

    不要把它当成一个 5 字节整体去对齐。
    数组只是若干连续基本类型,对齐依据是元素类型(这里是 char,按 1 字节对齐)。

  2. 混淆大小端的内部位序

    很多同学误以为小端会把 0x12 存成 0x21
    ❌ 错误!

    大小端的单位是字节(Byte),一个字节内部的 8 位不会颠倒。
    0x12 存进去仍然是 0x12

  3. 结构体嵌套结构体

    如果 struct A 中嵌套 struct B
    那么 struct Bstruct A 中的偏移量,必须是 struct B 内部最大基本成员大小的整数倍


【五】记忆技巧

1️⃣ 大小端口诀

小端小小小
小端模式下:低有效字节 → 低地址

记住小端,大端自然反过来。


2️⃣ 边界对齐两步走

  • 第一步(对内):每个成员

    偏移量 % 自身大小 == 0

  • 第二步(对外):整体大小

    总大小 % 最大成员大小 == 0


3️⃣ 结构体瘦身法

把占空间小的成员写在一起(如 charshort 连续放),
可以显著减少填充字节,降低内存浪费

浮点数

一】核心概念(用考研语言解释)

1. 浮点数的一般格式

浮点数在计算机中表示为:N=rE×M

  • r (基数):计算机中通常隐含为2。
  • E (阶码):通常用移码表示,决定了浮点数的表示范围(能表示多大或多小的数)。
  • M (尾数):通常用原码补码表示,决定了浮点数的精度(有效数字有多少位)。
2. 408绝对重点:IEEE 754 单精度浮点数 (float)

408考得最多的是32位的单精度浮点数(float),它的结构像切蛋糕一样被严格划分为三部分:1位符号位 + 8位阶码 + 23位尾数

  • 数符 (S):最高位(第31位),0表正,1表负。
  • 阶码 (E):中间8位(第23~30位),用**无符号数(即移码)**表示。注意,IEEE 754的移码偏置值是 127(不是128)。真实阶码 e=E−127。
  • 尾数 (M):低23位(第0~22位),用原码表示。采用隐藏位技术,规定规格化尾数的最高有效位总是1,并且不存放在内存中,以节省1位空间。实际尾数值为 1.M。
  • 真值公式:N=(−1)S×1.M×2E−127

【二】考试常考点(408常怎么出题)

  1. 十进制与IEEE 754的相互转换:给你一个十进制数(比如 -12.5),让你写出它在内存中的十六进制机器码;或者反过来,这是必考的基本功。
  2. C语言类型转换(精度丢失问题):当 int (32位,有效数字31位+1位符号) 转换为 float (32位,有效数字24位+1位符号+8位阶) 时,会不会丢失精度?(**会!**因为23+1=24位存不下31位的有效数字)。
  3. 浮点数的加减法运算步骤:常考概念排序——对阶 → 尾数求和 → 规格化 → 舍入 → 溢出判断。尤其爱考“对阶”规则。
  4. 特殊值判断:当阶码 E 全0或全1时,代表0、无穷大(∞)或非数(NaN)等非规格化状态。

【三】典型例题分析

题目:将十进制数 −12.5 转换成 IEEE 754 单精度浮点数,并用十六进制表示其机器码。

【一】题目考察什么知识点 考察十进制小数到二进制的转换,以及 IEEE 754 单精度浮点数的“数符-阶码-尾数”三段式编码拼接规则。

【二】解题思路分析

  1. 将十进制数转化为二进制真值。
  2. 将二进制真值写成规格化的浮点数形式(即 1.xxx×2e)。
  3. 分别提取符号位 S、阶码 E(真实阶码加127)和尾数 M(去掉隐藏的1)。
  4. 拼接成32位二进制,最后按4位一组转为十六进制。

【三】逐步推导过程

  1. 求二进制真值

    • 整数部分:12=1100(2)​
    • 小数部分:0.5=0.1(2)​
    • 真值:−12.5=−1100.1(2)​
  2. 规格化表示

    • 将小数点左移3位,变成:−1.1001×23
  3. 计算各部分编码

    • 数符 S:因为是负数,所以 S=1。
    • 阶码 E:真实阶码 e=3,偏置值为127。所以 E=3+127=130。将其转为8位二进制:130=128+2=10000010(2)​。
    • 尾数 M:小数点后面的部分是 1001,隐藏了前面的 1.。所以尾数前四位是 1001,后面全部补 0,凑足23位:1001 0000 0000 0000 0000 000
  4. 拼接并转十六进制

    • 拼接:1_10000010_10010000000000000000000
    • 按4位一组划分:1100 0001 0100 1000 0000 0000 0000 0000
    • 转十六进制:0xC1480000

【四】正确答案 机器码的十六进制表示为:0xC1480000

【五】错误选项为什么错 常见错误算出的机器码可能是 0xC1C80000,错误原因在于没有隐藏尾数的最高位1,直接把 11001 当成了尾数存进去。只要记住“头一砍掉”就不会犯这种错。

【六】本题属于哪类题型 这是计组第二章最经典的“数据表示与编码”计算题,常在单选题中直接考察,或作为主观大题的第一步(比如给你两段C语言代码,让你分析底层表示)。

【七】如何举一反三 只要遇到 IEEE 754 转换,牢记口诀:“定正负、化二进、移小数点、算阶码(加127)、去头(隐1)填尾数”。如果是逆向推导(给机器码求十进制),步骤完全反过来:先拆分三段 → 减去127算阶码 → 加上“1.”还原尾数 → 移动小数点得真值 → 转回十进制。

【四】易错点总结

  1. 偏置值记错:很多人受传统移码思维影响,以为8位移码偏置值是128。IEEE 754 标准明确规定,单精度的偏置值是 127!(双精度64位是 1023)。
  2. 隐藏位忘记处理:把真值 1.101 存入尾数时,存的应该是 10100...,而不是 110100...。最高位的 1 绝对不能存进去!
  3. 对阶的方向搞反:浮点数加减法第一步是“对阶”。规则必须是:小阶向大阶看齐,小阶的尾数算术右移。因为尾数右移只会丢失一点低位精度,如果大阶向小阶看齐(尾数左移),最高有效位会被挤掉,导致不可挽回的严重错误。

【五】记忆技巧或理解方法

  • 格式划分口诀:“1把扇(8-3)” → 1位符号,8位阶码,23位尾数。
  • 偏置值理解:为什么是127而不是128?因为IEEE 754规定阶码全0和全1有特殊用途(全0代表0或非规格化数,全1代表无穷或NaN),所以正常可用的阶码范围是 1 ~ 254。减去127后,真实阶码范围是 -126 ~ +127,这样正负指数范围更加对称均衡。
  • 对阶操作形象理解:对阶就像两个人身高不同要平视。矮子(小阶)可以垫砖头(阶码变大),然后视线往上看(相当于尾数右移);但高个子不能砍腿,所以只能小阶向大阶看齐

浮点数加减运算

1. 知识点系统讲解(考试导向)

浮点数加减的核心流程是**“对阶 → 尾数运算 → 规格化 → 舍入”**。

完整步骤:

  1. 对阶(关键步骤)
  • 让两个数的指数(阶码)相同
  • 方法:小阶向大阶对齐(右移尾数)
  • 本质:改变表示形式,不改变数值
  1. 尾数加减
  • 指数相同后,直接对尾数进行加减
  • 注意符号位(可能是加也可能是减)
  1. 规格化
  • 结果必须满足:1.xxx(规格化形式)

情况:

  • 如果结果 >= 2 → 右移尾数,阶码 +1
  • 如果结果 < 1 → 左移尾数,阶码 -1
  1. 舍入(了解)
  • 位数超出时进行截断或四舍五入
  • 可能引入误差

核心本质:

  • 阶码决定“数量级”
  • 尾数决定“精度”
  • 加减必须在同一数量级下进行

2. 通俗理解(直观类比)

可以把浮点数看成:

“带单位的数”

例如:

  • $1.2 \times 10^3 = 1200$
  • $3.4 \times 10^2 = 340$

你不能直接:

$$
1200 + 3.4
$$

必须先统一单位:

$$
3.4 \times 10^2 = 0.34 \times 10^3
$$

再计算:

$$
1.2 + 0.34
$$

👉 浮点数对阶就是“统一单位”的过程

3. 例题分析(核心)

例题1:基础对阶加法

计算:

$$
1.01 \times 2^3 + 1.10 \times 2^2
$$

步骤:

① 对阶
将小指数对齐:

$$
1.10 \times 2^2 = 0.110 \times 2^3
$$

② 尾数相加

$$
1.01 + 0.110 = 1.111
$$

③ 规格化
已经是 1.xxx,无需调整

④ 结果

$$
1.111 \times 2^3
$$

例题2:产生规格化调整

计算:

$$
1.11 \times 2^3 + 1.01 \times 2^3
$$

① 对阶
已相同

② 尾数相加

$$
1.11 + 1.01 = 11.00
$$

③ 规格化

$$
11.00 = 1.100 \times 2^4
$$

(尾数右移一位,阶码+1)

④ 结果

$$
1.100 \times 2^4
$$

例题3:减法(易错)

计算:

$$
1.01 \times 2^3 - 1.00 \times 2^2
$$

① 对阶

$$
1.00 \times 2^2 = 0.100 \times 2^3
$$

② 尾数相减

$$
1.01 - 0.100 = 0.110
$$

③ 规格化

$$
0.110 = 1.10 \times 2^2
$$

(左移一位,阶码-1)

④ 结果

$$
1.10 \times 2^2
$$

总结一句话(应试关键):
👉 浮点数加减 = 先对阶,再算尾数,最后调整规格化

如果你下一步想提高分数,建议专门练:

  • “对阶导致精度丢失”类型题

回答

1. 知识点系统讲解(考试导向)

存储器的作用:
用于存放程序和数据,是计算机系统的核心组成部分之一。

一、存储器的层次结构(高频考点)

按照速度—容量—成本划分:

  • 寄存器(CPU内部,最快,最小)
  • Cache(高速缓存)
  • 主存(内存,RAM)
  • 辅存(磁盘、SSD等)

特点规律:

  • 越靠近CPU → 速度越快、容量越小、价格越高
  • 越远离CPU → 速度越慢、容量越大、价格越低

二、主存的基本组成

主存由多个存储单元组成:

  • 每个存储单元有一个地址
  • 每个单元存放一定长度的数据(如8位=1字节)

相关概念:

  • 存储容量 = 存储单元个数 × 每个单元位数
  • 地址线决定容量(2ⁿ个单元)
  • 数据线决定一次能读写多少位

三、存储器分类(常考)

  1. 按存取方式:
  • 随机存取存储器(RAM)
  • 只读存储器(ROM)
  • 顺序存取(磁带,基本不考)
  1. 按存储介质:
  • 半导体存储器(主存)
  • 磁表面存储器(硬盘)
  • 光存储(光盘)
  1. 按是否易失:
  • 易失性(RAM:断电丢失)
  • 非易失性(ROM、硬盘)

四、关键性能指标(高频)

  1. 存取时间(访问延迟)
  • 读/写一次所需时间
  1. 存储周期
  • 连续两次访问的最小间隔
  1. 带宽
  • 单位时间传输的数据量

2. 通俗理解(直观类比)

可以把存储器看成一个“多层仓库系统”:

  • 寄存器:手里拿着的东西(最快)
  • Cache:桌子上的资料(很快)
  • 主存:房间里的柜子(一般)
  • 硬盘:仓库(很大但慢)

👉 CPU工作时:

  • 优先从“手里(寄存器)”拿
  • 没有就去“桌子(Cache)”
  • 再没有就去“柜子(主存)”
  • 最后才去“仓库(硬盘)”

核心本质:
👉 用多层结构来平衡:速度 vs 容量 vs 成本

3. 例题分析(核心)

例题1:存储容量计算(高频)

某存储器有:

  • 地址线 10 根
  • 数据线 8 根

求:存储容量

解题步骤:

① 存储单元个数:

$$
2^{10} = 1024
$$

② 每个单元位数:

$$
8 \text{ 位} = 1 \text{ 字节}
$$

③ 总容量:

$$
1024 \times 1B = 1024B = 1KB
$$

例题2:层次结构判断(选择题高频)

下列哪种存储器速度最快?

A. 主存
B. Cache
C. 硬盘
D. 寄存器

分析:

速度排序:

$$
寄存器 > Cache > 主存 > 硬盘
$$

答案:D

例题3:性能指标理解(易错)

存取时间和存储周期的关系?

关键结论:

  • 存储周期 >= 存取时间
  • 因为一次访问后需要恢复时间

总结(应试抓核心):

  • 容量问题 → 看地址线
  • 速度问题 → 看层次结构
  • 指标问题 → 区分“存取时间 vs 存储周期”

如果你继续往下学,下一步通常会考:

  • Cache工作原理(命中率)
  • 主存与Cache的映射方式(重点)

用户问题

下一节是主存储器,包括主存储器的基本组成,SRAM和DRAM,ROM,双端口RAM

回答

1. 知识点系统讲解(考试导向)

一、主存储器的基本组成

主存由存储体 + 控制电路 + 地址/数据通路构成:

  • 存储体(核心):由大量存储单元组成(按地址编址)
  • 地址寄存器 MAR(Memory Address Register):存放要访问的地址
  • 数据寄存器 MDR(Memory Data Register):存放读/写的数据
  • 控制信号:读/写控制

基本工作流程:

  • 读:CPU → MAR(地址)→ 主存 → 数据到 MDR → CPU
  • 写:CPU → MDR(数据)→ 写入主存指定地址

👉 常考点:

  • MAR位数决定“寻址范围”
  • MDR位数决定“数据宽度”

二、SRAM 与 DRAM(核心重点)

1. SRAM(静态RAM)

  • 用触发器存储(一般6个晶体管)
  • 不需要刷新
  • 速度快、成本高、容量小
  • 常用于:Cache

2. DRAM(动态RAM)

  • 用电容存储(1个电容+1个晶体管)
  • 必须周期性刷新
  • 速度慢于SRAM、成本低、容量大
  • 常用于:主存

核心对比(必记):

特性 SRAM DRAM
结构 触发器 电容
是否刷新 不需要 必须
速度 较慢
成本
应用 Cache 主存

三、ROM(只读存储器)

特点:

  • 非易失性(断电不丢失)
  • 主要用于存放固化程序(如BIOS)

常见类型(了解):

  • PROM(一次编程)
  • EPROM(可擦除)
  • EEPROM(可电擦除)

👉 考点:

  • ROM“逻辑上只读”,但有些可以改写

四、双端口RAM(了解但有区分度)

特点:

  • 两个独立访问端口
  • 可以同时进行两次访问(读/写)

用途:

  • 多处理器系统
  • CPU 与 I/O 同时访问

👉 本质:提高并行访问能力

2. 通俗理解(直观类比)

可以把主存看成一个“图书馆系统”:

  • 存储体:书架
  • 地址:书的位置编号
  • MAR:你写下要找的书的位置
  • MDR:你手里拿到的书

SRAM vs DRAM:

  • SRAM:像“电子记事本”,一直记着,不会忘
  • DRAM:像“短期记忆”,必须不断提醒(刷新),否则会忘

ROM:

  • 像“印刷好的书”,一般不让改

双端口RAM:

  • 像一个图书馆有两个窗口
  • 两个人可以同时借书

3. 例题分析(核心)

例题1:SRAM vs DRAM判断(高频选择题)

下列说法正确的是:

A. DRAM速度比SRAM快
B. SRAM需要刷新
C. DRAM常用于主存
D. SRAM成本更低

分析:

  • A ❌(SRAM更快)
  • B ❌(SRAM不刷新)
  • C ✅(主存用DRAM)
  • D ❌(SRAM更贵)

答案:C

例题2:MAR与MDR作用(易考概念)

若MAR为16位,MDR为8位,则:

① 可寻址单元数:

$$
2^{16} = 65536
$$

② 每个单元大小:
8位 = 1字节

③ 总容量:

$$
65536 \times 1B = 64KB
$$

👉 结论:

  • MAR决定“有多少地址”
  • MDR决定“每次取多少数据”

例题3:刷新问题(常考理解)

为什么DRAM需要刷新?

关键原因:

  • 数据存储在电容中
  • 电荷会随时间泄漏
  • 不刷新会丢失数据

👉 本质:
DRAM不是“存住了”,而是“暂时记住”

总结一句话(应试核心):
👉 主存 = DRAM为主 + SRAM做缓存,ROM负责“长期记忆”

如果继续往下,一般会进入:

  • 存储器扩展(位扩展、字扩展)
  • 或 Cache映射(408重点难点)

用户问题

你忘记介绍多模块存储器了

回答

对,这一节里还应补上多模块存储器。它在408里是常考点,尤其容易和“存储周期、带宽、交叉编址”结合出题。

下面把这一部分补完整。

补充:多模块存储器

1. 知识点系统讲解(考试导向)

多模块存储器,就是把主存分成若干个独立的存储模块,从而提高主存的访问效率。

这样做的目的不是单纯为了“容量更大”,而是为了:

  • 提高并行性
  • 提高存储器带宽
  • 尽量让CPU少等待

为什么需要多模块存储器?

单个存储器模块虽然一次能完成读写,但它完成一次存取后,往往还要经过一个存储周期才能进行下一次访问。
如果CPU连续访问数据,单模块主存容易跟不上。

所以就把主存拆成多个模块,让不同模块轮流工作。

2. 多模块存储器的两种组织方式

(1)高位交叉编址

高位地址决定模块号。

也就是说,连续的一大段地址放在同一个模块中。

例如有4个模块:

  • 模块0:0000~0011
  • 模块1:0100~0111
  • 模块2:1000~1011
  • 模块3:1100~1111

这种方式的特点:

  • 地址分配简单
  • 适合按块存放
  • 不利于提高连续访问速度

因为程序顺序访问时,很可能总在同一个模块里取数,这样并不能并行。

(2)低位交叉编址

低位地址决定模块号。

也就是说,连续地址分散到不同模块中

例如4个模块时:

  • 地址0 → 模块0
  • 地址1 → 模块1
  • 地址2 → 模块2
  • 地址3 → 模块3
  • 地址4 → 模块0
  • 地址5 → 模块1

这种方式的特点:

  • 连续地址落在不同模块
  • 可以让各模块轮流工作
  • 能显著提高顺序访问速度
  • 是考试重点

3. 核心原理

低位交叉编址下,如果有 $m$ 个模块,那么通常:

  • 地址的低 $\log_2 m$ 位表示模块号
  • 高位表示模块内地址

这样一来,CPU连续访问主存时,连续地址会自动分配到不同模块中。
当模块0还在恢复时,模块1可以工作;模块1恢复时,模块2可以工作。

所以总体效果就是:
单个模块访问不快,但整体流水式访问更快。

2. 通俗理解(直观类比)

可以把多模块存储器理解成“多个窗口同时服务”。

单模块存储器

像银行只有一个窗口:

  • 第一个人办完
  • 窗口还要整理一下
  • 第二个人才能继续

所以排队慢。

多模块存储器

像银行有4个窗口:

  • 第一个人去1号窗口
  • 第二个人去2号窗口
  • 第三个人去3号窗口
  • 第四个人去4号窗口

这样大家轮流办理,整体速度就快很多。

为什么低位交叉更好?

因为它会把“连续来的人”自动分到不同窗口。
如果是高位交叉,可能前面很多人全挤在1号窗口,那就失去并行的意义了。

3. 例题分析(核心)

例题1:判断哪种方式更适合提高顺序访问速度

某主存采用4模块组织,下列哪种方式更有利于CPU顺序访问一串连续地址?

A. 高位交叉编址
B. 低位交叉编址

分析:

顺序访问时,如果采用低位交叉:

  • 0号地址在模块0
  • 1号地址在模块1
  • 2号地址在模块2
  • 3号地址在模块3

连续地址被分散到不同模块,可以并行轮转访问。

答案:B

例题2:地址分配判断

某存储器采用4体低位交叉编址,则地址 0、1、2、3、4、5 分别属于哪些模块?

解题思路:

4个模块,需要2位低位来表示模块号:

  • 00 → 模块0
  • 01 → 模块1
  • 10 → 模块2
  • 11 → 模块3

所以:

  • 0 → 模块0
  • 1 → 模块1
  • 2 → 模块2
  • 3 → 模块3
  • 4 → 模块0
  • 5 → 模块1

这类题本质就是看:
模块号 = 地址对模块数取模

也就是:

$$
模块号 = 地址 \bmod 4
$$

例题3:为什么低位交叉能提高带宽

设每个模块存取周期为 $T$,总共有4个模块。

如果采用单模块方式,CPU连续读取4个字,往往要接近 $4T$ 的时间。

如果采用4体低位交叉,在理想情况下,各模块交替工作,CPU可以更连续地获得数据,整体传输速度明显提升。

结论:

  • 单模块:受存储周期限制明显
  • 多模块低位交叉:能把等待时间“摊开”
  • 所以提高的是顺序读写时的带宽

4. 这一节现在应当完整包括哪些内容

你这一小节如果按完整框架整理,应包括:

  • 主存储器的基本组成
  • SRAM和DRAM
  • ROM
  • 双端口RAM
  • 多模块存储器

其中真正的重点通常是:

  • SRAM与DRAM区别
  • MAR/MDR相关容量计算
  • 多模块存储器中的低位交叉编址

双端口RAM一般不是最核心,但会出概念题。

如果你愿意,我可以把“主存储器”这一整节重新按你当前Agent格式,完整整理成一版最终稿。

用户问题

讲解主存储器和cpu的连接

回答

1. 知识点系统讲解(考试导向)

本节核心是:CPU如何通过总线与主存进行信息交换,重点掌握“连接结构 + 工作流程 + 扩展方式”。

一、CPU与主存的连接结构

CPU与主存之间通过三类总线连接:

  1. 地址总线(Address Bus)
  • 方向:CPU → 主存(单向)
  • 作用:传送要访问的存储单元地址
  • 位数决定:最大寻址范围(容量)
  1. 数据总线(Data Bus)
  • 方向:双向(CPU ↔ 主存)
  • 作用:传送数据
  • 位数决定:一次传输的数据量
  1. 控制总线(Control Bus)
  • 作用:传送控制信号
  • 常见信号:

读信号(RD)

写信号(WR)

片选信号(CS)

👉 核心一句话:
地址总线定位置,数据总线传内容,控制总线定操作

二、基本工作过程(高频)

1. 读操作流程

① CPU将地址送入 MAR
② 地址通过地址总线传给主存
③ CPU发出“读信号”
④ 主存根据地址取出数据
⑤ 数据送入 MDR
⑥ 通过数据总线返回CPU

2. 写操作流程

① CPU将地址送入 MAR
② CPU将数据送入 MDR
③ 地址通过地址总线送出
④ CPU发出“写信号”
⑤ 数据通过数据总线写入主存

👉 常考点:

  • 读操作:数据“主存 → CPU”
  • 写操作:数据“CPU → 主存”

三、主存扩展与连接(重点)

当单个存储芯片容量不足时,需要扩展。

1. 位扩展(数据宽度扩展)

目的:扩大数据位数

方法:

  • 多个存储芯片并联
  • 共用地址线和控制线
  • 各芯片负责不同位

例如:

  • 8位CPU + 4位芯片
    → 需要2个芯片组成8位
2. 字扩展(容量扩展)

目的:扩大存储单元数量

方法:

  • 增加存储芯片数量
  • 用高位地址进行片选(CS)

👉 本质:

  • 不同地址访问不同芯片
3. 字位扩展(综合)

同时扩展:

  • 容量(字)
  • 位宽(位)

四、片选信号(关键考点)

在字扩展中必须解决的问题:

👉 如何确定访问哪一块存储芯片?

方法:

  • 用高位地址通过译码器产生片选信号

本质:

  • 地址 = 模块编号 + 模块内地址

五、连接中的性能问题(理解)

  1. 总线带宽限制
  • 数据总线越宽 → 传输越快
  1. 存储周期限制
  • 主存速度慢于CPU → 产生等待
  1. 解决方法(后续内容)
  • Cache
  • 多模块存储器

2. 通俗理解(直观类比)

可以把CPU和主存的连接理解为“快递系统”:

  • 地址总线:写地址(送货地址)
  • 数据总线:运货(数据本身)
  • 控制总线:说明是“取货”还是“送货”

读操作:

  • CPU:我要这个地址的东西
  • 主存:把数据送回来

写操作:

  • CPU:把这个数据送到这个地址

片选信号:

  • 像一个仓库有多个分区
  • 地址的高位决定你去哪个区取货

3. 例题分析(核心)

例题1:总线作用判断(高频选择题)

下列说法正确的是:

A. 数据总线单向传输
B. 地址总线双向传输
C. 控制总线用于读写控制
D. 地址总线传输数据

分析:

  • A ❌(数据总线双向)
  • B ❌(地址总线单向)
  • C ✅
  • D ❌

答案:C

例题2:位扩展计算

CPU数据总线为8位,现有存储芯片为4位宽,需要几个芯片?

计算:

$$
8 / 4 = 2
$$

答案:2个

例题3:字扩展理解(常考)

有4个存储芯片,需要用多少位地址进行片选?

计算:

$$
\log_2 4 = 2
$$

👉 需要2位高位地址作为片选

例题4:读写方向判断(易错)

判断:

“写操作时数据从主存流向CPU”

答案:❌

正确:

  • 写:CPU → 主存
  • 读:主存 → CPU

本节应试核心总结

  • 三总线:地址(单向)、数据(双向)、控制(控制)
  • MAR → 地址,MDR → 数据
  • 读写流程必须熟
  • 位扩展 → 扩数据宽度
  • 字扩展 → 扩容量(片选关键)
  • 片选 = 高位地址译码

这一节是后续学习 Cache、存储系统设计的基础。
如果继续,下一节通常进入:Cache(映射与命中率,408重点)


27 408考研
http://cathylove47.github.io/2026/03/12/27-408考研/
作者
cathy
发布于
2026年3月12日
许可协议