1. 实验缘起从“看得见”的比特开始如果你正在学习计算机组成原理或者对计算机内部如何工作感到好奇那么“数据表示”这个看似枯燥的课题恰恰是理解一切的基础。我们总说计算机处理的是0和1但一个具体的数字、一个英文字母、甚至一个汉字在机器内部究竟是怎样被这一串串0和1“画”出来的这个“画”的过程就是数据表示。很多教材和课程会直接给出各种编码的表格和定义比如原码、反码、补码ASCII码国标码。背下来当然可以应付考试但如果不亲手“搭建”一次你很难真正理解为什么补码能巧妙地解决加减法运算的统一问题为什么汉明校验码能在数据中插入几位就能发现甚至纠正错误。这种感觉就像只看菜谱永远学不会炒菜的火候。这就是Logisim这类数字电路仿真工具的价值所在。它让你摆脱了抽象的公式和概念提供了一个可视化的“电子实验箱”。你可以用逻辑门、导线、时钟这些最基础的元件像搭积木一样从零开始构建出能完成特定数据表示与运算功能的电路。当你在Logisim里连接好最后一个与非门给电路输入一组二进制数看到输出指示灯如你所料地亮起时那种“原来如此”的顿悟感是任何书本都无法替代的。本次实验我们就聚焦于计算机组成原理中最核心的数据表示部分。我们将不满足于知道结论而是要深入电路层面理解其运作机理。我们会从最简单的逻辑门开始逐步构建出可控的加减法器探讨数值的补码表示如何让电路设计变得优雅我们也会揭开字符和汉字编码的神秘面纱看看一个“啊”字是如何从区位码一步步变成机内码的最后我们还会挑战一下数据可靠性的守护者——校验码亲手设计一个能发现错误的汉明校验电路。整个旅程的目标是当你完成这些实验后再回头去看教科书上的那些定义它们不再是需要死记硬背的条文而是一幅幅在你脑海中可以动态运行的电路图。你会真正理解计算机的“智能”源于这些精巧、确定且可以被层层构建的逻辑。2. 实验基石Logisim环境与数字逻辑入门工欲善其事必先利其器。在开始搭建复杂的数据表示电路之前我们必须先和我们的“数字实验室”——Logisim——熟悉起来并重温一下构成所有数字电路大厦的砖瓦基本逻辑门。2.1 Logisim你的可视化数字电路沙盒Logisim是一款用Java编写的开源数字电路仿真软件它的最大特点就是直观。整个界面分为几个关键区域左侧是元件库像工具箱一样分门别类地放着导线、逻辑门、多路选择器、触发器等所有你需要的零件中间是画布也就是你的主工作区可以在这里自由放置和连接元件右侧通常是属性表和仿真控制面板。对于初学者掌握几个核心操作就能快速上手放置元件从左侧库中点击所需元件如AND门然后在画布上点击即可放置。连接导线点击工具栏上的导线工具从一个元件的引脚拖动到另一个元件的引脚。Logisim会自动帮你走线按住Ctrl键可以绘制斜线。修改属性选中任何一个元件如一个输入引脚右侧属性表会显示其可配置项比如数据位宽Data Bits、标签Label等。这里有一个极易踩坑的点Logisim中很多元件的位宽默认是1位。当你需要处理8位、16位数据时必须记得在属性中将“Data Bits”修改为对应的值如8否则电路会按1位处理导致结果完全错误。仿真测试通过工具栏上的“手形”工具编辑工具和“手指”工具仿真工具切换。在仿真模式下你可以点击输入引脚如一个输入开关来改变其输入值0或1电路会实时响应输出引脚或LED会显示当前结果。注意在搭建较大电路时强烈建议使用“子电路”功能。你可以将一部分完成特定功能的电路如一个全加器封装成一个自定义元件这样在主电路中就可以像使用标准门一样使用它极大提升了设计的模块化和可维护性图纸也会清晰很多。2.2 重温逻辑门与、或、非、异或所有复杂的处理器其最底层都源于几个基本的逻辑门。在Logisim中构建电路本质上就是在安排这些门的连接关系。我们来快速回顾一下并理解它们在数据表示中的作用与门符号为AND。只有所有输入都为1时输出才为1。在数据表示中它常用来实现“掩码”操作。例如如果你有一个8位数想只保留它的低4位可以将它和一个二进制数00001111进行按位与运算高4位就会被清零。或门符号为OR。只要有一个输入为1输出就为1。常用于将特定的位设置为1。例如将某个数与00010000进行按位或可以确保其第5位从右向左数被置1。非门符号为NOT或Inverter。它执行取反操作输入1输出0输入0输出1。这是实现补码反码1的关键也是构建多路选择器、译码器等组合逻辑的基础。异或门符号为XOR。当两个输入不同时输出为1相同时输出为0。这是一个极其重要的门电路它有一个美妙的特性一个数与另一个数异或两次会得到原数。即A XOR B XOR B A。这个特性被广泛应用于奇偶校验、简单的加密解密以及我们后面会看到的加法器设计中。在Logisim中搭建一个简单的门电路组合来验证这些特性是热身的绝佳方式。比如尝试用与、或、非门搭建一个异或门A XOR B (A AND NOT B) OR (NOT A AND B)这能让你深刻理解门电路是如何组合出更复杂功能的。3. 数值的基石从一位全加器到8位可控加减法器理解了逻辑门我们就可以向第一个实质性目标迈进构建一个能进行算术运算的电路。而这一切的起点是加法。由于补码的存在减法可以转化为加法因此一个可控的加减法器是理解计算机运算单元的核心。3.1 补码为什么是“反码加一”在深入电路之前必须彻底理解补码。我们为什么不用更直观的原码原因在于运算的复杂性。用原码做加法如果是同号数值相加符号不变如果是异号实际要做减法还得比较绝对值大小来确定结果的符号。这需要复杂的判断逻辑。补码的发明完美地解决了这个问题。对于n位二进制数其补码的定义是[X]补 2^n X (mod 2^n)。对于正数补码就是其本身对于负数补码等于其绝对值的二进制表示“按位取反得到反码再加1”。这个“反码加一”的规则在电路上有非常直观的实现。更重要的是补码使得加法和减法统一了起来。A - B可以转化为A (-B)而-B正是B的补码。这样CPU只需要一个加法器配合一个求补码的电路就能完成加减法。3.2 构建基础单元一位全加器加法器的基础是一位全加器。它有三个输入加数A、加数B、以及来自低位的进位Cin有两个输出本位和S、以及向高位的进位Cout。其真值表如下ABCinSCout0000000110010100110110010101011100111111根据真值表我们可以写出逻辑表达式S A XOR B XOR CinCout (A AND B) OR (Cin AND (A XOR B))在Logisim中你可以直接用两个异或门实现S用与门和或门实现Cout。将这部分电路封装成一个名为“FullAdder”的子电路它将成为我们构建多位加法器的标准零件。3.3 串联与并行行波进位加法器有了全加器如何计算8位数的加法最直观的方法是将8个全加器串联起来。低位的进位输出Cout连接到高一位的进位输入Cin。这种结构称为行波进位加法器。在Logisim中操作放置8个“FullAdder”子电路。将第一个全加器最低位的Cin接地表示0或接一个开关作为初始进位。将第i个全加器的Cout连接到第i1个全加器的Cin。将8位加数A和B的每一位分别连接到对应全加器的A、B输入端。每个全加器的S输出组合起来就是8位和。最高位全加器的Cout就是最终的进位。这样一个8位加法器就完成了。你可以通过开关输入两组8位二进制数观察输出LED显示的和以及进位。3.4 实现可控加减补码转换与溢出判断现在我们要让这个加法器也能做减法。关键在于通过一个控制信号Sub来决定是否对第二个操作数B求补码。求补电路回忆一下对一个数求补码是“按位取反再加1”。按位取反可以用一个非门NOT实现。加1这个操作可以巧妙地利用最低位的进位输入Cin。我们让Sub信号同时控制这两件事。电路设计在B的每一位输入和加法器的B输入端之间插入一个异或门。异或门的另一个输入端统一接Sub信号。回忆异或门的特性B XOR 0 B,B XOR 1 NOT B。因此当Sub0做加法时B的值原样通过当Sub1做减法时B的每一位都被取反得到了反码。同时将Sub信号直接连接到最低位全加器的Cin。这样当Sub1时Cin1相当于在取反的基础上“加1”完整地得到了B的补码[-B]补。溢出判断补码运算中结果超出表示范围时会发生溢出导致结果错误。对于8位补码其表示范围是-128~127。判断溢出有一个经典规则最高位的进位Cout和次高位向最高位的进位Cin如果两者不同则发生溢出。即Overflow Cout XOR Cin。你需要在电路中提取出最高位全加器的Cout和Cin用一个异或门判断溢出并用一个LED指示。最终你将得到一个完整的8位可控加减法器。控制信号Sub为0时计算AB为1时计算A-B。通过测试几组边界数据如1271, -128-1观察溢出标志是否正确亮起可以验证你的电路是否可靠。4. 字符与汉字的“身份证”编码体系深入剖析计算机不仅能处理数字还要处理文本。这就需要对字符进行编码给每个字符分配一个唯一的数字ID。英文字符少用ASCII码7位扩展后8位就够了。但汉字数量庞大就需要一套更复杂的编码体系。4.1 ASCII码西文字符的基石ASCII码用7位二进制数00H-7FH表示了128个字符包括大小写英文字母、数字、标点符号和控制字符如换行、回车。在Logisim实验中理解ASCII码的意义在于建立“字符↔二进制数”的映射概念。你可以设计一个简单的电路用拨码开关输入7位二进制数用一个“文本”显示元件在Logisim的Input/Output库中来显示对应的字符。这能直观地让你看到当你输入0100000165时屏幕显示的是‘A’。4.2 国标码与区位码汉字编码的“经纬度”汉字编码的核心是GB2312标准。它像一张巨大的94行×94列的表格收录了6763个常用汉字和682个符号。区位码可以理解为汉字在这张表格中的坐标。行号叫“区”列号叫“位”都用十进制表示01-94。例如“啊”字在第16区第01位其区位码就是1601。注意这是十进制的表示。国标码为了在计算机中传输和存储需要将区位码转换为两个字节的二进制码。转换规则是将区号和位号分别加上32即20H。因为ASCII码的前32个是控制字符为了避免冲突所以加上32使其进入可打印字符的范围。“啊”字的区号16324830H位号01323321H所以其国标码是3021H十六进制表示。在Logisim中你可以搭建一个电路来模拟这个转换过程输入用两个十进制转BCD码的电路表示区码和位码然后分别加上00100000即32输出就是国标码的两个字节。4.3 机内码在系统中安全地存在国标码还有一个问题它的两个字节30H, 21H恰好对应ASCII字符‘0’和‘!’。如果一段文本里混有“啊”字和“0!”这两个字符计算机就无法区分。为了解决二义性引入了机内码。规则非常简单将国标码的每个字节的最高位第8位从0置为1。因为ASCII码是7位编码最高位恒为0所以最高位为1的字节一定是汉字编码的一部分。所以“啊”字的机内码计算过程是区位码16 01(十进制)国标码(163248, 013233)-30H 21H(十六进制) -00110000 00100001(二进制)机内码将两个字节的最高位置1 -10110000 10100001-B0H A1H在Logisim里你可以在国标码转换电路后面给两个输出字节分别连接一个或门与10000000进行按位或运算就能得到机内码。这个“最高位置1”的操作是区分中英文字符的关键也是早期中文系统处理文本的基础逻辑。5. 数据的“守护者”校验码原理与汉明码设计数据在存储或传输过程中可能出错比如从内存读出的某一位从0变成了1。校验码就是为了检测甚至纠正这类错误而生的。奇偶校验最简单但只能发现奇数个错误且不能定位。汉明码则更强大。5.1 奇偶校验最简单的错误侦测原理是在数据位后面添加一个校验位使得整个码字数据位校验位中“1”的个数为偶数偶校验或奇数奇校验。接收方重新计算“1”的个数如果与约定不符就说明出错了。在Logisim中实现一个8位数据的偶校验生成器很简单将8个数据位输入一个8输入的异或门。异或门的特性是当输入中“1”的个数为奇数时输出1偶数时输出0。因此对于偶校验校验位P就等于这8位的异或结果。这样数据 P中“1”的总个数就一定是偶数。5.2 汉明码不仅能发现还能定位错误汉明码通过在数据位中插入多个校验位构建一个“错误定位系统”。对于能纠正一位错误的汉明码其编码规则需要满足2^r m r 1其中m是数据位长度r是校验位位数。例如对4位数据m4需要3位校验位r3因为2^38 4318。设计步骤以4位数据D3 D2 D1 D0为例确定校验位位置校验位P1, P2, P4...插入在位置编号为2的幂次方的地方1, 2, 4, 8...。最终7位汉明码的位序是P1, P2, D3, P4, D2, D1, D0 (位置1-7)。确定校验关系每个校验位负责校验某些位置的数据。规则是位置编号的二进制表示中第i位为1的那些位置就由Pi校验。P1 (位置1 二进制001): 校验所有位置编号二进制表示中最低位为1的位即位置1,3,5,7 (P1, D3, D2, D0)。P2 (位置2 二进制010): 校验所有位置编号二进制表示中次低位为1的位即位置2,3,6,7 (P2, D3, D1, D0)。P4 (位置4 二进制100): 校验所有位置编号二进制表示中最高位为1的位即位置4,5,6,7 (P4, D2, D1, D0)。计算校验位采用偶校验。即令每个校验位与其所校验的所有位包括数据位和其他校验位的异或结果为0。P1 XOR D3 XOR D2 XOR D0 0-P1 D3 XOR D2 XOR D0P2 XOR D3 XOR D1 XOR D0 0-P2 D3 XOR D1 XOR D0P4 XOR D2 XOR D1 XOR D0 0-P4 D2 XOR D1 XOR D0错误检测与定位接收方收到7位码字后重新计算三个校验方程的值得到三个校验因子S1, S2, S4如果方程成立则为0否则为1。将S4S2S1组成一个二进制数其值就是出错的位置编号。如果为0则表示无错。5.3 在Logisim中搭建汉明码编解码电路这是一个综合性的项目能极大锻炼你的逻辑设计能力。编码电路输入4个数据位D3-D0用异或门网络根据上述公式计算出P1, P2, P4然后将它们与数据位按正确顺序合并输出7位汉明码。解码与纠错电路输入7位可能出错的汉明码。根据接收到的数据位和校验位重新计算S1, S2, S4。S1 P1 XOR D3 XOR D2 XOR D0S2 P2 XOR D3 XOR D1 XOR D0S4 P4 XOR D2 XOR D1 XOR D0用一个3-8译码器或组合逻辑将S4S2S1这个3位二进制数译码。译码器的8个输出线分别对应位置1到7和第0条线表示无错。在数据路径上使用7个2选1多路选择器。每个选择器对应汉明码的一位。选择器的两个输入一个是该位的原始值一个是该位取反后的值。选择信号就是译码器输出的对应位置线。如果S4S2S10译码器“无错”线有效所有选择器都选择原始值通过。如果S4S2S13二进制011表示位置3出错即D3。那么译码器的“位置3”输出线有效连接到第3个位D3对应的多路选择器上使其选择取反后的值从而纠正该位错误。其他位置的选择器仍选原始值。最终输出纠正后的4位原始数据。当你搭建完这个电路并故意翻转某一位输入进行测试看到电路能自动输出正确的原始数据时你会对校验码的威力有前所未有的认识。这不仅仅是理论而是可以亲手实现的数据可靠性保障机制。6. 实验进阶从部件到系统思维的跨越完成以上几个核心实验你已经亲手“铸造”了计算机中用于表示和处理数据的关键硬件部件。但这还不是终点而是通向更宏大理解的起点。如何将这些部件有机组合并融入系统思维是实验的进阶课题。6.1 运算器的雏形ALU核心功能集成我们构建了可控加减法器这其实就是算术逻辑单元最核心的算术功能。一个简单的8位ALU可以在此基础上扩展逻辑运算与、或、非、异或等。这些操作相对简单可以通过多路选择器与算术运算共享输入输出通道。功能选择引入一个2-4位的功能选择信号如F[1:0]通过一个多路选择器在不同的功能输出加法结果、减法结果、与结果、或结果...中进行选择作为ALU的最终输出。标志位集成除了溢出标志计算机中还有几个重要的状态标志位它们存储在程序状态字寄存器中。零标志当运算结果的所有位都为0时该标志置1。可以用一个多输入的或非门实现。符号标志直接取运算结果的最高位对于有符号数这就是符号位。进位标志对于加法运算就是最高位的进位Cout对于减法需要特殊处理通常与加法统一考虑。 在Logisim中你可以将这些标志位计算电路集成到你的加减法器周围并输出到单独的引脚模拟一个简易ALU的状态输出。6.2 存储与检索理解内存如何工作数据需要被存储和读取。Logisim的“Memory”库提供了RAM和ROM组件你可以用它们来模拟内存。地址与数据理解地址总线选择哪个存储单元和数据总线写入或读出的内容的区别。尝试设计一个电路通过一组开关输入地址另一组开关输入要写入的数据一个“写入使能”信号控制写入操作再通过另一组LED显示从该地址读出的数据。字符点阵存储这是一个经典的综合实验。汉字在屏幕上显示为16x16的点阵每个点用1位表示亮/灭。一个汉字就需要256位即32字节。你可以在Logisim的ROM中手动或通过导入文件的方式存入几个汉字的点阵数据。然后设计一个电路输入汉字的机内码作为地址的高位以及行号、列号作为地址的低位从ROM中读出对应点的值控制一个LED的亮灭。这能让你深刻理解从字符编码到最终屏幕显示的完整链条。6.3 实验调试心法信号追踪与模块化验证在Logisim中搭建复杂电路调试是不可避免的。分享几个我踩过坑后总结的心法分模块测试逐级集成永远不要一次性搭建完整个大电路再测试。先确保每一个子电路如全加器、校验位生成器功能完全正确。利用Logisim的“手形”工具给子电路输入各种边界情况验证输出。善用探针和日志Logisim的“探针”组件可以实时显示线上信号的值。在关键节点如进位链、多路选择器的输出、译码器的输出放置探针能让你清晰地看到数据流快速定位问题所在。位宽一致性检查这是最常见的错误来源。确保连接的所有导线其位宽属性是一致的。如果一个8位输出连接到一个1位输入Logisim可能会自动截断而不报错导致结果诡异。养成选中导线查看其位宽属性的习惯。时钟与时序的模拟对于包含触发器的时序电路如寄存器要理解时钟边沿触发的概念。在Logisim仿真中可以使用“时钟”组件并手动点击或者使用“自动滴答”功能来模拟时钟信号观察数据在时钟控制下的锁存与传递。计算机组成原理的实验其魅力不在于复现一个已知的结果而在于亲身体验从抽象定义到物理实现之间那条曲折但充满乐趣的道路。当你用最基础的门电路一步步构建出能运算、能编码、能校验的完整功能时你对“计算机如何工作”的理解就从书本上的平面图变成了脑海中立体的、可运行的模型。这份通过动手获得的直观感受是任何理论讲解都无法给予的宝贵财富。