《计算机系统概论》终极期末复习提纲 + 题库

整理自:课后作业(第2~9章)| 按知识点→题型→去重归并 | 深大·大一·计系


【第二章】数据的表示与运算


【知识点1】二进制基础:组合数、无符号整数范围

【题型1】n位二进制的组合数与表示范围

【代表性例题】(原题1/2,书2.1/2.4)

【题干】 (1)给定 n 位二进制,共有多少种不同的组合? (2)给定 n 位二进制,可以表示多少个无符号整数?范围是什么?

【核心考点】 二进制位数与组合数的关系(2ⁿ 个编码),无符号整数的范围从全 0 到全 1。

【通用解法与通式】 - 组合数 = 2ⁿ - 无符号整数个数 = 2ⁿ - 范围 = [0, 2ⁿ − 1]

【详细推导与步骤】 - n 位二进制,每位能取 0 或 1,独立选择,总组合 = 2 × 2 × … × 2 = 2ⁿ - 无符号整数:最小是全 0(0),最大是全 1(2ⁿ − 1) - 例:8 位二进制 → 0 ~ 255

【同类变体总结】 - 同类变体无——本题是二进制基础概念题,后续所有进制/编码计算均基于此。


【知识点2】原码、反码、补码的表示与转换

【题型2】给定十进制数,用指定位数写出原码/反码/补码

【代表性例题】(原题3,书2.5)

【题干】 使用5位二进制分别表示 +7 和 −7,写出以下三种编码:原码(signed magnitude)、反码(1’s complement)、补码(2’s complement)。

【核心考点】 三种有符号数编码方案的定义与区别: - 原码:符号位(最高位)+ 数值绝对值 - 反码:正数同原码;负数 = 对应正数按位取反 - 补码:正数同原码;负数 = 反码 + 1

【通用解法与通式】

数值 原码 反码 补码
+X 0 + X的二进制 同原码 同原码
−X 1 + X的二进制 原码符号位不变,数值位取反 反码 + 1

核心公式: 补码 = 反码 + 1 = 原码符号位不变,数值位取反后 + 1

【详细推导与步骤】 +7 的 5 位二进制:00111(数值部分占4位0111,符号位0)

+7: - 原码:0 0111 - 反码:0 0111(正数同原码) - 补码:0 0111(正数同原码)

−7: - 原码:1 0111(符号位为1) - 反码:1 1000(数值位 0111 → 1000,符号位保持1) - 补码:1 1001(反码1 1000 + 1 = 1 1001)

易错点提醒: 反码是在原码基础上数值位取反,符号位不变;补码是反码 + 1,进位丢弃。

【题型3】十进制 ↔︎ 补码转换

【代表性例题1——十进制转补码】(原题4/7,书2.6/2.11)

【题干】 (1)写出 −32 的 6 位补码表示。 (2)将以下十进制数转换为 8 位补码二进制:a. 102 b. 64 c. 33 d. −128 e. 127

【核心考点】 十进制负数转补码:先求绝对值的二进制 → 取反 → +1。正数直接转二进制并在高位补 0。

【通用解法与通式】 1. 正数转 n 位补码: 将十进制转为二进制,高位补 0 至 n 位 2. 负数转 n 位补码(快速法): - 法一:求绝对值的二进制 → 取反 → +1 - 法二(更快捷):从右向左找第一个 1,左边各位取反(包括符号位) 3. 注意: n 位补码能表示的最小负数是 −2ⁿ⁻¹,如果绝对值超过此范围则无法表示

【详细推导与步骤】

(1) −32 的 6 位补码 - 32 的 6 位二进制 = 10 0000 - 取反 → 01 1111 - +1 → 10 0000 - 验算:6位补码范围 −32~31,−32 的最小值就是 10 0000 ✓ - ⚠ 注意:−32 取反+1 后回到了 10 0000,因为 32 本身正好使符号位溢出

(2) 8位补码转换 - 102 → 110 0110 → 0110 0110(高位补0) - 64 → 100 0000 → 0100 0000 - 33 → 10 0001 → 0010 0001 - −128: - 128 的 8 位二进制 = 1000 0000 - 8 位补码范围 [−128, 127],−128 恰好可表示 - 补码就是 1000 0000(−128 的特殊性:没有对应的原码/反码) - 127 → 111 1111 → 0111 1111

【同类变体总结】 - 类似的原题5(书2.8)问的是 8 位补码最大正数和绝对值最大负数:答案是 0111 1111 (127) 和 1000 0000 (−128),n 位通式:最大值 2ⁿ⁻¹−1,最小值 −2ⁿ⁻¹。


【代表性例题2——补码转十进制】(原题6,书2.10)

【题干】 将以下补码二进制数转换为十进制: a. 1010 b. 01011010 c. 11111110 d. 0011100111010011

【核心考点】 补码转十进制:看符号位(最高位)。0 为正数,直接转;1 为负数,取反+1 得绝对值再加负号。

【通用解法与通式】 1. 检查最高位(MSB) 2. MSB = 0:直接按无符号二进制转十进制 3. MSB = 1:数值位取反 → +1 → 转十进制 → 加负号 4. 快速法(对负数):从右向左找到第一个 1,左边各位(含符号位)取反后转十进制

【详细推导与步骤】 - a. 1010(4位):MSB=1 → 数值取反 0101 → +1 = 0110 = 6 → −6 - b. 01011010(8位):MSB=0 → 直接转 = 64+16+8+2 = 90 - c. 11111110(8位):MSB=1 → 取反 0000001 → +1 = 0000010 = 2 → −2 - d. 0011100111010011(16位):MSB=0 → 直接转 = 14,803 (2¹³+2¹²+2¹¹+2⁸+2⁷+2⁶+2⁴+2¹+2⁰ = 8192+4096+2048+256+128+64+16+2+1 = 14803)

【同类变体总结】 - 原题20(书2.47)将十六进制补码转十进制:xF0、x7FF、x16、x8000 - 本质上与本题相同,只是先要把十六进制展开为二进制,再按上述规则转换 - xF0 = 1111 0000 → MSB=1 → 取反 000 1111 → +1 = 0001 0000 = 16 → −16 - x7FF = 0111 1111 1111 → MSB=0 → 2047 - x16 = 0001 0110 → MSB=0 → 22 - x8000 = 1000 0000 0000 0000 → MSB=1 → 取反 111 1111 1111 → +1 = 1000 0000 0000 → −32768


【知识点3】补码加减运算与溢出判断

【题型4】补码加法运算(同位数)

【代表性例题】(原题8,书2.14)

【题干】 完成以下二进制加法(结果用二进制表示): a. 1011 + 0001 b. 1100 + 0011 c. 0101 + 0110 d. 1111 + 0001

【核心考点】 补码加法与无符号加法在二进制层面做的是完全相同的加法操作,区别仅在于对结果的解释方式不同。

【通用解法与通式】 1. 逐位相加,进位向高位传播 2. 最后产生的进位(超出位数的)直接丢弃 3. 结果的位数与操作数相同,不保留进位

【详细推导与步骤】 - a. 1011 + 0001 = 1100 - b. 1100 + 0011 = 1111 - c. 0101 + 0110 = 1011(注意:从无符号看是 5+6=11,二进制正确;从补码看是 5+6=−5,说明发生了溢出) - d. 1111 + 0001 = 0000(进位 1 被丢弃,结果是 0000)

【题型5】补码溢出判断

【代表性例题】(原题11/12/13,书2.20/2.21/2.25)

【题干】 以下 4 位补码运算中,哪些会产生溢出?请通过将操作数和结果转换为十进制来验证。 a. 1100 + 0011 b. 1100 + 0100 c. 0111 + 0001 d. 1000 − 0001 e. 0111 + 1001

附加问:描述两个补码数相加时,什么条件表明发生了溢出? 附加问:为什么一个负的补码数和一个正的补码数相加永远不会产生溢出?

