HNU2026-计算机系统-期中知识点速查
《计算机系统核心知识点速查手册》摘要 本手册系统梳理了计算机系统核心概念,涵盖五大关键领域:编译流程、二进制表示、整数运算、浮点数处理和汇编基础。主要内容包括: 编译四阶段(预处理、编译、汇编、链接)的核心工具与参数 计算机体系核心组件(CPU结构、存储器层次、操作系统抽象) 二进制与进制转换技巧,重点区分位运算与逻辑运算 整数表示与运算(补码转换、截断处理、溢出判断) IEEE 754浮点标准详
计算机系统 期中知识点速查
用途:考前快速翻阅的浓缩手册,覆盖教材第 1-6 章全部核心考点
标准:每条内容都能在 50 分钟机考中帮你快速回忆并答题
配合使用:[[计算机系统课程笔记]]、[[计算机系统期中题库]]
链接:计算机系统专栏
Ch1 概论与编译流程
编译四阶段
| 阶段 | 工具 | 输入 → 输出 | gcc 参数 | 能检查的错误 |
|---|---|---|---|---|
| 预处理 | cpp | .c → .i |
-E |
宏定义错误、缺失头文件 |
| 编译 | cc1 | .i → .s |
-S |
语法错误、类型错误 |
| 汇编 | as | .s → .o |
-c |
汇编指令合法性 |
| 链接 | ld | .o → 可执行 |
(无) | 符号未定义/重复定义 |
.o文件是二进制,不能用文本编辑器直接查看.s文件是汇编文本,可以查看-g生成调试信息,-O1/-O2优化级别
CPU 与存储器
- CPU 组成:运算器 + 控制器 + 寄存器(存储器不属于 CPU)
- PC(程序计数器):保存下一条要执行的指令地址(IA32 中叫
%eip) - 存储器层次:寄存器 > L1 > L2 > L3 > 主存 > 磁盘(速度↓ 容量↑ 造价↓)
- 操作系统三大抽象:进程(CPU+ 主存 +I/O)、虚拟存储器(主存 + 磁盘)、文件(I/O)
- 计算机能直接执行的是机器语言(不是汇编、不是高级语言)
- 一条指令包含:操作码 + 操作数
- 时钟周期是计算机操作的最小时间单位
主存(内存)
- 主存是临时存储设备,存放程序和数据
- 机器级程序使用的是虚拟地址(不是物理地址)
- 1 字节 = 8 位(bit),字节是最小可寻址单位
- 内存容量 = 2 地址位数 2^{地址位数} 2地址位数 字节
Ch2 二进制与信息表示
进制转换速查
十六进制 ↔ 二进制:每 1 位十六进制 = 4 位二进制
| 十六进制 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 二进制 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
十进制 → 二进制:整数部分除 2 取余(从下往上),小数部分乘 2 取整(从上往下)
二进制小数:小数点右侧每位权重为 2 − 1 , 2 − 2 , 2 − 3 , … 2^{-1}, 2^{-2}, 2^{-3}, \ldots 2−1,2−2,2−3,…
- 只能精确表示 x / 2 k x/2^k x/2k 形式的小数
- 1/3、1/5、1/10 等在二进制中是无限循环
位运算 vs 逻辑运算
| 运算 | 位运算 | 逻辑运算 |
|---|---|---|
| 与 | &(逐位) |
&&(整体 0/1) |
| 或 | |(逐位) |
||(整体 0/1) |
| 非 | ~(逐位取反) |
!(非零→0,零→1) |
| 异或 | ^(逐位) |
无 |
关键区别:
!0x41=0x00(非零取反为 0)~0x41=0xBE(逐位取反)0x69 && 0x55=0x01(两个非零,逻辑与为 1)0x69 & 0x55=0x41(逐位与)
移位操作
| 操作 | 指令 | 规则 |
|---|---|---|
| 逻辑左移 | shl / sal |
右端补 0 |
| 算术左移 | sal / shl |
右端补 0(与逻辑左移等价) |
| 逻辑右移 | shr |
左端补 0 |
| 算术右移 | sar |
左端补符号位 |
- C 语言中,无符号数右移是逻辑右移,有符号数右移是算术右移
- 左移 k 位 = 乘以 2 k 2^k 2k
- 算术右移 k 位 ≈ 除以 2 k 2^k 2k(向负无穷舍入)
inc/dec不改变 CF,add/sub改变 CF
大小端
- 小端(Little Endian):最低有效字节在最低地址(x86 使用小端)
- 大端(Big Endian):最高有效字节在最低地址
- 大小端只影响字节间排列顺序,字节内部存储不变
例:0x01234567 在小端存储(地址递增):67 45 23 01
数据类型大小
| 类型 | 32 位系统 | 64 位系统 |
|---|---|---|
char |
1 | 1 |
short |
2 | 2 |
int |
4 | 4 |
long |
4 | 8 |
float |
4 | 4 |
double |
8 | 8 |
| 指针 | 4 | 8 |
unsigned char范围:[0, 255]char范围:[-128, 127]short范围:[-32768, 32767]
Ch5-1 整数表示
B2U 与 B2T
- B2U(无符号): ∑ i = 0 w − 1 x i ⋅ 2 i \displaystyle\sum_{i=0}^{w-1} x_i \cdot 2^i i=0∑w−1xi⋅2i
- B2T(补码): − x w − 1 ⋅ 2 w − 1 + ∑ i = 0 w − 2 x i ⋅ 2 i -x_{w-1} \cdot 2^{w-1} + \displaystyle\sum_{i=0}^{w-2} x_i \cdot 2^i −xw−1⋅2w−1+i=0∑w−2xi⋅2i
补码求法
正数:补码 = 原码
负数:|x| 的二进制 → 全部取反 → +1
例:-25 的 8 位补码
- 25 = 0001 1001
- 取反 = 1110 0110
- +1 = 1110 0111 = E7H
有符号 ↔ 无符号转换
核心:位模式不变,解释规则变
- T2U(有符号→无符号):负数变大正数,
新值 = 原值 + 2^w - U2T(无符号→有符号):大正数变负数,
新值 = 原值 - 2^w - C 语言陷阱:有符号数与无符号数混合运算时,有符号数隐式转为无符号
截断
- 直接保留低 k 位
- 无符号截断: x m o d 2 k x \mod 2^k xmod2k
- 有符号截断:先按无符号截断,再按补码重新解释
例:4 位 1011(补码=-5,无符号=11)截断到 3 位 → 011 → 补码=3,无符号=3
溢出判断
无符号加法溢出: s = x + y s = x + y s=x+y,若 s < x s < x s<x(或 s < y s < y s<y),则溢出
补码加法溢出:
- 正溢出:正 + 正 = 负(结果为 x + y − 2 w x + y - 2^w x+y−2w)
- 负溢出:负 + 负 = 正(结果为 x + y + 2 w x + y + 2^w x+y+2w)
- 正 + 负永远不溢出
乘除与移位
- 乘以 2 k 2^k 2k = 左移 k 位
- 无符号除以 2 k 2^k 2k = 逻辑右移 k 位
- 有符号除以 2 k 2^k 2k = 算术右移 k 位(向负无穷舍入)
- 编译器常用移位 + 加法代替乘法(如
x*12 = x*8+x*4 = (x<<3)+(x<<2)) - 整数除法比乘法慢
Ch5-2 浮点数
IEEE 754 格式
V = ( − 1 ) s × M × 2 E V = (-1)^s \times M \times 2^E V=(−1)s×M×2E
| 符号 s | 阶码 exp | 尾数 frac | |
|---|---|---|---|
| float (32 位) | 1 bit | 8 bit | 23 bit |
| double (64 位) | 1 bit | 11 bit | 52 bit |
Bias = 2 k − 1 − 1 2^{k-1} - 1 2k−1−1(float: 127,double: 1023)
三种类型
| 类型 | 阶码 | E | M | 用途 |
|---|---|---|---|---|
| 规格化 | 非全 0 非全 1 | exp - Bias | 1.frac | 大多数浮点数 |
| 非规格化 | 全 0 | 1 - Bias | 0.frac | 极小值和 ±0 |
| 特殊值 | 全 1 | — | frac=0→±∞; frac≠0→NaN | 特殊情况 |
- 规格化值的尾数有隐含的前导 1(即 M = 1.frac)
- 非规格化值的 E = 1 - Bias(不是 0 - Bias!为了与规格化平滑过渡)
- 浮点数的正负由符号位 s 决定(不是阶码决定)
- 阶码位数 → 影响范围;尾数位数 → 影响精度
- 基数(2)在机器数中隐含不出现
舍入
- 默认:向偶数舍入(Round to Nearest Even)
- 中间值(恰好在两个可表示值正中间)→ 向偶数方向凑
- 二进制中 " 向偶 "= 舍入后最低位为 0
浮点运算
- 加法步骤:对阶(小阶向大阶对齐)→ 尾数加法 → 规格化 → 舍入 → 判溢出
- 浮点加法满足交换律,不满足结合律
- 浮点乘法满足交换律,不满足结合律和分配律
(3.14 + 1e20) - 1e20= 0(不是 3.14!因为精度丢失)
C 语言类型转换
| 转换 | 结果 |
|---|---|
| int → double | 精确(double 有 52 位尾数,够装 32 位 int) |
| int → float | 不会溢出,但可能舍入(float 只有 23 位尾数) |
| float/double → int | 向零截断,可能溢出(行为未定义) |
Ch3 VSPM 原型机
- MOVB:从内存读一个字节到寄存器
- MOVC:将立即数(常数)写入寄存器
- MOVD:将寄存器值写入内存
- JMP:无条件跳转
- JG:大于时跳转(基于条件码判断)
Ch4 ATT 汇编语言
MOV 指令族
| 指令 | 操作数大小 |
|---|---|
movb |
1 字节 |
movw |
2 字节 |
movl |
4 字节 |
movq |
8 字节 |
限制:不能两个操作数都是内存,必须经过寄存器中转
零扩展 vs 符号扩展
| 指令 | 含义 | 高位填充 |
|---|---|---|
movzbl |
byte → long 零扩展 | 补 0 |
movzwl |
word → long 零扩展 | 补 0 |
movsbl |
byte → long 符号扩展 | 补符号位 |
movswl |
word → long 符号扩展 | 补符号位 |
例:%dh = 0xCD,%eax = 0x98765432
movzbl %dh, %eax→%eax = 0x000000CD(高位补 0)movsbl %dh, %eax→%eax = 0xFFFFFFCD(CD 最高位为 1,补 1)movb %dh, %al→%eax = 0x987654CD(只改低字节,高位不变)
LEA 指令
leal D(Rb, Ri, S), Dest → Dest = Rb + Ri × S + D
- 不访问内存,纯地址/算术计算
- 不设置条件码
- S 只能是 1, 2, 4, 8
常见题型:
leal 9(%eax,%ecx,2), %edx→ %edx = 9 + x + 2y(不是 9(x+2y))leal (%eax,%ecx,5), %edx→ %edx = x + 5y(不是 5x)leal 6(%eax), %edx→ %edx = x + 6(不是 6x)
寻址模式
| 类型 | 格式 | 计算 | 示例 |
|---|---|---|---|
| 立即数 | $Imm | 值就是 Imm | $0x400 |
| 寄存器 | %reg | R[reg] | %eax |
| 绝对 | Imm | M[Imm] | 0x400 |
| 间接 | (%reg) | M[R[reg]] | (%eax) |
| 基址+偏移 | Imm(%reg) | M[Imm + R[reg]] | 8(%ebp) |
| 比例变址 | Imm(Rb,Ri,S) | M[Imm + R[Rb] + R[Ri]×S] | (%edx,%ecx,4) |
Intel vs ATT 格式区别
| 区别 | ATT | Intel |
|---|---|---|
| 操作数顺序 | 源, 目的 | 目的, 源 |
| 寄存器前缀 | %eax |
eax |
| 大小后缀 | movl |
无后缀 |
| 内存引用 | 8(%ebp) |
[ebp+8] |
| 立即数前缀 | $ |
无 |
算术指令要点
inc/dec不改变 CF(与add 1的区别!)sal和shl完全等价(都是逻辑/算术左移,补 0)sar算术右移(填符号位),shr逻辑右移(填 0)
Ch6-1 条件码与控制
四个条件码
| 条件码 | 名称 | 含义 |
|---|---|---|
| CF | Carry Flag | 最高位进位/借位(无符号溢出) |
| ZF | Zero Flag | 结果为 0 |
| SF | Sign Flag | 结果为负(最高位为 1) |
| OF | Overflow Flag | 有符号溢出 |
不设置条件码的指令:lea、mov
CMP 与 TEST
cmp b, a:计算 a - b,只设条件码不存结果test b, a:计算 a & b,只设条件码不存结果test %eax, %eax:检测 %eax 是否为零/负
跳转指令
| 指令 | 条件 | 含义 |
|---|---|---|
je / jz |
ZF=1 | 等于/零 |
jne / jnz |
ZF=0 | 不等于/非零 |
js |
SF=1 | 负数 |
jg |
~(SF⊕OF) & ~ZF | 大于(有符号) |
jge |
~(SF⊕OF) | 大于等于(有符号) |
jl |
SF⊕OF | 小于(有符号) |
jle |
(SF⊕OF) | ZF | 小于等于(有符号) |
ja |
~CF & ~ZF | 高于(无符号 >) |
jae |
~CF | 高于等于(无符号 >=) |
jb |
CF | 低于(无符号 <) |
有符号比较核心:a < b ⟺ SF ⊕ OF = 1
条件传送
cmovX Src, Dest:条件为真时执行 mov,否则不操作
cmova:CF=0 且 ZF=0 时传送(无符号大于)
Ch6-2 过程调用与栈帧
栈操作
- 栈向低地址方向增长
pushl Src:%esp -= 4,然后M[%esp] = Srcpopl Dest:Dest = M[%esp],然后%esp += 4pushl %ebp等价于subl $4, %esp+movl %ebp, (%esp)
CALL / RET / LEAVE
| 指令 | 等价操作 | 作用 |
|---|---|---|
call Label |
push 返回地址 + jmp Label |
调用过程 |
ret |
pop %eip |
返回调用者 |
leave |
movl %ebp, %esp + popl %ebp |
恢复栈帧 |
call之后%esp减 4(压入返回地址)- 返回地址 =
call指令之后那条指令的地址(不是 call 本身的地址)
栈帧结构(从高地址到低地址)
参数 n
...
参数 1 ← 调用者栈帧
返回地址 ← call 指令压入
旧 %ebp ← 被调用者 push %ebp
局部变量 ← 被调用者栈帧
临时空间
← %esp(栈顶)
寄存器保护约定(IA32)
| 类型 | 寄存器 | 谁负责保存 |
|---|---|---|
| 调用者保存 | %eax, %ecx, %edx |
调用者在 call 前保存 |
| 被调用者保存 | %ebx, %esi, %edi |
被调用者在使用前 push,返回前 pop |
- 返回值存在
%eax %esp栈顶指针,%ebp帧指针- IA32 参数通过栈传递;x86-64 前 6 个参数通过寄存器(%rdi, %rsi, %rdx, %rcx, %r8, %r9)
关键判断
- 局部变量通过栈分配(不是堆)
- 程序寄存器组是唯一能被所有过程共享的资源 → 正确
- 函数不创建栈帧的条件:所有局部变量在寄存器中 + 不调用其他函数
pop %eip→ 不合法(不存在这条指令)
Ch6-3 数据结构
数组
T A[N]:分配 N × sizeof(T) 字节连续内存A[i]地址 = 基址 + i × sizeof(T)- 汇编:
movl (%edx,%eax,4), %eax→ 访问 int 数组 A[i]
二维数组
T D[R][C]:行优先,占 R × C × sizeof(T) 字节D[i][j]地址 = 基址 + (i × C + j) × sizeof(T)
结构体对齐(三规则)
- 首地址必须是最大成员字节数的整数倍
- 每个成员地址必须是自身字节数的整数倍(不够就插填充)
- 总大小必须是最大成员字节数的整数倍(末尾补填充)
优化技巧:大尺寸字段放前面,可减少填充
联合体
- 所有成员共享同一基地址
- 总大小 = 最大成员的大小
安全
- 缓冲区溢出:向栈上缓冲区写入过多数据,覆盖返回地址
- 三层防御:
- ASLR(地址空间布局随机化):每次运行地址不同
- Stack Canary(栈金丝雀):在返回地址前插入随机值,返回前校验
- NX bit(不可执行位):栈/堆标记为不可执行
- " 限制访问形式 "不是防溢出机制
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)