计算机组成原理:定点运算核心概念与实战习题精解
1. 从“算”到“理”:为什么课后习题比听课更重要
学计算机组成原理,尤其是学到定点运算这一章,很多同学会陷入一个误区:把教材上的公式和框图看懂了,例题也跟下来了,就觉得自己掌握了。但一到做课后习题,尤其是微课版教材里那些设计精巧的题目,立刻就卡壳,感觉无从下手。这太正常了,因为听课和看书是“输入”,是理解别人梳理好的逻辑;而做题是“输出”,是逼着你用自己的话把知识重新组织、应用一遍。定点运算这一块,恰恰是计算机硬件设计的基石,它不讲虚的,全是实打实的逻辑门、进位链、溢出判断。你公式背得再熟,不会在具体场景下分析一个补码加减法的溢出,不会手动推导一位乘法的过程,那等于没学。
我自己当年学这门课,以及后来带学生、做项目涉及到底层优化时,感触最深的一点就是:对定点运算的深刻理解,直接决定了你日后是只能调用高级语言库函数的“码农”,还是能进行系统级性能优化的“工程师”。比如,在做嵌入式开发时,STM32这类MCU没有硬件浮点单元(FPU),你要处理小数怎么办?全靠定点数运算。再比如,写图形渲染或者音频处理的高性能代码,为了极致效率,也经常需要把浮点运算转化为定点运算来避免昂贵的浮点指令。这些实战需求,根源都在《计算机组成原理》的这第三章里。
所以,面对微课版第三章的课后习题,别把它当成负担,而应该视作一次难得的“实战演练”。这份答案和解析的目的,不是让你抄完应付作业,而是希望通过拆解每一道典型题目,带你穿透概念的表象,看到数据在ALU(算术逻辑单元)中流动、变换、溢出的完整过程,把“组成原理”真正变成你自己的“肌肉记忆”。接下来,我们就抛开笼统的概述,直接切入核心,从最基础的运算器结构开始,一步步拆解那些让你头疼的习题。
2. 运算器核心:ALU、寄存器与数据通路
在做任何具体运算题目之前,我们必须先在心里搭建一个最简化的运算器模型。很多同学做题出错,不是因为运算规则没记牢,而是根本不清楚“数在哪里”、“怎么过去”、“结果存哪儿”。这个模型不需要像教材框图那么复杂,但几个关键部件必须清晰。
2.1 核心部件功能与互动关系
想象一个最简单的定点运算场景:计算A + B。
- 操作数来源(寄存器):数A和数B并不是凭空出现的。它们通常预先存放在两个专用的寄存器中,比如累加器ACC(Accumulator)和通用寄存器X。在题目中,ACC和X就是你的“临时工作台”。
- 运算执行者(ALU):算术逻辑单元是真正的“算盘”。它从ACC和X接收数据,根据控制信号(是加、减、还是与、或)执行运算。
- 结果与状态(ACC与标志位):运算的结果通常会直接覆盖原来的ACC内容。同时,ALU还会设置一些标志位,比如:
- 溢出标志OF:最重要的标志之一,表示有符号数的运算结果超出了表示范围。
- 零标志ZF:结果是否为全0。
- 符号标志SF:结果的符号位(最高位)是0还是1。
- 进位标志CF:表示无符号数运算最高位是否有进位(加法)或借位(减法)。
它们之间的关系,可以用一个简单的数据流来描述:(ACC) 和 (X) -> [ALU] -> (ACC), 同时[ALU] -> {标志寄存器}。在做题时,尤其是顺序执行多条运算指令的题目,你必须时刻跟踪ACC和X寄存器里的内容变化,以及标志位的状态,就像在调试器里单步执行一样。
2.2 微课版习题常见考点剖析
基于这个模型,我们来看微课版习题常怎么考:
- 考点一:给定ACC和X初值,求运算后ACC和标志位。这是最直接的考法。你需要严格按照补码(对于有符号数)或原码(对于无符号数,但计算机内部通常也用补码做加减)的运算规则计算,并独立判断溢出(OF)和进位(CF)。这里最容易混淆的就是OF和CF的判断方法不同。
- 考点二:分析一段简单的指令序列。例如:先
LOAD X, A(把数A装入X),再ADD B(ACC加B),再STORE C(存结果)。你需要手动模拟这个过程。这里的关键是理解“隐含寻址”——ADD B这条指令,可能隐含了一个操作数在ACC,另一个操作数B来自内存或X寄存器,具体要看题目约定的指令格式。 - 考点三:结合移位操作。定点乘除法的核心就是“移位+加减”。题目可能会让你手动模拟一位乘法(原码一位乘或补码一位乘)的一两个步骤,这时候就需要你清晰地画出部分积寄存器、乘数寄存器的移位过程,以及每次加什么(加被乘数、加被乘数的负补码、还是加0)。
注意:做题时,一定要把每个寄存器的位数(比如8位、16位)牢牢记在脑子里。这是判断溢出、进行符号扩展等所有操作的前提。忽略位数是初学者最常犯的错误,没有之一。
3. 定点加减运算:溢出判断是灵魂
加减法是基础,但这里的“坑”几乎全集中在溢出判断上。很多同学公式记得滚瓜烂熟:“两个正数相加得负,两个负数相加得正,就溢出了”。但一到复杂情况或者结合标志位分析,就迷糊了。我们得从根上理解。
3.1 补码加减运算与溢出逻辑
计算机内部,有符号数一律用补码表示和运算。补码的好处是,减法可以化为加法来做:[A]补 - [B]补 = [A]补 + [-B]补。所以,无论是加还是减,最终在ALU里都是做加法。
溢出的本质,是运算结果超出了给定位数补码所能表示的范围。对于一个n位补码(含1位符号位),其表示范围是[-2^(n-1), 2^(n-1)-1]。比如8位补码范围是-128~+127。
如何判断溢出?有两种等效且必须掌握的方法:
- 双符号位判断法(变形补码):这是教材重点,也是理解溢出的最佳方式。将符号位扩充为两位:
00表示正,11表示负。运算后,看两位符号位:- 如果结果是
01, 表示正溢出(两个正数相加超过了最大正数)。 - 如果结果是
10, 表示负溢出(两个负数相加超过了最小负数)。 - 如果结果是
00或11, 则无溢出。 运算时,数都用双符号位表示,符号位也参与运算。这个方法非常直观,能清晰地看到溢出是如何发生的。
- 如果结果是
- 单符号位结合进位判断:根据最高位(符号位)的进位
Cs和次高位(数值最高位)向符号位的进位Cp进行异或:OF = Cs ⊕ Cp。若为1,则溢出。这个方法更接近硬件实际实现。
3.2 典型习题精解与易错点
我们来看一道经典题型:已知8位补码表示的机器数X和Y,求[X+Y]补和[X-Y]补,并判断是否溢出。
假设X = 0x6A(二进制01101010,十进制+106),Y = 0x7B(二进制01111011,十进制+123)。
第一步:计算 [X+Y]补直接用补码相加:
01101010 (X补 = +106) + 01111011 (Y补 = +123) --------------- 11100101 (结果补码)看结果符号位为1,表示负数。但两个正数相加怎么会得负呢?显然溢出了。
- 用双符号位验证:
X = 00 1101010,Y = 00 1111011。相加:
00 1101010 + 00 1111011 --------------- 01 1100101双符号位为01,符合正溢出的特征。结果11100101作为8位补码解释是-27,这显然是错误的,因为106+123=229,远超8位补码正数最大值127。所以运算无效,需要硬件通过溢出标志OF=1来中断或处理。
第二步:计算 [X-Y]补先求[-Y]补,即对Y补(01111011)逐位取反末位加1:10000101。
01101010 (X补) + 10000101 ([-Y]补) --------------- 11101111 (结果补码)符号位为1,结果是负数-17。计算106-123=-17,正确。
- 判断溢出:双符号位运算,
X=00 1101010,[-Y]补=11 0000101(注意负数的双符号位是11):
00 1101010 + 11 0000101 --------------- 11 1101111 (最高位进位1自然丢弃)双符号位为11,无溢出。或者用进位法,符号位进位Cs=1,次高位进位Cp=0,1⊕0=1?等等,这里要注意,我们说的Cs是符号位产生的进位,Cp是次高位向符号位的进位。在这个加法中,次高位(第6位向第7位)有进位吗?我们需要仔细列竖式看每一位的进位情况。为了避免混淆,对于减法,更稳妥的方法是直接用双符号位判断,或者牢记:正减正(或负减负)才有可能溢出,正减负(或负减正)不可能溢出。106和123都是正数,X-Y是正数减正数,结果范围在[-106, 106](因为Y可能比X大),完全在8位补码范围内,所以不可能溢出。这个“定性分析”有时比硬算更快。
易错点总结:
- 混淆溢出与进位:进位(CF)是针对无符号数运算的,溢出(OF)是针对有符号数运算的。两者判断电路不同,意义完全不同。8位机上,
0xFF + 0x01 = 0x00,对于无符号数(255+1=256)产生了进位(CF=1),但对于有符号数(-1+1=0)却没有溢出(OF=0)。 - 忘记位数限制:始终记住你是在n位环境下运算。结果超出n位就被截断,但标志位记录了这些“异常”信息。
- 减法转加法时出错:求
[-Y]补时,必须对Y的补码(包括符号位)整体取反加1,不能只对数值部分操作。
4. 定点乘法运算:从笔算到硬件实现
乘法比加减法复杂得多,核心思想是分解为“加法+移位”。教材主要讲解原码一位乘和补码一位乘(Booth算法)。习题往往考察你对这个过程的理解,而不是让你完成整个冗长的计算。
4.1 原码一位乘法:清晰但低效
原码乘法的规则很简单:符号位单独异或,数值部分按绝对值相乘。这与我们十进制的笔算乘法非常相似。
硬件实现时,需要三个寄存器:ACC(存放部分积,初始为0)、X(存放被乘数绝对值)、MQ(乘数寄存器,存放乘数绝对值,同时也会在运算中右移)。
运算过程(以定点整数为例):
- 从乘数MQ的最低位开始判断。
- 如果当前位为1,则部分积ACC加上被乘数X。
- 如果当前位为0,则ACC加0。
- 完成加法后,ACC和MQ联合起来进行一次算术右移(ACC的最低位进入MQ的最高位,ACC的最高位补符号位,对于原码乘法,因为操作的是绝对值,所以补0)。
- 重复步骤1-4,判断MQ的下一位(因为右移了,所以下次判断的位其实是原来的次低位),直到所有位处理完毕。
- 最终结果的高位在ACC,低位在MQ。
习题常见考法:给出被乘数X和乘数Y的原码,让你写出进行到第k步时的ACC和MQ的值。关键在于跟踪每一步的“加”和“移”操作。
例如:X=0.1101,Y=0.1011, 求原码一位乘的前三步。
- 初始化:
ACC=00.0000,X=00.1101,MQ=.1011(最低位1加下划线表示当前判断位)。 - 步骤1(判断MQ最低位1):
ACC + X = 00.0000 + 00.1101 = 00.1101。然后联合右移:ACC=00.0110,MQ=1.101(最右边补入了ACC移出的1?这里注意,ACC移出的最低位是1,进入MQ最高位。更规范的写法是ACC=00.0110 1,MQ=1 101,但通常把ACC和MQ看成一个整体,ACC存高位部分,MQ存低位及乘数剩余部分)。 - 步骤2(判断MQ新的最低位1):
ACC + X = 00.0110 + 00.1101 = 01.0011。右移:ACC=00.1001 1,MQ=1 10。 - 步骤3(判断MQ新的最低位0):
ACC + 0 = 00.1001 1。右移:ACC=00.0100 11,MQ=1 1。
通过这样一步步拆解,你就能清晰看到部分积是如何累积,乘数是如何被消耗的。
4.2 补码一位乘法(Booth算法):统一与高效
原码乘法需要单独处理符号,且对补码直接运算不友好。Booth算法的伟大之处在于它能用同一套逻辑直接处理补码数,并且当乘数中连续出现多个1时,可以减少加法次数,提高效率。
Booth算法的核心是重新编码乘数。它在乘数的最低位的右边增加一个辅助位Y_(n+1),初始为0。判断位由Y_i和Y_(i+1)两位组成,规则如下:
(Y_i, Y_(i+1)) = (0, 0)或(1, 1): 部分积ACC右移一位。(0, 1): ACC加上[X]补,然后右移。(1, 0): ACC加上[-X]补,然后右移。
运算从最低位对开始,每次操作后算术右移(ACC和MQ作为整体,ACC符号位不变,最高位补符号位)。需要循环n+1次(n为数值位数)。
为什么Booth算法更优?因为它把连续的“1”转换成了“加一次、减一次”的操作。例如乘数片段...011110...,在原码乘法中需要连续加4次被乘数;而在Booth编码下,011110可以看作+10000 - 00010(从右向左看边界),实际只需要一次加和一次减操作。
习题常见考法:给出[X]补和[Y]补,让你填写Booth算法的运算过程表,或者问进行到某一步时ACC和MQ的值。解题的关键是:
- 正确设置辅助位,并记住判断规则。
- 每次右移是算术右移,ACC的空位补符号位(即ACC原来的最高位)。
- 最后一步移位可能与其他步骤不同(有些教材描述最后一步不移位),务必以题目指定的算法版本为准。
实操心得:无论是原码乘还是补码乘,在纸上模拟时,建议画一个表格,列清楚每一步的“判断位”、“ACC操作”、“ACC操作后值”、“右移后ACC值”、“右移后MQ值”。这样一步一记录,清晰不易乱。尤其是在处理负数补码和算术右移时,表格能帮你严格跟踪符号位的变化。
5. 定点除法运算:恢复余数与加减交替
除法是定点运算中最复杂的,其核心思想是**“比较、减、移位”**。教材主要讲解原码除法的恢复余数法和加减交替法(不恢复余数法)。习题重点在于理解迭代过程。
5.1 恢复余数法:直观但速度慢
和我们笔算除法很像:比较被除数(或当前余数)和除数。如果够减(余数非负),则上商1,并做减法得到新余数;如果不够减(余数为负),则上商0,并且恢复原来的余数(把减掉的除数加回去),然后再进行后续操作。
硬件流程:
- 被除数放在ACC和MQ中(ACC存高位部分)。
- 将ACC和MQ整体左移一位。
- 用ACC(高位部分)减去除数(绝对值),结果放回ACC。
- 判断ACC符号:
- 若ACC >= 0(够减),则MQ最低位上1。
- 若ACC < 0(不够减),则MQ最低位上0,并恢复余数(ACC加回除数)。
- 重复步骤2-4,直到获得所需的商位数。
这个方法最大的问题就是“恢复余数”这一步,它增加了一次不必要的加法操作,降低了速度。
5.2 加减交替法(不恢复余数法):实用的优化
加减交替法是对恢复余数法的改进。它发现了一个规律:当余数为负(不够减)时,恢复余数(加除数)后左移,等价于先将负余数左移一位,再加上除数。
于是规则简化为:
- 初始化:被除数放在ACC和MQ中。
- 根据上一轮余数的符号决定本轮操作:
- 若上一轮余数 >= 0: 余数左移一位,减除数。
- 若上一轮余数 < 0: 余数左移一位,加除数。 (第一轮操作可以看作“上一轮余数”为被除数,通常直接执行“减除数”)。
- 根据本轮操作后新余数的符号上商:
- 若新余数 >= 0, 上商1。
- 若新余数 < 0, 上商0。
- 重复步骤2-3。
这个方法避免了显式的“恢复”步骤,每一步要么加、要么减,规律统一,硬件实现更简单,速度更快。
习题典型场景:给定被除数和除数(原码形式),让你用加减交替法计算几步,写出每一步的余数和商。这里的关键是记住规则取决于“上一轮余数符号”,并且上商取决于“本轮操作后的新余数符号”。容易出错的地方是第一步的操作,以及左移时ACC和MQ的联合操作(ACC移出的最高位进入MQ的最低位)。
例如:X=0.1011(被除数),Y=0.1101(除数),计算两步。
- 初始化:
ACC=00.1011(双符号位防溢出),MQ=0.0000(商),Y=00.1101。 - 第一步:因无“上一轮余数”,约定先做减法。
ACC - Y = 00.1011 - 00.1101 = 11.1110(补码运算,结果为负)。新余数R0 = 11.1110 < 0,故上商0。此时MQ=0.0000。 - 第二步:因
R0 < 0,本轮应“左移后加除数”。- 左移:
ACC和MQ联合左移一位。ACC=11.1100,MQ=0.0000(ACC移出的1进入MQ最低位?这里注意,左移时,ACC的最高位移出丢弃,最低位进入MQ的最高位,MQ本身左移,最低位补0。更准确地说,是将ACC和MQ看作一个整体寄存器进行左移)。我们更关注ACC的变化:R0左移一位后变为11.1100(数值部分1110)。 - 加除数:
ACC + Y = 11.1100 + 00.1101 = 00.1001(最高位进位溢出,双符号位00,正数)。新余数R1 = 00.1001 >= 0,故上商1。MQ=0.0001。
- 左移:
通过这个过程,你能清晰地看到余数如何波动,商如何逐位确定。
6. 标志位的综合应用与程序流控制
运算器不是孤立的,它的标志位(OF, ZF, SF, CF)直接服务于程序的控制流。这也是习题中常见的综合应用题,将定点运算与简单的机器指令执行联系起来。
6.1 条件跳转指令背后的标志位
高级语言中的if (a > b),while (i != 0), 在机器层面最终都会编译成基于标志位的条件跳转指令。常见的条件跳转有:
JZ/JE: 结果为0(ZF=1)时跳转。JNZ/JNE: 结果非0(ZF=0)时跳转。JO: 溢出(OF=1)时跳转。JNO: 无溢出(OF=0)时跳转。JS: 结果为负(SF=1)时跳转。JNS: 结果为非负(SF=0)时跳转。- 对于有符号数比较(
JG,JGE,JL,JLE)和无符号数比较(JA,JAE,JB,JBE),则需要组合判断OF、SF、ZF或CF、ZF。
6.2 习题实战:模拟一段微型程序
看一道综合题:假设一个简单的8位CPU,有以下指令:LOAD(加载到ACC),ADD(ACC加内存数),SUB(ACC减内存数),JZ addr(ZF=1跳转到addr),HLT(停机)。内存中数据:[0x10] = 0x7F,[0x11] = 0x01,[0x12] = 0x80。程序从0x00开始:
0x00: LOAD 0x10 ; ACC = 0x7F (+127) 0x02: ADD 0x11 ; ACC = 0x7F + 0x01 = ? 0x04: JZ 0x0A ; 会跳转吗? 0x06: SUB 0x12 ; 如果没跳转,执行这里 0x08: HLT 0x0A: HLT ; 跳转目标问:程序最终停在哪条指令?ACC和标志位(ZF, OF, SF)最终状态是什么?
我们来一步步模拟:
LOAD 0x10: ACC =0x7F(+127)。ZF=0, OF=0, SF=0。ADD 0x11: ACC =0x7F+0x01=0x80(二进制10000000)。- 作为有符号数:127+1=128,超出8位补码正数范围127,发生正溢出。OF=1。
- 结果
0x80作为补码解释是-128,符号位为1,所以SF=1。 - 结果不是0,所以ZF=0。
- 此时ACC =
0x80(-128), OF=1, SF=1, ZF=0。
JZ 0x0A: 检查ZF,当前ZF=0,所以不跳转,顺序执行下一条0x06。SUB 0x12: 计算ACC - [0x12]。[0x12]=0x80(-128)。减法转为加法:ACC + (-[0x12])补。- 先求
-[0x12]补:[0x12]补=0x80, 取反加1得0x80->0x7F->0x80?等等,这里有个技巧:-128的补码表示是0x80,求其负数的补码,就是求-(-128)即+128的补码,但+128无法用8位补码表示。我们严格计算:[- (0x80)]补。对0x80(二进制10000000)取反得01111111,加1得10000000,结果还是0x80。所以-[0x12]补 = 0x80。 - 执行加法:
ACC (0x80) + 0x80 = 0x100。8位寄存器只能存低8位,所以ACC =0x00。 - 判断标志:
- 结果
0x00, ZF=1。 - 符号位0, SF=0。
- 溢出判断:
0x80(-128) 减0x80(-128) 等于0,在范围内。用双符号位:11 0000000+11 0000000=110 0000000, 丢弃最高位进位,得10 0000000?我们仔细算:0x80双符号位是11 0000000(因为-128),两个相加:110000000 + 110000000 = 1100000000,取低9位100000000,双符号位10,表示负溢出?不对,-128 - (-128) = 0,不应该溢出。问题出在-128的补码表示是唯一的,0x80,其双符号位表示应该是10 0000000吗?实际上,对于n位补码,最小负数-2^(n-1)的补码是1后面跟(n-1)个0。在双符号位系统中,为了能检测溢出,我们将其符号位扩展为两位,但规则是:用两个相同的符号位来表示。对于正数,前两位是00;对于负数,前两位是11。那么-128的8位补码10000000,扩展为双符号位应该是11 0000000吗?但11 0000000是-256?这里出现了困惑。更严谨的做法是,对于8位数,我们讨论溢出时,可以简单用单符号位结合进位的异或。0x80 - 0x80转化为0x80 + 0x80 = 0x100。符号位进位Cs=1(最高位有进位),次高位向符号位进位Cp=1(因为10000000+10000000,次高位0+0=0,无进位?等等,我们定义Cp是数值最高位(第6位)向符号位(第7位)的进位。在10000000中,数值部分是0000000,两个这样的数相加,数值部分全为0,相加也为0,没有产生任何向符号位的进位,所以Cp=0。那么OF = Cs ⊕ Cp = 1 ⊕ 0 = 1。这显示溢出?但直觉上0不应该溢出。这个矛盾揭示了用8位补码表示-128减-128是有问题的,因为-128的负数是+128,无法表示。硬件在执行SUB 0x80时,内部操作是ACC + [-0x80]补,而[-0x80]补无法正确表示,导致运算出现异常。在实际题目中,这种边界情况常被避开。我们换一种思路:题目可能期望我们忽略这个边界问题,或者数据不是-128。我们假设[0x12]=0x81(-127)来避免歧义。但原题是0x80,我们就按规则算:ACC最终为0x00, ZF=1。溢出标志OF在加减法后由硬件电路根据Cs和Cp设置,对于这个特定运算,一些模型机可能会置OF=1,因为发生了“负减负得正”的边界溢出?但0在范围内。这是一个有争议的点。在典型习题中,数据通常会避开这种最小负数。我们姑且按计算结果ACC=0x00, ZF=1, SF=0, OF不确定(可能为1)来处理。
- 结果
- 先求
- 执行完
SUB后,顺序执行0x08: HLT。所以程序最终停在0x08地址的HLT指令。
这道题综合考察了补码加减、溢出判断、标志位影响以及指令执行流程。它告诉你,仅仅会算数是不够的,还必须理解这些算数结果如何影响程序的走向。
7. 从习题到实战:定点运算在工程中的意义
做完这些习题,你可能会觉得都是些纸上谈兵的二进制游戏。但恰恰是这些“游戏”,是理解计算机底层能力的钥匙。我以两个真实的工程场景来收尾,看看定点运算知识是怎么用的。
场景一:嵌入式系统(如STM32)的浮点转定点运算。STM32F1等系列没有硬件FPU,浮点数运算靠软件模拟,极其缓慢。在需要实时性的场合(如电机控制、数字滤波),我们会把浮点算法“定点化”。例如,圆周率π=3.14159,在浮点算法里直接写3.14159f。在定点化时,我们需要确定一个缩放因子(Q格式)。比如采用Q15格式(1位符号位,15位小数位),缩放因子就是2^15=32768。那么,π的定点数就是3.14159 * 32768 ≈ 102944(取整)。之后所有的加减乘除都在这个整数102944所代表的“定点π”上进行。乘法后需要右移15位来修正小数点的位置,这就是定点乘法的移位操作。如果你不懂补码乘法、算术移位这些基础,你根本无法理解为什么要右移,以及如何处理溢出。
场景二:性能优化中的定点数运用。在图像处理、音频编解码、游戏引擎等对性能要求极高的领域,即便CPU有强大的FPU,程序员有时也会主动使用定点数来换取更高的速度和确定性的性能。因为浮点运算单元虽然快,但其功耗、 latency(延迟)以及在不同平台上的行为一致性可能不如整数运算单元。例如,早期的3D游戏图形渲染中,顶点的坐标变换大量使用了定点数运算。这时,对溢出(饱和处理)、舍入(截断或四舍五入)的控制就至关重要,这些都需要扎实的定点运算知识作为支撑。
所以,当你再面对“计算机组成原理-定点运算”的课后习题时,希望你能意识到,你正在练习的不仅仅是解题技巧,而是在打磨一把未来可能用来解决实际工程问题的螺丝刀。每一道关于溢出、移位、补码的题目,都是在为你理解更复杂的系统——从CPU流水线到数字信号处理器(DSP)——打下不可或缺的基础。把这些题目吃透,让运算器的工作流程像呼吸一样自然,是你从理论走向实践的关键一步。