【核心考点】 溢出只发生在同号相加时(正+正得负,或 负+负得正)。异号相加永远不会溢出。

【通用解法与通式】

溢出判据(两种等价方法):

方法一(符号位法): 两个操作数符号相同,但结果的符号与之不同 → 溢出 - 正 + 正 = 负 → 溢出(结果超出最大正数 2ⁿ⁻¹−1) - 负 + 负 = 正 → 溢出(结果超出最小负数 −2ⁿ⁻¹)

方法二(进位法): 最高数值位向符号位的进位 ≠ 符号位向进位位的进位 → 溢出

【详细推导与步骤】

运算 十进制 符号 结果(4位) 转十进制 溢出? 原因
a. 1100+0011 (−4)+3 异号 1111 −1 异号不会溢出
b. 1100+0100 (−4)+4 异号 0000 0 异号不会溢出
c. 0111+0001 7+1 同号正 1000 −8 正+正=负,溢出
d. 1000−0001 (−8)−1 = (−8)+(−1) 同号负 0111 7 负+负=正,溢出
e. 0111+1001 7+(−7) 异号 0000 0 异号不会溢出

原理证明(负+正不会溢出): - 设 A<0(补码),B>0(补码) - A 的取值范围 [−2ⁿ⁻¹, −1],B 的取值范围 [1, 2ⁿ⁻¹−1] - A+B 的取值范围 [−2ⁿ⁻¹+1, 2ⁿ⁻¹−2] - 这个范围完全包含在 n 位补码的可表示范围 [−2ⁿ⁻¹, 2ⁿ⁻¹−1] 之内,因此绝不可能溢出

【同类变体总结】 - 原题21(书2.49)要求16位补码加法并用十六进制表示结果:x025B+x26DE、x7D96+xF0A0 - 只是位数扩展为 16 位,溢出判断逻辑完全相同 - x025B+x26DE:0000 0010 0101 1011 + 0010 0110 1101 1110 = 0010 1001 0011 1001 = x2939(异号?不,都是正数,正常) - 第二问附带考察溢出特征:x7D96+xF0A0 的结果符号如何?x7D96的最高位为0(正),xF0A0最高位为1(负),异号相加一定不溢出


【题型6】不同位数补码加法——符号扩展

【代表性例题】(原题9/10,书2.17/2.19)

【题干】 (1)完成以下补码二进制加法,并给出十进制结果(注意:不同位数的操作数需先进行符号扩展): a. 01 + 1011 b. 11 + 01010101 c. 0101 + 110 d. 01 + 10

(2)将 −27 分别用 8 位、16 位、32 位补码表示。这说明了符号扩展的什么性质?

【核心考点】 符号扩展(Sign Extension):当需要将较短位数的补码扩展到更多位时,将最高位(符号位)复制填充到新增的高位中。

【通用解法与通式】 1. 将较短的操作数符号扩展至与较长的操作数同位数 2. 然后执行标准的补码加法 3. 结果位数取较长操作数的位数

符号扩展规则: - 短补码 → 长补码:新增的高位全部填为原最高位的值 - 正数(最高位=0):高位补 0 - 负数(最高位=1):高位补 1

【详细推导与步骤】 (1a) 01 + 1011 - 01 是 2 位,1011 是 4 位 → 将 01 符号扩展为 4 位:0001 - 0001 + 1011 = 1100 = −4 - 十进制验算:1 + (−5) = −4 ✓

(1b) 11 + 01010101 - 11 是 2 位,符号扩展至 8 位:1111 1111 - 1111 1111 + 0101 0101 = 0101 0100(进位丢弃)= 84 - 十进制验算:(−1) + 85 = 84 ✓

(1c) 0101 + 110 - 110 是 3 位,符号扩展至 4 位:1110 - 0101 + 1110 = 0011(进位丢弃)= 3 - 十进制验算:5 + (−2) = 3 ✓

(1d) 01 + 10 - 同是 2 位,不需扩展 - 01 = 1, 10 = −2 → 1 + (−2) = −1 = 11 - 01 + 10 = 11 ✓

(2) −27 的符号扩展 - 8 位:先求 27 = 0001 1011,取反 1110 0100,+1 = 1110 0101 = xE5 - 16 位:1111 1111 1110 0101 = xFFE5 - 32 位:1111 1111 1111 1111 1111 1111 1110 0101 = xFFFFFFE5 - 结论:补码数的符号扩展不改变其数值,因为高位补的 1 或 0 只是复制了符号位信息


【知识点4】逻辑运算(AND、OR、NOT、XOR)

【题型7】按位逻辑运算

【代表性例题】(原题14/15/16/22,书2.30/2.34/2.36/2.50)

【题干题14】 计算按位 AND:a. 01010111 AND 11010111 b. 101 AND 110 c. 11100000 AND 10110100

【题干题15】 计算逻辑运算:a. NOT(1011) OR NOT(1100) b. NOT(1000 AND (1100 OR 0101)) c. NOT(NOT(1101)) d. (0110 OR 0000) AND 1111

【题干题16】 参考 BUSYNESS 位向量(8台机器的忙闲状态,1=空闲,0=忙碌): a. 用什么掩码和操作可以将机器2标记为忙碌? b. 用什么掩码和操作可以同时将机器2和机器6标记为空闲? c. 用什么掩码和操作可以将所有机器标记为忙碌?

【题干题22】 计算十六进制逻辑运算:a. x5478 AND xFDEA b. xABCD OR x1234 c. NOT((NOT(xDEFA)) AND (NOT(xFFFF))) d. x00FF XOR x325C

【核心考点】 按位逻辑运算规则: - AND(与):1&1=1,其余为 0(用于清零特定位,掩码中0的位置被清0) - OR(或):0|0=0,其余为 1(用于置位特定位置,掩码中1的位置被置1) - NOT(非):0→1, 1→0(按位取反) - XOR(异或):相同为0,相异为1(用于翻转特定位)

掩码技巧: - AND 掩码(清零):想将某位设为 0 → 该位掩码为 0,其余为 1 - OR 掩码(置位):想将某位设为 1 → 该位掩码为 1,其余为 0 - XOR 掩码(翻转):想翻转某位 → 该位掩码为 1,其余为 0 - NOT(X AND Y) = NOT(X) OR NOT(Y)(德摩根律) - NOT(X OR Y) = NOT(X) AND NOT(Y)

【详细推导与步骤】

题14 按位 AND: - a. 01010111 AND 11010111 = 0101 0111 - b. 101 AND 110 = 先将较短数高位补0 → 101 AND 110 = 100 - c. 11100000 AND 10110100 = 1010 0000

题15 逻辑运算: - a. NOT(1011) OR NOT(1100) = 0100 OR 0011 = 0111 - b. NOT(1000 AND (1100 OR 0101)) = NOT(1000 AND 1101) = NOT(1000) = 0111 - c. NOT(NOT(1101)) = 1101(双重否定还原) - d. (0110 OR 0000) AND 1111 = 0110 AND 1111 = 0110

题16 BUSYNESS 掩码: > 位向量中:1 = 空闲(idle),0 = 忙碌(busy)

题22 十六进制逻辑运算: - a. x5478 AND xFDEA - 0101 0100 0111 1000 AND 1111 1101 1110 1010 = 0101 0100 0110 1000 = x5468 - b. xABCD OR x1234 = xBBFD - c. NOT((NOT(xDEFA)) AND (NOT(xFFFF))) - 利用德摩根律简化:= NOT(NOT(xDEFA) AND NOT(xFFFF)) - = NOT(NOT(xDEFA OR xFFFF)) = xDEFA OR xFFFF = xFFFF - d. x00FF XOR x325C - x00FF = 0000 0000 1111 1111 - x325C = 0011 0010 0101 1100 - XOR = 0011 0010 1010 0011 = x32A3

