ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

计算机组成原理入门:存储程序与五大部件,理解计算机的核心

计算机组成原理入门:存储程序与五大部件,理解计算机的核心 1. 计算机到底是什么从“存储程序”这个核心说起1.1 为什么“存储程序”是计算机的灵魂很多人第一次接触“计算机组成原理”这门课翻到第一章看到“计算机概念”几个字觉得啰嗦又抽象索性直接跳过去看后面的进制转换、定点数浮点数。但我带过的学生里凡是后来在指令周期、Cache映射、总线仲裁这些章节反复卡壳的回头补的恰恰都是这一章欠下的概念债。今天我想把“计算机概念”这个看起来最基础、实际上最容易被低估的话题掰开了讲清楚。计算机按教材上的定义是一种“能对信息进行自动化处理的电子装置”。这几个字里面有三个关键词信息、自动化、处理。普通人看电脑看到的是屏幕、键盘、主机箱学计算机的人看电脑应该看到的是“输入设备——存储器——运算器——控制器——输出设备”这条数据通路。但真正让计算机成为计算机的不是这些部件的名字而是一个极其关键的设计思想——存储程序。所谓“存储程序”指的是把完成计算任务的指令和需要计算的数据一起以二进制的形式存放在存储器中计算机运行时自动从存储器中一条一条取出指令并执行。这个思想是冯·诺依曼在1945年提出的它用“指令和数据统一编码、统一存储”的方式解决了早期计算机靠插拔线路来切换计算任务的问题。通俗一点说早期那种靠插线改变任务的计算装置相当于一个厨师每做一道新菜就要重新砌一次灶台而存储程序概念的计算机相当于厨房里储备了一柜子的菜谱厨师只需按顺序翻菜谱就能一道接一道地把菜做出来不用动灶台。这一点是理解后续所有内容的钥匙。因为计算机能“自动”处理信息靠的不是某种玄学智能而是“程序被存放在存储器中控制器按地址顺序取指、译码、执行”这一套机械的循环。后面学的指令系统、控制器设计、中断机制乃至流水线技术全部建立在“指令从存储中来结果回存储中去”这个基本循环上。我见过太多同学学到控制器一章时满脑子都是“肉搏式”的微操作流程却搞不清为什么要按那样取指令、为什么程序计数器要自动加一根子就在于没吃透“存储程序”这四个字的重量。1.2 五大部件的分工与协作逻辑在存储程序思想的框架下计算机硬件系统由五大部件组成运算器、控制器、存储器、输入设备、输出设备。这五个部件不是五个孤立的盒子它们之间靠两条通道协作一条传数据一条传控制信号。存储器负责“存”既存指令也存数据。冯·诺依曼结构里没有把程序存储器和数据存储器分开这就是后来所谓“冯·诺依曼瓶颈”的由来指令和数据在同一块主存里共享空间。运算器负责“算”算术运算加减乘除和逻辑运算与、或、非、异或。现代CPU里ALU算术逻辑单元就是它的核心。控制器负责“指挥”根据指令的要求生成控制信号指挥其他部件协同工作。它相当于乐队指挥自己不演奏乐器但整场演出什么时候谁发声、发多大声都由它说了算。输入设备和输出设备负责“交流”键盘、鼠标、扫描仪是把外部信息变成机器能识别的二进制信号显示器、打印机是把机器处理结果变成人能理解的形式。我在课上爱打一个比方把这五个部件想象成一家餐厅。菜单程序和食材数据都存在库房存储器里掌勺的大厨运算器负责处理食材餐厅经理控制器按客人点单的先后顺序喊库房出货、喊大厨动手、喊服务员上菜服务员和前台输入输出设备负责接单和递菜。整个餐厅能正常运转关键在于经理手里的单子程序是提前写好的他不需要临时动脑想每一步该怎么办。这里有个特别容易被忽视的细节控制器和运算器在现代机器里被统称为中央处理器CPU但在概念层面它们是两个分工完全不同的部件。很多初学者只记得CPU是“电脑的大脑”却没有意识到这个“大脑”里既有“思考”的部分运算器也有“发号施令”的部分控制器理解GPU、DSP这些专用芯片的设计逻辑时就更吃力。后续我们讲指令周期时取指阶段的操作完全由控制器主导执行阶段才轮到运算器上阵如果这一章的部件分工没建立起来到最后一片混沌。1.3 硬件与软件到底谁决定谁讨论计算机概念绕不开另一个问题硬件和软件的关系。很多入门教材会说“硬件是躯体软件是灵魂”。这个说法形象但不够准确。更准确的说法是硬件提供了执行能力软件规定了执行顺序软件通过指令系统这个接口把人的意图翻译成硬件能执行的操作序列。指令系统Instruction Set ArchitectureISA是硬件和软件之间的契约。硬件设计者承诺“只要给我这些机器指令我就能按语义执行。”软件设计者承诺“只要硬件支持这些指令我就能在上面构建操作系统和应用程序。”我们常说“软件兼容”或“指令集兼容”指的就是不同CPU如果实现了同一个ISA那么同一个程序就能在上面跑比如x86架构的兼容性。这个接口的概念为什么重要因为很多人学到后面会产生一个困惑“高级语言写的代码怎么就跑起来了”流程是这样的源代码C/C/Java等经过编译器编译或解释器解释变成汇编语言或机器指令机器指令按照ISA的规定编码为二进制当程序被装载到内存并交给CPU执行时CPU的控制器按照ISA的语义一条一条地解释这些二进制位。整个链路里操作系统负责管理资源编译器负责翻译CPU负责忠实执行ISA三层协作缺一不可。顺着这个思路延伸一下为什么说“学软件的人也要学计算机组成原理”因为你写的高级语言里每一条语句、每一次函数调用、每一回数组访问最终都要落到机器指令上。不知道数组下标访问在汇编层面是怎么计算地址的你就很难理解为什么二维数组按行存储对Cache更友好不知道函数调用约定Calling Convention你就很难理解栈溢出为什么那么难防。软件的性能天花板有一半是硬件决定的。这就像开车你当然可以只管踩油门但如果你知道引擎的工作特性和变速箱的换挡逻辑同样的路程你能开得更快、更省油。2. 从不同视角看计算机为什么同一台机器有无数种理解方式2.1 机器级视角程序员眼里的计算机在程序员眼里计算机由三样东西抽象出来CPU能执行的指令、CPU能访问的存储单元、以及输入输出接口。程序员不关心CPU内部的ALU是什么电路结构不关心存储芯片用的是DRAM还是SRAM也不关心某个控制信号是几纳秒后到达的。对程序员而言计算机就是“一台能按指令工作的抽象机器”。这个抽象层次被称为机器级Machine Level。汇编程序员站在这个层次上工作时能看到的就是寄存器、内存地址、指令、栈、中断向量等。比如一个简单的x86汇编程序程序员要考虑把数据放到哪个寄存器通过什么寻址方式访问内存函数调用时参数压栈的顺序是怎样的。这些细节在高级语言里完全被隐藏了但它们恰恰决定了程序的真实执行效率。很多考研的同学做408真题时遇到“某指令系统的寻址方式有立即数寻址、直接寻址、间接寻址、寄存器寻址、变址寻址”这类题目感觉就是在背表格。但如果把自己代入到“我是汇编程序员我需要用这些寻址方式写一个数组求和程序”的场景里理解起来会顺很多。为什么需要变址寻址因为你不可能把一个数组的每个元素都写成一个直接寻址指令为什么需要间接寻址因为你需要在程序运行过程中动态改变要访问的地址典型的场景是指针变量。2.2 微架构视角硬件设计者眼里的计算机硬件设计者的视角和程序员完全不同。设计者思考的问题是给定一个ISA我应该怎么用逻辑门、寄存器、数据通路和控制单元把它实现出来并且在功耗、延迟、面积之间做取舍。这就是所谓的微架构Microarchitecture。用一个经典例子说明两者区别ISA规定了一条乘法指令MUL执行的是两个数相乘。程序员不需要关心这个MUL指令实际是怎么完成的但微架构设计者必须决定是用一个硬件乘法器一个时钟周期直接出结果快但电路面积大、功耗高还是用加法器做移位相加多个时钟周期出结果慢但电路简单在ARM Cortex-M系列这样的低成本处理器上设计者有时就会选择后者因为面积和功耗的约束优先于计算速度。ISA是一样的但微架构变了处理器的性能、功耗和成本也跟着变了。这个“接口与实现分离”的思想是计算机组成原理整门课里最重要的一对概念。ISA是标准微架构是实现两者之间不是一一对应的。同一个ISA可以有完全不同的微架构实现比如Intel和AMD各自实现x86但内部微架构差异极大。理解不了这对概念后面的流水线、乱序执行、分支预测等内容就像空中楼阁。2.3 层次结构视角为什么计算机要分层还有一种更宏观的视角把计算机看成一个多层次的系统从最底层的物理器件到最高层的应用软件每一层都对上层屏蔽了实现细节、提供接口。自下而上大致是这样一层一层堆叠的第0层数字逻辑层。门电路、触发器、组合逻辑、时序逻辑。比如与门、或门、非门、D触发器、计数器等。这一层负责实现最基本的“0/1”逻辑。第1层微体系结构层。寄存器、ALU、数据通路、控制单元。这一层实现了指令的解释执行。汇编指令在这里被翻译成微操作序列。第2层指令系统层ISA层。程序员通过机器指令或汇编语言编程。这一层是硬件和软件的接口界面。第3层操作系统层。系统调用、进程管理、内存管理、文件系统。操作系统指令和汇编指令混用程序员通常经由操作系统API来访问硬件。第4层汇编语言层。把符号化的助记符翻译成机器指令。第5层高级语言层。C、C、Java、Python等由编译器翻译成汇编语言或中间代码。第6层应用层。数据库、Web服务、办公软件、游戏。我为什么要花这么大力气讲分层因为后面整个系列的内容都在这张“纵切图”上展开。讲存储系统时你看到寄存器、Cache、主存、磁盘在这条纵轴上从高到低排列速度递减、容量递增、价格递减讲输入输出系统时你看到操作系统层和设备控制器层怎么分工配合中断和DMA就是层与层之间的通信协议。如果脑子里没有这张分层图每一章都会像一座孤岛。反过来有了分层思维你会觉得计算机不只是一门课而是六七个层次环环相扣的系统工程。这个视角还能直接回答一个初学者的灵魂拷问“我已经学了Python能用它写出一个会弹窗的程序为什么还要学计算机组成原理”答案是Python解释器本身就是一个运行在你机器上的程序它调用操作系统提供的接口操作系统通过ISA去控制CPU和内存CPU靠微架构逐条解释指令微架构靠逻辑门实现。你每敲一行代码整条纵轴都在为你工作。不了解这条链路上每一层是什么、为什么那样设计你在工程中遇到性能问题、并发问题、资源占用问题时就只能靠猜。3. 计算机概念到底有多厉害它能解释什么又能预判什么3.1 从“存储程序”到“指令周期”一条主线贯穿全书计算机组成原理教材翻到中后段有一章专门讲CPU的指令周期取指周期、间址周期、执行周期、中断周期。有些同学觉得这是新知识其实这不过是第一章“存储程序”概念的展开版。一个指令周期的基本流程是程序计数器PC给出指令地址控制器把该地址送给存储器存储器返回一条指令控制器解析这条指令的操作码和操作数地址按需要再访存取操作数执行操作然后程序计数器按规则自增或跳转进入下一条指令。最后中断周期还要检查是否有中断请求有则保存断点、转去中断服务程序。你看这个流程里的每一步都在实践“指令和程序存放在存储器中控制器按序取指令并执行”这句话。所谓“周期”是说CPU的工作本质上是不断重复“取指→译码→执行”的机械循环。即使是现代处理器引入了流水线——同时取出多条指令、让多条指令在不同阶段重叠执行——它依然没有脱离这个基本循环只是把循环的不同阶段拉开来并行处理了。这也是为什么第一章强调“存储程序”这4个字的时候我说它是整本书的“源”。换个更生活化的角度你可以把CPU的工作理解为工厂流水线上的质检员。质检员控制器拿到一张工单指令工单上写着要检查什么、用什么标准查质检员就按工单动手执行查完再拿下一张工单。流水线技术就是给这条线配了多个质检员各负责不同工位第一张工单在贴标签第二张已经在测电压第三张刚拿到手。但不管怎么并行工单总得一张一张地从“工单队列”里取出来这个队列就是存储程序中的“程序”。3.2 概念的指挥棒作用从机器字长到Cache设计再举一个例子机器字长。教科书里定义说机器字长是指CPU一次能处理的二进制位数通常等于运算器ALU的位宽和寄存器位宽。这个概念看似只是“一个多少位的CPU”的简单回答但它的指挥棒作用贯穿了整个硬件设计。数据通路宽度必须与机器字长匹配否则一次运算要拆成多次传输效率塌方。指令字长往往也是机器字长的整数倍。x86指令长度变化比较大从1字节到15字节都有这让取指阶段变得复杂而RISC架构如RISC-V固定指令长度为32位取指逻辑简单得多。内存地址空间直接受寻址宽度限制。32位处理器最多访问4GB——这个数值不是拍脑袋来的2的32次方约等于4.29×10的9次方也就是4294967296字节除以1024的平方才是4GB。这也是当年32位系统“4GB内存墙”的根源。同样的逻辑也能用到Cache设计上。Cache的容量、块大小、映射方式、替换算法每一项选择背后都有存储器访问局部性原理在起作用程序倾向于在短时间内反复访问同一块地址区域时间局部性并且访问过的地址附近也容易被访问空间局部性。为什么C语言里“按行遍历二维数组”比“按列遍历”快因为数组在内存中是按行优先连续存放的按行遍历时Cache预取进来的整块数据能连续命中按列遍历则跳着访问局部性被破坏了Cache命中率直降。我每次给同学讲这个例子都会看到很多人恍然大悟“原来学校里教的遍历顺序不是教条是硬件原理的必然结果。”这就是计算机概念的价值它不只定义“是什么”更解释“为什么是”还能帮你预测“怎么做更快”。3.3 概念能预判什么从瓶颈到扩展方向理解了计算机的基本构成和层次结构你还能预判出它性能上限在哪里。冯·诺依曼结构有一个著名的瓶颈问题CPU和存储器之间只有一条数据总线指令和数据要在这同一条总线上轮流通传这就像只有一个窗口的银行所有存取款的客户都在这一条队里排着CPU再快也得等内存给数据。这就是后来各种优化方案的出发点在CPU和主存之间插入高速缓存Cache就是为了缓解CPU和主存的速率差异。采用Harvard结构指令存储器和数据存储器物理分离各自独立编址、独立总线就是为了让取指和访数能并行进行。引入多级存储体系寄存器→Cache→主存→磁盘就是为了平衡速度、容量、价格三者。如果你看到一款新处理器脑子里只有“主频多高、核数多少”这两个参数说明概念基础还没到位。真正的行家会问它的一级缓存多大是数据缓存和指令缓存分离吗集成了什么内存控制器支持DDR几它的乱序执行窗口多大分支预测器用什么算法这些背后全是第一章那些概念在延伸。概念不是死知识是你判断一个系统“好不好、为什么好、哪里会成瓶颈”的思维框架。4. 计算机概念学习中的常见误区与我的排雷经验4.1 误区一把“计算机组成原理”当成“计算机体系结构”这是我在知乎私信和线下答疑里被问到最多的问题。甚至有同学买了两本书一本叫“计算机组成原理”一本叫“计算机体系结构”翻了半天也没搞清区别。其实两者的差异是清楚的计算机组成Computer Organization关注的是硬件部件的实现细节和连接方式比如ALU用什么逻辑电路实现、控制器是硬布线还是微程序、Cache的块大小和映射方式怎么定计算机体系结构Computer Architecture关注的是软件可见的属性比如指令集包含哪些指令、寄存器有多少个、寻址方式有哪些、数据类型怎么编码。一句话体系结构是“契约内容”组成是实现方式。同一个体系结构比如x86-64可以有不同的组成实现Intel和AMD的微架构天差地别。这个区分对考研特别重要。408专业课里计算机组成原理部分考的是组成与体系结构的综合内容——指令系统、数据表示、存储层次、CPU设计、总线、I/O而“计算机体系结构”作为一门研究生或高年级本科生课程更偏重并行性挖掘、性能评测、功耗管理。如果你准备考研买对书很重要唐朔飞的《计算机组成原理》、王道考研系列书的覆盖范围和体系结构课程的侧重完全不同。把概念搞混复习方向就跑偏了。4.2 误区二只看概念不画图把“层次结构”背成名词解释不少人在“计算机概念”这一章翻得飞快觉得“就是几个名词背下来就行”。但到后面学到Cache映射、虚拟存储器、总线仲裁时才发现自己脑子里没有“结构图”支撑全靠文字描述理解寸步难行。我的建议是第一次学这一章时必须能凭记忆手绘出两幅图。第一幅是五大部件连接框图标清CPU、主存、I/O接口之间通过系统总线相连第二幅是层次结构图把数字逻辑层一路画到应用层。不要小看这两幅手绘——它们是你后续所有知识点的“锚点”。学到中断时在I/O接口和CPU之间标出中断请求线学到DMA时在I/O接口和主存之间画出直通通道学到Cache时在CPU和主存之间插一块缓存。每学一章就在第一幅图上加几个标注。这个方法是笨的但亲测极其有效。我在辅导学生时常用一个“从顶到底讲一次开机过程”的练习想象你按下电源键从电源供电、复位信号、CPU从复位向量取第一条指令BIOS/UEFI程序到引导程序加载操作系统内核再到操作系统初始化内存管理、建立中断向量表最后启动Shell或桌面。这一条故事线走一遍几乎把整本组成原理的主要章节都串起来了。能把这个过程讲清楚的人概念绝对不会差。4.3 误区三忽略“二进制是计算机的语言”这个前提很多同学觉得“二进制”是理所当然不用专门理解。但计算机概念里有一条暗线为什么计算机会采用二进制因为硬件上最容易实现只有两种状态的物理器件——比如晶体管的截止与导通、磁层的NS极、光盘上的凹坑与平面。十进制需要十个稳定状态电路实现难度指数级上升抗干扰能力反而下降。这也是为什么我们学冯·诺依曼结构时强调“指令和数据都只能用二进制表示”。这条暗线的后续影响太大了二进制的进位规则决定了机器数的表示方式——原码、补码、反码、移码补码的设计就是为了让加减法能用同一套加法器完成IEEE 754浮点数标准规定了单精度和双精度的符号位、阶码、尾数的编码格式。如果你在这一章没有建立起“一切数据最终都是一串0和1”的信念后面做进制转换、补码加减法题目、浮点数表示题时很容易犯浑。另外还有一个常见错误就是搞不清“位、字节、字”这几个概念跨层使用时到底什么意思。位bit是一个二进制位字节Byte是8个bit是存储容量的基本单位字Word则是CPU一次能处理的位数即机器字长比如64位处理器的字长是64bit即8Byte。很多教材还会区分“存储字长”和“机器字长”——存储字长是存储器一次并行读写的位数可能和机器字长不同。这种细微差别考研选择题里经常拿出来坑人。4.4 四类人群的学习路径建议在校本科生或零基础者先读唐朔飞的《计算机组成原理》前3章概念、数据表示、存储与运算基础配合在Logisim里搭一个最简单的运算器实验重点理解“从逻辑门到ALU”的实现过程再回头看概念会非常有感觉。考研党408方向王道考研的组成原理视频或辅导书是性价比最高的入门组合把书里的基础题做完后再刷历年真题。复习时注意第一章虽然是“概念”但每年都会出“数据表示”后续章节的题概念题本身不多重量级在于给后面章节打底。有编程经验、想提升内功的程序员不必通读教材建议看《深入理解计算机系统》CS:APP前几章它用C语言程序的视角反向拆解硬件行为把存储程序、寻址方式、栈帧、局部性讲得非常透。想自学的硬件爱好者建议边看书边用手头的真实平台验证比如在树莓派上写一段汇编在QEMU里观察指令执行或者用FPGA搭一个简易RISC-V核心。动手造的计算机哪怕只是一个能算加法的玩具八位CPU你对“计算机概念”四个字的理解深度也会远超只读书的人。4.5 考研期末高频概念题速查从历年408、各校期末试题来看“计算机概念”这个主题的命题点相对集中。我根据题目频率和坑点整理成一个速查表方便你考前自查命题点核心问法常见坑位存储程序思想冯·诺依曼结构的特点答不全“指令以二进制形式存储、程序顺序执行、五大部件组成”或者把“存储程序”误写成“程序存储”计算机五大部件哪些部件受控制器控制输入设备不算控制器直接控制对象需要通过I/O接口交互机器字长32位CPU的字长与地址总线宽度的关系误以为地址总线宽度等于机器字长实际二者可以不同比如某些32位CPU支持36位物理地址存储器层次寄存器、Cache、主存、磁盘的速度排序误把磁盘当内存的一部分外部存储器和主存是两码事ISA与微架构同一ISA不同微架构误以为指令集相同则CPU内部一定相同软硬件接口关系编译、汇编、链接各阶段混淆汇编器与编译器、链接器的作用二进制表示为什么计算机用二进制需要答出“物理实现简单、抗干扰强、逻辑代数成熟”而不是只答“机器只能识别0和1”这张表可以玩一个“盲考”训练遮住右侧的“常见坑位”列只看命题点自己在心里把答案完整过一遍再对照右侧查漏补缺。所有基础概念都能对答如流了再进入下一章“数据表示与运算”。5. 我的实操建议怎么把“计算机概念”学成自带导航的地图5.1 动手验证一个“最小计算机”说一千道一万概念这东西光靠眼睛看是记不牢的。我建议每个学这门课的人哪怕你是纯软件出生都亲手“打造”一台最简计算机哪怕是在模拟器里。Logisim是一个很好的起点它是一个免费的图形化数字逻辑模拟器可以用来画门电路、搭建ALU、寄存器和存储器甚至能手动连出一条完整的CPU数据通路。我的一个学生用Logisim从零搭了一台4位CPU虽然只支持一条“加一”指令但他在写实验报告时对我说“以前我不理解程序计数器为什么要自增自己搭完才明白CPU真的是个‘哑巴’你给它什么指令它就走什么路指令全存在ROM里。”如果不想用图形化工具也可以用软件模拟。ThumbSim这类ARM指令集模拟器可以让你在电脑上运行ARM汇编指令单步查看寄存器变化体会指令在架构层面的行为。更硬核的可以装QEMU用调试模式观察Linux内核加载、执行第一条指令的过程——这是理解“复位向量”、“启动流程”这些概念的终极验证。5.2 建立“三段式问答”自检法每章学完自测我的某位学长当年备考时给过我一个“三段式问答”自检法我沿用了很多年也推荐给了大量学生。每学完一个章节问自己三组问题“它是什么它为什么存在如果没有它会怎样”拿第一章的内容做一次示范是什么计算机由五大部件组成指令和数据统统一进制存储在存储器中CPU按序取指令、译码、执行形成一个自动化的处理循环。为什么存在为了让计算装置能快速切换任务不用靠人工插线为了让同一个硬件能执行无穷多种不同的逻辑只需换程序不用换电路。存储程序是硬件通用性的基石。如果没有它会怎样计算机就退化成了“专用计算器”——一台机器只能算一种题。那今天我们这台能写文档、能跑数据库、能打游戏、能跑深度学习模型的设备就不存在了你能想到的所有“软件生态”都不会诞生。这个方法的意义在于它逼着你不满足于“认识名词”而去思考“设计动机”。我在帮人改简历、做技术评估时也发现说得出“为什么这么设计”的人和只会背定义的人工程能力差距非常明显。5.3 系列内容的路线图预告“计算机组成原理系列”这篇是开篇之后我会沿着“概念 → 数据表示 → 运算器 → 存储器 → 指令系统 → CPU设计 → 总线与I/O”的路线一篇一篇地展开。第一篇之所以只讲概念是因为概念是地图地图不画好后面所有章节都会像在陌生城市没有导航只能各看各的风景。下一篇会紧接“数据表示与运算”讲原码、补码、反码、移码怎么来为什么补码可以统一加减法以及IEEE 754浮点数那个“阶码偏置”是怎么算出来的还有一组考研必考的“定点数加减运算溢出判断”实例计算。到时候你会发现第一篇建立的分层视角和“存储程序”心智模型在后面几乎处处都用得上。最后分享一个我自己的学习习惯每次学完一章别急着翻下一章先在空白纸上凭记忆画出这一章的知识结构图然后用三句话向一个不懂计算机的朋友解释这章核心。能说明白才是真学会。第一张图画不完整没关系你是从这一章开始走上“能画全图”的路的。
返回列表