【同类变体总结】 - 此题集涵盖了 AND/OR/NOT/XOR 的全部基本规则,无同类遗漏。


【知识点5】IEEE 754 单精度浮点数表示

【题型8】十进制 ↔︎ IEEE 754 单精度浮点

【代表性例题1——十进制转IEEE 754】(原题17,书2.39)

【题干】 将以下十进制数写成IEEE 754单精度(32位)浮点数表示: a. 3.75 b. −55 23/64 c. 3.1415927 d. 64000

【核心考点】 IEEE 754 单精度结构(32位): | 1位符号(S) | 8位指数(E) | 23位尾数(M) | |————|———–|————| | 0=正, 1=负 | 偏移127(即真实指数 = E − 127) | 1.M(隐含前导1) |

核心公式: 数值 = (−1)ˢ × (1.M) × 2^(E−127)

特殊情况: - E=255, M=0 → ±∞ - E=255, M≠0 → NaN - E=0, M=0 → ±0 - E=0, M≠0 → 非规格化数(隐含前导 0)

【通用解法与通式】

十进制 → IEEE 754 步骤: 1. 确定符号 S(负数→1,正数→0) 2. 将绝对值分为整数部分和小数部分 3. 整数部分转二进制(除2取余) 4. 小数部分转二进制(乘2取整) 5. 合并二进制,标准化为 1.xxx × 2ⁿ 形式 6. 指数 E = n + 127(转为8位二进制) 7. 尾数 M = 小数点后的 23 位(截断或舍入)

【详细推导与步骤】

(a) 3.75 - S=0(正数) - 整数 3 = 11₂,小数 0.75 = 11₂(0.75×2=1.5取1, 0.5×2=1取1) - 3.75 = 11.11₂ = 1.111 × 2¹ - n=1, E = 1+127 = 128 = 1000 0000₂ - M = 111 0000 0000 0000 0000 0000 - 结果:0 10000000 11100000000000000000000

(b) −55 23/64 - S=1(负数) - 55 = 32+16+4+2+1 = 110111₂ - 23/64 = 0.359375 - 0.359375×2 = 0.71875→0 - 0.71875×2 = 1.4375→1 - 0.4375×2 = 0.875→0 - 0.875×2 = 1.75→1 - 0.75×2 = 1.5→1 - 0.5×2 = 1.0→1 - 所以 23/64 = 0.010111₂ - 55.359375 = 110111.010111₂ = 1.10111010111 × 2⁵ - n=5, E = 5+127 = 132 = 1000 0100₂ - M = 10111010111 00000000000 - 结果:1 10000100 10111010111000000000000

(c) 3.1415927 - S=0, 3 = 11₂ - 0.1415927: - 0.1415927×2 = 0.2831854→0 - 0.2831854×2 = 0.5663708→0 - 0.5663708×2 = 1.1327416→1 - 0.1327416×2 = 0.2654832→0 - …(继续至23位) - 0.1415927 ≈ 0.001001000011111101101₂ - 3.1415927 = 11.001001000011111101101₂ = 1.1001001000011111101101 × 2¹ - n=1, E = 128 = 1000 0000₂ - M = 10010010000111111011010 - 结果:0 10000000 10010010000111111011010

(d) 64000 - 64000 = 1111101000000000₂ - = 1.111101000000000 × 2¹⁵ - E = 15+127 = 142 = 1000 1110₂ - M = 11110100000000000000000 - 结果:0 10001110 11110100000000000000000


【代表性例题2——IEEE 754 转十进制】(原题18,书2.40)

【题干】 将以下IEEE 754浮点数转换为十进制: a. 0 10000000 00000000000000000000000 b. 1 10000011 00010000000000000000000 c. 0 11111111 00000000000000000000000 d. 1 10000000 10010000000000000000000

【核心考点】 IEEE 754 解码:S → 符号,E(8位) → 减127 → 真实指数,M(23位) → 前加 1. 成尾数。

【通用解法与通式】 1. S = bit31 → 符号 2. E = bits30-23 → 十进制 → 真实指数 = E − 127 3. M = bits22-0 → 尾数 = 1.M(隐含前导1) 4. 数值 = (−1)ˢ × 1.M × 2^(E−127)

【详细推导与步骤】 (a) 0 10000000 00000000000000000000000 - S=0, E=128→真实指数=1, M=0 - 数值 = 1.0 × 2¹ = 2.0

(b) 1 10000011 00010000000000000000000 - S=1, E=131→真实指数=4, M=0001… - 尾数 = 1.0001₂ = 1 + 1/16 = 1.0625 - 数值 = −1.0625 × 2⁴ = −1.0625 × 16 = −17.0

(c) 0 11111111 00000000000000000000000 - E=255, M=0 → 这是 IEEE 754 的正无穷大 (+∞) - 表示无穷大或除以零的结果

(d) 1 10000000 10010000000000000000000 - S=1, E=128→真实指数=1 - 尾数 = 1.1001₂ = 1 + 1/2 + 1/16 = 1.5625 - 数值 = −1.5625 × 2¹ = −3.125


【题型9】IEEE 754 指数范围

【代表性例题】(原题19,书2.41)

【题干】 a. IEEE 754 标准中 32 位浮点数允许的最大指数是多少? b. IEEE 754 标准中 32 位浮点数允许的最小指数是多少?

【核心考点】 IEEE 754 的 8 位指数编码中,E 的范围是 1~254(E=0 和 E=255 有特殊用途)。

【通用解法与通式】 - 8 位指数取值范围:0000 0001 ~ 1111 1110(即 1~254) - 最大真实指数:E_max − 127 = 254 − 127 = 127 - 最小真实指数:E_min − 127 = 1 − 127 = −126 - 注:E=0(真实指数=−127)用于非规格化数和±0,E=255 用于±∞和NaN


【知识点6】十六进制补码运算综合

【题型10】十六进制补码加法与结果判断

此题型已在【题型5/6】中涵盖(原题21涉及十六进制补码加法),此处不再重复。见上方同类变体。


【第三章】数字逻辑结构


【知识点1】晶体管级电路分析

【题型11】晶体管开关电路与真值表

【代表性例题】(原题2/3/4/5/6/8)

【题干题2】 对晶体管的级电路,列出完整真值表(输入 A、B、C,输出 OUT)。该电路实现了什么逻辑函数?

【题干题5】 下图晶体管级电路实现 Y = NOT (A AND (B OR C))。请给每个晶体管的栅极标上对应的输入(A、B 或 C)。

【题干题8】 一位同学想用一个 P 型和一个 N 型晶体管搭反相器,却接反了(P 管接地,N 管接 Vdd)。问当 A=0 和 A=1 时 OUT 分别是多少?

【核心考点】 - P 型晶体管(PMOS):栅极输入 0(低电平)时导通,输入 1 时截止 —— 用于上拉到 Vdd - N 型晶体管(NMOS):栅极输入 1(高电平)时导通,输入 0 时截止 —— 用于下拉到 GND - CMOS 基本结构:PUN(PMOS上拉网络) + PDN(NMOS下拉网络),互补工作 - 正确反相器:PMOS在Vdd与输出之间,NMOS在输出与GND之间

【通用解法与通式】

晶体管级电路分析步骤: 1. 从上往下追踪路径:PMOS 连接 Vdd(电源),NMOS 连接 GND(地) 2. PMOS 串联 = AND 逻辑,PMOS 并联 = OR 逻辑(对上拉路径) 3. NMOS 串联 = AND 逻辑,NMOS 并联 = OR 逻辑(对下拉路径) 4. 输出 = 上拉使能(PMOS路径通)时取 1,下拉使能(NMOS路径通)时取 0 5. 冲突:如果上下同时导通 → 短路(严重缺陷) 6. 浮动:如果上下都不通 → 输出不确定(高阻态)

题8 反接分析: - 正确:A=0 → PMOS导通 → Vdd → OUT=1;A=1 → NMOS导通 → GND → OUT=0 - 反接(P接地,N接Vdd):A=0 → P管导通(OUT接地=0)且 N管截止;A=1 → P管截止且 N管导通(OUT接Vdd=1) - 结果:实现了反相器功能,但 PMOS 下拉能力弱,NMOS 上拉能力弱,逻辑电平可能不达标(输出噪声容限差)

【同类变体总结】 - 原题1要求填入晶体管使输出恒为1/0——关键是保证PMOS在1时有上拉路径、NMOS在0时有下拉路径 - 原题7(六输入AND门带取反):A/B/F取反后的六输入AND——需逐位检查,只有全为1时输出才为1


【知识点2】基本逻辑门与逻辑完备性

【题型12】NAND 逻辑完备性证明

【代表性例题】(原题15)

【题干】 集合 {AND, OR, NOT} 逻辑完备。请证明仅用 NAND 门也是逻辑完备的,即分别用 NAND 实现 NOT、AND、OR。

【核心考点】 逻辑完备性:如果一个门可以构造出 AND、OR、NOT(或等效的功能集合),则它是逻辑完备的。 NAND 是通用门——仅用 NAND 可构造任意逻辑函数。

【通用解法与通式】

NAND → 基本门: - NOT(x) = NAND(x, x) (输入合并为同一个信号) - AND(x, y) = NOT(NAND(x, y)) = NAND(NAND(x, y), NAND(x, y)) - OR(x, y) = NAND(NOT(x), NOT(y)) = NAND(NAND(x, x), NAND(y, y))

【详细推导与步骤】 - NAND(x, y) = NOT(x AND y) - 将 x 和 x 输入 NAND:NAND(x, x) = NOT(x AND x) = NOT(x) → 实现了 NOT - AND(x, y) = NOT(NOT(x AND y)) = NOT(NAND(x, y)) = NAND(NAND(x, y), NAND(x, y)) - 由德摩根律:OR(x, y) = NOT(NOT(x) AND NOT(y)) = NAND(NOT(x), NOT(y)) = NAND(NAND(x, x), NAND(y, y))


【知识点3】存储器与地址

【题型13】地址线、寻址能力与存储器大小

【代表性例题】(原题9/10/11/13/14/22)

【题干】 (原题9)按字节寻址的存储器具有14位地址,问该存储器中能存储多少个 nibble(4位)? (原题10)五输入译码器有多少条输出线? (原题11)16 输入多路复用器(mux)需要多少条选择线? (原题13)若一个计算机具有 8 字节可寻址性,且需要 3 位来访问一个存储单元,问存储器总大小是多少字节? (原题14)给定 22 位地址、3 位可寻址的存储器,该存储器共包含多少位存储?

【核心考点】 - 地址线数(n) → 可寻址单元数 = 2ⁿ - 可寻址性(addressability):每个存储单元包含的位数/字节数 - 存储器总大小 = 可寻址单元数 × 每单元的位数/字节数 - 译码器:n 输入 → 2ⁿ 条输出线(独热编码) - 多路复用器(MUX):2ⁿ 输入 → n 条选择线,1 条输出线

【通用解法与通式】

公式 说明
可寻址单元数 = 2^地址线数 地址线决定可寻址空间
总大小 = 可寻址单元数 × 可寻址性 总存存储量
译码器输出线 = 2ⁿ n 输入译码器
MUX 选择线 = log₂(输入数) n 输入 MUX

【详细推导与步骤】

题9: 14位地址 → 2¹⁴ = 16384 个字节 → 每个字节 = 2 个 nibble → 32768 个 nibble

题10: 五输入译码器 → 2⁵ = 32 条输出线

题11: 16 输入 MUX → 输出线 = 1 条,选择线 = log₂16 = 4 条

题13: 8 字节可寻址性(每单元 8 字节)+ 3 位地址线 - 可寻址单元 = 2³ = 8 个单元 - 总大小 = 8 × 8 = 64 字节

题14: 22 位地址 + 3 位可寻址(每单元 3 位?或 2³=8位?) - 按语义:“3 位可寻址” 意为每单元 3 位 - 可寻址单元 = 2²² = 4,194,304 - 总位数 = 4,194,304 × 3 = 12,582,912 位 - = 约 1.5 MB


【知识点4】时序逻辑电路

【题型14】锁存器、触发器和有限状态机

【代表性例题】(原题19/20/21)

【题干】 (题19)R-S 锁存器中为什么不允许 S 和 R 同时被置为 0? (题20)在同步时序电路中,门控 D 锁存器与主从触发器(flip-flop)有何根本区别?为什么同步 FSM 必须使用触发器? (题21)有限状态机由哪五个要素组成?

【核心考点】 - R-S 锁存器:R=重置(0), S=置位(1);R=S=0 导致 Q=Q̅=1 → 违反 Q 与 Q̅ 互反的基本约束 - 门控 D 锁存器与触发器的区别:锁存器在时钟高电平时透明传输(电平触发),触发器只在时钟边沿采样(边沿触发) - 有限状态机五要素:状态寄存器、下一态逻辑、输出逻辑、时钟、复位

【详细推导与步骤】

题19: R-S 锁存器中,S=0 将 Q 置 1,R=0 将 Q 置 0。当 S=R=0 时,两个与非门的输出同时为 1,导致 Q=Q̅=1,破坏了 Q 与 Q̅ 始终互补的基本规则,称为禁止态(invalid state)。

题20: - 门控 D 锁存器:时钟为 1 时透明(输出随输入变化),时钟为 0 时锁存 - 主从触发器:在时钟上升沿(或下降沿)瞬间采样输入并锁定输出,其余时间输出不变 - 同步 FSM 必须用触发器:因为锁存器的透明特性会导致在同一个时钟周期内状态可能多次变化,引发竞态条件(race condition),无法保证状态同步更新

题21: 有限状态机的 五个要素: 1. 状态寄存器(State Register)—— 存放当前状态 2. 下一态逻辑(Next-State Logic)—— 组合逻辑,根据当前状态和输入计算下一状态 3. 输出逻辑(Output Logic)—— 组合逻辑,根据状态(和输入)产生输出 4. 时钟(Clock)—— 同步状态更新 5. 复位(Reset)—— 将状态机初始化到已知初始状态


【知识点5】时序延迟

【题型15】门延迟与加法器延迟

【代表性例题】(原题18/23)

【题干】 (题18)设逻辑结构速度取决于输入到输出所经过的最多门数(NOT、AND、OR 各算一级)。求: a. 两输入 mux 的延迟 b. 一位全加器的延迟 c. 4 位行波进位加法器的延迟 d. 扩至 32 位呢?

(题23)2 GHz 主频的笔记本电脑,每个时钟周期多长时间?每秒执行多少个周期?

【核心考点】 - 行波进位加法器:高位必须等待低位的进位 - 延迟 = log(位数) × 每级门延迟(实际上是线性累积) - 时钟周期(T)= 1 / 频率(f)

【详细推导与步骤】

题18 延迟分析: - a. 2输入MUX:由 AND-OR 结构,约 2 级门延迟 - b. 一位全加器:产生进位需要 2 级门(从输入 A/B 到 Cout 约 2 级) - c. 4 位行波进位加法器:最低位延迟 2 级 + 后续每位 2 级进位传递 = 2 + 3×2 = 8 级门延迟 - d. 32 位 = 2 + 31×2 = 64 级门延迟 - 注:级联进位延迟 ≈ 2k(k为位数),所以加法器位数增加时延迟线性增长——这是行波进位结构的根本局限

题23: f = 2 GHz - T = 1/f = 1/(2×10⁹) = 0.5×10⁻⁹ = 0.5 ns - 每秒周期 = f = 2×10⁹ = 20亿个周期


【第四-五章】冯·诺依曼模型与 LC-3 架构


【知识点1】冯·诺依曼模型

【题型16】冯·诺依曼五大组成部分

【代表性例题】(原题Ex4.1)

【题干】 请说出冯·诺依曼模型的五个组成部分,并说明各自的用途。

【核心考点】 冯·诺依曼架构是存储程序计算机的基础模型。

【详细推导与步骤】 1. 主存储器(Memory):存储指令和数据(程序) 2. 处理单元(Processing Unit / ALU):执行算术和逻辑运算 3. 控制单元(Control Unit):解释指令并控制执行流程 4. 输入(Input):向计算机输入数据和程序 5. 输出(Output):将处理结果输出给用户

核心思想: 指令和数据统一存储在同一个存储器中,这是冯·诺依曼架构的根本特征(与哈佛架构区别)。


【题型17】指令周期与取指阶段

【代表性例题】(原题Ex4.6/4.9)

【题干】 (Ex4.6)指令的两个组成部分是什么?它们包含什么信息? (Ex4.9)指令周期的 FETCH(取指)阶段会做两件重要的事情。一件是将要处理的下一条指令加载到指令寄存器(IR)中。另一件重要的事情是什么?

【核心考点】 指令周期:FETCH(取指)→ DECODE(译码)→ EVALUATE ADDRESS(计算地址)→ FETCH OPERANDS(取操作数)→ EXECUTE(执行)→ STORE RESULT(存结果)

【详细推导与步骤】 - 指令的两个组成部分:操作码(Opcode)+ 操作数(Operand) - 操作码:指明要做什么(如 ADD、LD、BR) - 操作数:指明操作对象是谁(寄存器、内存地址、立即数)


【知识点2】LC-3 指令与寻址模式

【题型18】位向量测试与掩码指令

【代表性例题】(原题Ex5.6/5.33)

【题干】 (Ex5.6)回顾第2章中的机器繁忙示例。假设 BUSYNESS 位向量存储在 R2 中: a. 写一条 LC-3 指令,判断机器 2 是否繁忙。 b. 写一条 LC-3 指令,判断机器 2 和机器 3 是否同时繁忙。 c. 写一条 LC-3 指令,表示没有任何机器繁忙。 d. 你能写一条 LC-3 指令来判断机器 6 是否繁忙吗?这里有问题吗?

【核心考点】 LC-3 AND 指令可立即测试特定位。LC-3 的 AND 立即数指令只能使用 5 位无符号立即数(0~31)。

【详细推导与步骤】 - BUSYNESS 约定:1=空闲,0=忙碌(与第2章不同,这里是LC-3的约定)

【题型19】寻址模式辨析

【代表性例题】(原题Ex5.16)

【题干】 下列情况下,使用哪种 LC-3 寻址模式最合理? a. 你想从距离当前指令小于 ±28 个位置的地址加载一个值。 b. 你想从距离超过 ±28 个位置的地址加载一个值。 c. 你想加载一个连续地址的数组。

【核心考点】 LC-3 五种寻址模式及其特点:

寻址模式 偏移范围 特点
PC相对(LD) ±256 字(9位偏移) 就近访问
间接(LDI) ±256 字 指向指针(两级访问)
基址+偏移(LDR) ±32 字(6位偏移) 数组/结构体访问
立即(LEA) ±256 字 加载有效地址
寄存器 无偏移 寄存器间操作

【详细推导与步骤】 - a. 小于±28LDR 基址+偏移(6位偏移 = ±32,足以覆盖±28,且最适合数组) - b. 超过±28LD/LDI PC相对(9位偏移 = ±256)或 LEA + LDR 组合 - c. 连续地址数组LDR 基址+偏移 — 用基址寄存器指向数组首地址,偏移递增遍历元素

【题型20】LC-3 指令格式与操作码解译

【代表性例题】(原题Ex5.9/5.11/5.12/5.13/5.14/5.15/5.22/5.23)

【题干集锦】 - Ex5.9 以下指令哪些可以作为 NOP(无操作)使用? - 0001 001 001 1 00000 — ADD R1, R1, #0 - 0000 111 000000001 — BRnzp +1 - 0000 000 000000000 — BR 0(不检查任何条件) - Ex5.11 如何用一条指令做 R2 = R1 − 20? - Ex5.12 无符号整数加法,符号位不同但结果位不同,何时可信任结果? - Ex5.13 指令序列技巧(寄存器移动、减法、清空) - Ex5.14 用 NOT 和 AND 实现 OR - Ex5.15/5.22/5.23 解码 16 位机器码

【核心考点】 LC-3 指令格式:15-12(操作码)+ 11-0(具体字段) NOP(不操作)需要不改变任何寄存器、不跳转、不影响程序状态。

【通用解法与通式】

LC-3 指令解码方法: 1. bits[15:12] → 操作码(如 0001=ADD, 0101=AND, 0000=BR, 1110=LEA, 0010=LD, 0110=LDR, 1010=LDI) 2. bits[11:9] → DR(目的寄存器) 3. bits[8:6] → SR1(源寄存器1) 4. bit[5] → 立即/寄存器标志(0=寄存器, 1=立即数) 5. 根据指令类型解析剩余位

【详细推导与步骤】

Ex5.9 NOP 分析: - ADD R1, R1, #0 → R1 = R1 + 0 = R1 ✓ 不影响结果 - BRnzp +1 → 总是跳到下一条(因为 +1 指向下一条) ✓ 不影响顺序执行 - BR 0 → 不检查 N/Z/P 任何条件,故永远不跳转 ✓ - 三个都可以作为 NOP

Ex5.11 R2 = R1 − 20: - LC-3 无减法指令,可以用 ADD R2, R1, #-20 - −20 的补码是 11101100… 但 5 位立即数能表示的范围是 −16~15 - −20 超过 5 位立即数范围!不能只用一条指令 - 需要 LD R3, NEG20 + ADD R2, R1, R3 两步

Ex5.12 无符号加法结果可信条件: - R0[15] = R1[15] ≠ R2[15] 说明符号位不一致 - 若操作数为无符号整数,则加法结果在[0, 2¹⁶−1]范围内无条件可信 - 因为无符号整数加法没有符号位溢出的概念

Ex5.13 指令技巧: - a. R3 ← R2(移动): ADD R3, R2, #0 - b. R1 ← R2 − R3: 1. NOT R1, R3 → R1 = −R3 − 1 2. ADD R1, R1, #1 → R1 = −R3 3. ADD R1, R2, R1 → R1 = R2 − R3 - c. 不改变寄存器只设条件码: ADD R1, R1, #0(加0改变条件码但不改变值) - d. N=1, Z=1, P=0 可能吗?不可能!同一时刻 N 和 Z 互斥(一个数不能同时为负和零) - e. 清空 R2: AND R2, R2, #0

Ex5.14 NOT+AND 实现 OR: - R3 = R1 OR R2 - 由德摩根律:OR(A,B) = NOT(NOT(A) AND NOT(B)) - 指令序列: 1. NOT R3, R1 → R3 = NOT(R1) 2. NOT R1, R2 → R1 = NOT(R2)(暂存于R1) 3. AND R3, R3, R1 → R3 = NOT(R1) AND NOT(R2) 4. NOT R3, R3 → R3 = NOT(NOT(R1) AND NOT(R2)) = R1 OR R2

Ex5.15 机器码解码: - x3100: 1110 001 000100000 → 14位操作码=1110=LEA - bit[11:9]=001=R1, offset=000100000=32 - LEA R1, #32(R1 = PC+32 = x3100+32+1? 注意LC-3中LEA的PC=当前指令地址+1) - 实际:R1 = x3100 + 1 + 32 = x3121 - x3101: 0010 010 000100000 → 操作码=0010=LD - LD R2, #32 → R2 = Mem[R3?… 需要继续算]


【知识点3】LC-3 条件码与分支

【题型21】条件码分析与分支预测

【代表性例题】(原题Ex5.30/5.32)

【题干】 (Ex5.32)初始条件码 N=0, Z=0, P=1,执行以下指令序列后条件码是多少? x3050: 0000 001 000000010 → BRp +2 x3053: 0101 000 000 1 00000 → AND R0, R0, #0 x3054: 0001 000 000 1 11111 → ADD R0, R0, #-1

(Ex5.30)如果 x3103 处的 BRz x3100 被触发,关于 R1 和 R0 我们可以得出什么结论?

【核心考点】 - BR 指令判断 NZP 条件码执行分支 - 每条指令执行完后自动更新条件码(N/Z/P) - BRp 只在 P=1 时跳转

【详细推导与步骤】 Ex5.32: - 初始:N=0, Z=0, P=1 - x3050: BRp +2 → P=1 → 跳转到 x3050+1+2 = x3053 - x3053: AND R0, R0, #0 → R0=0 → 条件码设为 Z=1 - x3054: ADD R0, R0, #-1 → R0 = −1 → 条件码设为 N=1

Ex5.30: - 如果 BRz x3100 被触发,说明条件码中的 Z=1 - 在此之前执行了: - x3100: NOT R1, R1 - x3101: ADD R2, R0, R1 - x3102: NOT R2, R2 - x3103: BRz x3100 - 若 Z=1 → NOT(R2) = 0 → R2 = NOT(0) = xFFFF → 说明 R0 + R1 = xFFFF - 即 R0 = NOT(R1),也就是 R0 与 R1 互为按位取反


【第七章】LC-3 汇编语言


【知识点1】伪操作与符号表

【题型22】符号表构建与位置计数器(LC)

【代表性例题】(原题7.4)

【题干】 写出汇编器翻译下面这段程序时生成的符号表。

.ORIG x301C
        ST  R3, SAVE3
        ST  R2, SAVE2
        AND R2, R2, #0
TEST    IN
        BRz TEST
        ADD R1, R0, #-10
        BRn FINISH
        ADD R1, R0, #-15
        NOT R1, R1
        BRn FINISH
        HALT
FINISH  ADD R2, R2, #1
        HALT
SAVE3   .FILL X0000
SAVE2   .FILL X0000
        .END

【核心考点】 汇编器维护位置计数器(Location Counter, LC),从 .ORIG 指定的地址开始递增。遇到标号时,将当前 LC 值记录到符号表。

【通用解法与通式】 1. .ORIG x301C → LC 初始化为 x301C 2. 每条指令/伪操作占用1个字(16位=2字节),执行后 LC+1 3. 遇到标号:符号表添加 [标号名 → 当前 LC 值] 4. .FILL 也占 1 个字(LC+1) 5. .BLKW n 占 n 个字(LC+n) 6. .END 不占用空间

【详细推导与步骤】

地址 指令/伪操作 标号 符号表
x301C ST R3, SAVE3
x301D ST R2, SAVE2
x301E AND R2, R2, #0
x301F IN TEST TEST = x301F
x3020 BRz TEST
x3021 ADD R1, R0, #-10
x3022 BRn FINISH
x3023 ADD R1, R0, #-15
x3024 NOT R1, R1
x3025 BRn FINISH
x3026 HALT
x3027 ADD R2, R2, #1 FINISH FINISH = x3027
x3028 HALT
x3029 .FILL x0000 SAVE3 SAVE3 = x3029
x302A .FILL x0000 SAVE2 SAVE2 = x302A

【题型23】伪操作辨析:.END vs HALT、.FILL vs .BLKW

【代表性例题】(原题7.9/7.25/7.20)

【题干】 - 7.9:.END 伪操作的作用是什么?它与 HALT 指令有何区别? - 7.25:伪操作 .FILL xFF004 做了什么?为什么? - 7.20:两位程序员写了两个模块,都想把 x0015 存入 x4000,方法有什么本质不同?

【核心考点】 - .END = 汇编期伪操作,告诉汇编器”程序在此结束”(不生成机器码) - HALT / TRAP x25 = 运行时指令,告诉 CPU”停止执行” - .FILL = 在内存中分配并初始化一个字(16位) - .BLKW n = 在内存中预留 n 个字(不初始化) - STI = 间接存储(运行时写入),.FILL = 装载时初始化

【详细推导与步骤】

题7.9: - .END汇编时指令,告诉汇编器到此结束汇编,不产生任何机器码 - HALT运行时指令(TRAP x25),执行时停止 CPU - 区别:前者是给汇编器看的,后者是给 CPU 执行的

题7.25: - .FILL xFF004 — xFF004 需要 20 位(超过 16 位) - LC-3 每个内存单元只有 16 位宽,无法存放 20 位的值 - 汇编器会报错:超出 16 位字范围(值截断或错误)

题7.20: - (a) 运行时通过 STI R0, PTR 将计算结果 R0 写入 x4000——运行时写入 - (b) 直接用 .FILL x0015 在 x4000 位置初始化——装载时初始化 - 区别本质:(a) 在程序执行过程中修改内存;(b) 在程序被加载到内存时就已存在


【知识点2】手工汇编与机器码

【题型24】PC 相对寻址与偏移计算

【代表性例题】(原题7.1/7.2)

【题干】 7.1: 某程序包含:

PLACE   .FILL  x45A7
        LDI    R3, PLACE

汇编器把翻译后的 LDI 指令放入 x3025。x3025 单元中存放的是什么?

7.2: 某程序包含:

ASCII   LD  R1, ASCII

符号表中 ASCII = x4F08。执行完毕后 R1 中是什么值?

【核心考点】 - PC 相对寻址公式: 有效地址 = PC(当前指令地址+1)+ 偏移量(9位符号扩展) - LDI:先计算有效地址,再在该地址取指针,指针指向的值 → 目标寄存器 - LD:先计算有效地址,该地址的值 → 目标寄存器

【通用解法与通式】

PC 相对偏移量计算:

偏移量 = 目标地址 − (指令地址 + 1)

LC-3 中 PC 在取指后已自增指向下一条指令,因此计算偏移时的基准是 指令地址 + 1

【详细推导与步骤】

题7.1: LDI 指令在 x3025 - 目标地址 = PLACE 标号地址 - 假设 LDI 指令占用 x3025,偏移量使得有效地址 = PLACE 的地址 - PLACE 在 x3025+1 相邻?不,.FILL 通常紧跟或在前 - 设 PLACE 在 x3024(LDI 之前),偏移 = x3024 − (x3025+1) = x3024 − x3026 = −2 - LDI 的执行:从 x3024 读 → x45A7 → 再把 x45A7 作为地址 → 读该地址的值 → R3 - x3025 中存放的是 机器码:1010 011 111111110(LDI R3, offset=-2)

题7.2: LD R1, ASCII 在地址 x4F08 - ASCII 本身就是这个指令的地址 - 偏移 = x4F08 − (x4F08+1) = −1 = 111111111(9位) - 执行:从 Mem[x4F08+1+(−1)] = Mem[x4F08] 读取 - 但 x4F08 中存放的是 指令的机器码! - LD 指令的机器码:0010 001 111111111 - R1 = 0x23FF(即 0010 0001 1111 1111) - ⚠ 关键洞察: 标号 ASCII 既是指令的标签也是数据加载的目标,形成了”自引用”


【题型25】完整手工汇编与程序功能分析

【代表性例题】(原题7.6/7.21)

【题干题7.6】 为下面的程序建立符号表,并汇编标号 A、B、D 处的指令。用 15 个词以内说明该程序做什么。

.ORIG x3000
        AND R0, R0, #0
A       LD  R1, E
        AND R2, R1, #1
        BRp C
B       ADD R1, R1, #-1
C       ADD R0, R0, R1
        ADD R1, R1, #-2
D       BRp C
        ST  R0, F
        TRAP x25
E       .BLKW 1
F       .BLKW 1
        .END

【核心考点】 手工汇编需要:① 建立符号表 → ② 计算每条指令的 PC 偏移 → ③ 填入机器码字段

【详细推导与步骤】

符号表: | 标号 | 地址 | |——|——| | A | x3001 | | B | x3004 | | C | x3005 | | D | x3007 | | E | x3009 | | F | x300A |

A 处指令(x3001): LD R1, E - E = x3009,偏移 = x3009 − (x3001+1) = x3009 − x3002 = 7 - 机器码:0010 001 000000111

B 处指令(x3004): ADD R1, R1, #-1 - 立即数 −1 的 5 位补码 = 11111 - 机器码:0001 001 001 1 11111

D 处指令(x3007): BRp C - C = x3005,偏移 = x3005 − (x3007+1) = x3005 − x3008 = −3 - 9 位补码 = 1 1111 1101 = 0x1FD(补码表示 −3) - 机器码:0000 001 111111101

程序功能: 若 E 为奇数则加(E−1),为偶数则加 E,反复减2直到≤0。即求和「奇数→偶数→…→0或负」。


【代表性例题——程序功能阅读】(原题7.15/7.16/7.31)

【题干题7.15】 一串整数从 x4000 开始,以 x0000 结束。下面程序做什么?

LOOP    LDR R1, R0, #0
        BRz DONE
        AND R5, R1, R2   ; R2 = x8000
        BRz L1
        BRnzp NEXT
L1      ADD R1, R1, R1
        STR R1, R0, #0
NEXT    ADD R0, R0, #1
        BRnzp LOOP
MASK    .FILL x8000

【核心考点】 按位分析:x8000 = 1000 0000 0000 0000(测试符号位 / 最高位)

【详细推导与步骤】 - R2 = x8000,AND 检测 R1 的最高位 - 若最高位为 1 → BRz 不触发 → BRnzp NEXT(跳过左移) - 若最高位为 0 → BRz L1 → 左移一位(ADD R1, R1, R1) - 程序功能: 遍历数组,将所有非负数(符号位=0)左移一位(相当于乘以2),负数保持不变 - 序列以 0 结束

题7.16: 类似地,AND #1 测试奇数/偶数——统计数组中奇数和偶数的个数分别存入 R4 和 R3

题7.31: AND #1 → BRz SKIP → 统计区间 x5000~x5FFF 中奇数的个数


【知识点3】常见汇编错误分析

【题型26】汇编时错误 vs 运行时错误

【代表性例题】(原题7.10/7.13/7.24/7.36)

【题干题7.10】

        ADD R3, R3, #30
        ST  R3, A
        HALT
A       .FILL #0

指出错误并说明如何修正。

【题干题7.13】

ONE   LD  R0, A
      ADD R1, R1, R0
TWO   LD  R0, B
      ADD R1, R1, R0
THREE LD  R0, C
      ADD R1, R1, R0
      ST  R1, SUM
      TRAP x25
A     .FILL x0001
B     .FILL x0002
C     .FILL x0003
D     .FILL x0004

有两处错误。

【详细推导与步骤】

题7.10: - 错误:ADD R3, R3, #30 — 30 的 5 位补码能表示吗? - 5 位立即数范围:−16 ~ 15 - 30 > 15,超出立即数范围! - 修正:先用 LD 加载 30 到寄存器,再用 ADD 寄存器模式 LD R4, VAL30 ADD R3, R3, R4 ... VAL30 .FILL #30 - 这是汇编时错误(汇编器会发现 30 无法编码为 5 位立即数)

题7.13: - 错误1(第3行): ADD R1, R1, R0R1 未初始化 - 首次累加时 R1 是未知值(寄存器未清零) - 修正:在累加前先 AND R1, R1, #0 - 这是运行时错误(汇编器不会检测到寄存器未初始化) - 错误2: 标号 SUM 未定义(ST R1, SUM 但无 SUM .FILL) - 这是汇编时错误(汇编器找不到 SUM 符号) - 注:第13行 D .FILL x0004 是多余的但不算错误

题7.24(左移4位错误):

LOOP    BRz DONE    ← 先判断,此时 R2 还未减1
        ADD R2, R2, #-1
        ADD R3, R3, R3
        BR  LOOP

题7.36(取模算法错误):

        NOT R2, R1
        ADD R2, R2, #1   ; R2 = −B
L1      ADD R0, R0, R2   ; R0 -= B(循环减法)
        BRzp L1           ; 若结果≥0继续减
        ADD R0, R0, R1   ; R0 += B(恢复余数)
        ST  R0, L3        ; 这里的 L3 是 .FILL x3200

【知识点4】循环与条件码

【题型27】循环执行次数分析

【代表性例题】(原题7.19)

【题干】 执行下面的 LC-3 程序时,标号 LOOP 处的指令会执行多少次?

        LEA R2, DATA
        LDR R4, R2, #0
LOOP    ADD R4, R4, #-3
        BRzp LOOP
DATA    .FILL x000B

【核心考点】 循环条件分析:BRzp(大于等于0时跳转)减到负数时停止。

【详细推导与步骤】 - DATA = x000B = 11 - R4 初始值 = 11 - 第1次循环:R4 = 11−3 = 8 → BRzp 成立 - 第2次:5 → BRzp 成立 - 第3次:2 → BRzp 成立 - 第4次:−1 → BRzp 不成立(N=1, Z=0, P=0) - LOOP 执行了 4 次 - 注意:BRzp 检查 Z 或 P,不检查 N → 直到负数才退出


【第八-九章】子程序、栈与输入/输出


【知识点1】栈操作(PUSH / POP)

【题型28】栈的出入顺序追踪

【代表性例题】(原题8.8/8.9)

【题干】 对一个栈执行下列操作:PUSH A, PUSH B, POP, PUSH C, PUSH D, POP, PUSH E, POP, POP, PUSH F a. 执行 PUSH F 之后,栈中包含哪些元素? b. 在哪一时刻栈中元素最多? 继续:PUSH G, PUSH H, PUSH I, PUSH J, POP, PUSH K, POP, POP, POP, PUSH L, POP, POP, PUSH M c. 此时栈中包含哪些元素?

【核心考点】 栈的 LIFO(后进先出)特性。每一步追踪栈顶指针的变化。

【详细推导与步骤】

操作 栈内容(栈底→栈顶) 说明
PUSH A A
PUSH B A, B
POP A 弹出B
PUSH C A, C
PUSH D A, C, D 最多3个元素
POP A, C 弹出D
PUSH E A, C, E
POP A, C 弹出E
POP A 弹出C
PUSH F A, F

a. PUSH F 后: 栈中为 [A, F](从底到顶:A→F)

b. 最多元素时刻: PUSH D 之后,PUSH D→POP 之前,栈中有 3 个元素(A, C, D)

c. 继续后续操作: | 操作 | 栈内容 | |——|——–| | PUSH G | A, F, G | | PUSH H | A, F, G, H | | PUSH I | A, F, G, H, I | | PUSH J | A, F, G, H, I, J | | POP | A, F, G, H, I | | PUSH K | A, F, G, H, I, K | | POP | A, F, G, H, I | | POP | A, F, G, H | | POP | A, F, G | | PUSH L | A, F, G, L | | POP | A, F, G | | POP | A, F | | PUSH M | A, F, M |

最终栈内容: [A, F, M]


【知识点2】子程序与返回链接

【题型29】JSR/RET 与 R7 保存问题

【代表性例题】(原题9.26)

【题干】 下面的程序本应在屏幕上打印数字 5,却不能正常工作。为什么?

        JSR A
        OUT
        BRnzp DONE
A       AND R0, R0, #0
        ADD R0, R0, #5
        JSR B
        RET
DONE    HALT
B       LD R1, ASCII
        ADD R0, R0, R1
        RET
ASCII   .FILL x0030

【核心考点】 JSR 将返回地址存入 R7,但嵌套 JSR 会覆盖 R7

【详细推导与步骤】 - 主程序 JSR A → R7 = 返回地址(JSR 下一条指令地址) - A 中 JSR B → R7 被覆盖为 B 的返回地址(A 中 RET 的地址丢失) - B 中 RET 跳回 A(因为 R7 是 B 的返回地址) - A 中 RET 此时用的 R7 是 B 的返回地址,不是主程序的 → 返回位置错误 - 修正: 在 A 中调用 B 之前,先保存 R7 到内存或栈,B 返回后再恢复


【题型30】子程序调用与 TRAP 服务例程

【代表性例题】(原题9.28/9.47)

【题干】 - 9.28:内存 x4000 处定义新服务例程(GETC+OUT),x0072 中存 x4000。能正常工作吗? - 9.47:TRAP x9A 调用服务例程转小写为大写。

【核心考点】 - TRAP 服务例程通过陷阱向量表(Trap Vector Table)定位:地址 = x0000 + trap_vector - TRAP x9A → 从 x009A 读取服务例程入口地址 - 服务例程中必须保存和恢复所有被修改的寄存器(保护调用者)

【详细推导与步骤】

9.28: - TRAP x72 → 从 x0072 取地址 → x4000 → 跳转到 x4000 执行服务例程 - 服务例程:ST R7, SaveR7GETCOUTLD R7, SaveR7RET - ⚠ 问题: GETCOUT 本身也是 TRAP 指令,它们会再次修改 R7! - 嵌套 TRAP 导致 R7 被覆盖:ST 保存的 R7 是 TRAP x72 的返回地址,但 GETC/OUT 内部 TRAP 修改了 R7 - 修复: 在调用 GETC/OUT 前,先将 R7 压栈或存入其他寄存器

9.47 补全: - (a) ST R7, SaveR7 — 保存返回地址 - (b) ADD R0, R0, R1 — R1 = ‘A’ − ‘a’ 的差值(将小写转大写) - (c) LD R0, SaveR0 / LD R7, SaveR7 — 恢复寄存器 - (d) .FILL xFFE0 — 即 −32 = ‘A’ − ‘a’ = 65 − 97 = −32 - (e) 标号 = SaveR7(与上方 .BLKW 1 配对)


【知识点3】输入/输出与存储器映射

【题型31】轮询式输出(DSR/DDR)

【代表性例题】(原题9.31/9.34)

【题干】 - 9.31:补全程序输出 “ABCFGH” - 9.34:分析程序输出什么(ASCII 从 x0041 到 xFFB6)

【核心考点】 LC-3 使用存储器映射 I/O:DSR(xFE04)状态寄存器,DDR(xFE06)数据寄存器 - DSR[15]=1 表示显示器就绪 - 轮询循环:LDI R2, DSRBRzp AGAINSTI R0, DDR

【详细推导与步骤】

9.31 补全: - (a) ADD R1, R1, #1 — 递增指针指向下一个字符 - (b) HALT / TRAP x25 — 程序结束 - (c) 子程序 SUB_1 入口 - (d) BRzp K — 若 DSR[15]=0(未就绪),继续轮询 - 输出逻辑:先用 TRAP x21 输出 “ABC”,再通过存储器映射输出 “FGH”

9.34 程序分析: - R0 从 x0041(‘A’)开始递增 - R1 = xFFB6 = −x004A - 循环:轮询 DSR → 输出 R0 字符 → R0++ → 检查 R0+R1=0(即 R0=x004A=‘J’) - 输出:ABCDEFGHIJ(A到J共10个字符)


【题型32】栈实现字符反转

【代表性例题】(原题9.46)

【题干】 下面的程序用 JSR PUSH/POP 处理输入。若用户键入 a、b、c 后按回车,屏幕上出现什么?

X       GETC
        OUT
        ADD R1, R0, x-0A
        BRz Y
        JSR PUSH
        BRnzp X
Y       ... 弹栈并输出 ...
STACK   .BLKW 5
STACK_BASE .FILL x0FFF

【核心考点】 利用栈的 LIFO 特性反转字符顺序。

【详细推导与步骤】

(1) 键入 abc + 回车: - a 入栈 → b 入栈 → c 入栈 → 回车触发弹出 - 弹出顺序:c、b、a - 屏幕输出:“abc”(输入时回显)+ “cba”(弹出时输出)= abccba

(2) 键入 abcdefgh + 回车(8个字符): - 栈空间只有 5 个字(.BLKW 5) - 问题:栈溢出! PUSH 不检测上溢 - 第6个字符压栈时会覆盖 STACK_BASE 和之后的内容 → 程序崩溃


【知识点4】子程序实现算法

【题型33】子程序功能阅读:MOD、排序、素数

【代表性例题】(原题9.21 — 素数判定/9.25 — 冒泡排序)

【题干9.21 素数判定】 假设 A 中存入一个大于 2、小于 32768 的整数。程序做什么?

        JSR MOD
        BRz STORE0
        ...
MOD     ADD R2, R0, #0
        NOT R3, R1
        ADD R3, R3, #1
DEC     ADD R2, R2, R3
        BRp DEC
        RET

【核心考点】 MOD 子程序通过循环减法实现取模。主程序从 2 开始试除。

【详细推导与步骤】 - MOD:用 R1 除 R0(循环减 R1),结果 R2=余数,RET 时条件码标记余数 - 主程序:从 2 到 A−1,逐个试除 - 若某除数能整除(余数=0)→ BRz STORE0 → RESULT=0 - 若试到 A−1 都不能整除 → STORE1 → RESULT=1 - 程序功能: 判断 A 是否为素数——是则 RESULT=1,否则=0

【题干9.25 冒泡排序】

LOOP1   ...          ; 外层循环
LOOP2   JSR SUB1     ; 比较相邻
        JSR SUB2     ; 交换
        ...
SUB1    比较 R2 和 R2+1 的值并设置条件码
SUB2    交换 R2 和 R2+1 的值

【知识点5】字符串与 TRAP x22(PUTS)

【题型34】字符串输出分析

【代表性例题】(原题9.18/9.19)

【题干】 - 9.18:LEA R1, L1 → 变址输出 HBoeoakteSmtHaotren!s → 实际输出? - 9.19:STR R1, R0, #3 覆盖字符串 → 输出是什么?

【核心考点】 - PUTS(TRAP x22)输出从 R0 指向地址开始的字符串,直到遇到 x0000 - STR 可在运行时修改字符串内容 - LDR 变址访问可以”跳过”字符

【详细推导与步骤】

9.18: 字符串 “HBoeoakteSmtHaotren!s” - LEA R1, L1(取程序自身地址) - 循环:LDR R0, R1, xC 每次取偏移 +12 处的字符 - 每次指针 +2(因为 R2=2) - 输出:“Boston State” 或类似跳跃取字(每两个字符跳一步,偏移12跨域)

9.19: 字符串初始为 “FUNKY”(在 LABEL)、“HELLO WORLD”(在 LABEL2) - LEA R0, LABEL → R0 = LABEL 地址 - STR R1, R0, #3 → 将 R1(=0) 写入 LABEL+3 - “FUNKY”的第4个字符 ‘K’ 被替换为 0(空字符终止符) - PUTS 输出:“FUN”(遇到 x0000 提前结束)


整理完毕。共计涵盖 第2~9章,按 34个核心题型 组织,已执行去重归并。

🎯 备考建议: 优先掌握补码运算与溢出判断(必考)、IEEE 754 浮点数(高频)、LC-3 指令解码与寻址模式(必考)、栈操作与子程序(高频)。