
讲真DMA这块内容是计算机408计算机组成原理里最容易被“误会”的考点之一。很多同学学到I/O设备与主机进行信息传送的控制方式时背了程序查询、中断、DMA、通道这四种方式的定义觉得DMA不就是“不用CPU参与”、让设备直接和内存传数据嘛。可真到做题的时候周期挪用到底是怎么发生的、DMAC内部三个寄存器的初值谁来设、DMA和中断的优先级谁高一考一个准地出错。这篇内容就是围绕DMA方式来一次彻底拆解把原理、硬件组成、传送流程、高频考点和易错点全部过一遍。无论你是正在刷408真题的考研党还是学《计算机组成原理》期末复习到I/O这一章又或者只是想把中断和DMA的关系彻底理清楚这篇都适用。1. 从I/O控制方式演进看DMA为何登场1.1 程序查询和中断方式到底“卡”在哪先说程序查询方式。它最大的问题就是CPU要“死等”CPU不断读取设备状态寄存器设备没好就原地循环等待好了才传送一个数据。这种方式控制简单、硬件成本低但CPU把大量时间浪费在查询上。打个比方就像你让一个员工去干一件事然后你每隔一分钟就去问他“干完了吗”这段时间你什么都干不了。在早期低速设备为主的时代这种傻等还能忍但设备一多、速度一高CPU就基本被查询占满了。中断方式比查询好很多设备准备好之后主动向CPU发中断请求CPU先把手头的事处理好再响应不用傻等了。但它有一个致命问题每传送一个数据CPU都要经历“保存现场—识别中断源—跳转到中断服务程序—传送数据—恢复现场—返回断点”这一整套流程。如果设备速度很快比如磁盘每几微秒就准备好一个数据CPU就一直在被中断打断进程切换和现场恢复的开销甚至比传送数据本身还大。这就好比老板刚想集中精力写个方案员工每隔两分钟就来敲门请示一次方案根本写不下去。DMA方式正是为了解决这个矛盾出现的。它的核心思想是数据在设备和主存之间的搬运不再一件件经过CPU中转而是由专门的硬件——DMA控制器直接接管。CPU只在DMA传输开始前做一次初始化传输结束后处理一次中断中间整个过程CPU可以去做别的。换句话说前面两种方式是“CPU亲自搬家”DMA方式是“CPU叫了一个搬家公司自己继续写方案”。1.2 DMA方式的核心思想如何理解才不跑偏很多教材会把DMA定义成“在外设与主存之间直接传送数据的方式”这个表述很容易让人误解以为DMA传输完全不需要CPU。实际上DMA并不是要取代CPU而是把“搬运数据”这个重复性劳动从CPU手里剥离出来让CPU专注于计算和控制。用408里的话说DMA方式下数据传送的“控制权”交给了DMA控制器但整个DMA传输的“发起权”和“结束确认权”仍然在CPU手上。理解DMA这个定位特别关键。因为408真题很喜欢在选项里挖这种坑说“DMA方式传输数据时CPU完全不需要参与”、“DMA方式可以代替中断方式处理所有I/O”这些说法都是错的。DMA只负责数据搬运传送完一批数据之后它还需要通过中断方式通知CPU“活干完了”。DMA和中断从来不是替代关系而是配合关系。这一点想通了后面看DMA的三个阶段就顺了。2. DMA控制器的硬件构成搬运工手里的三张王牌2.1 三个核心寄存器的分工与计算DMA控制器简称DMAC是整个DMA传输的执行机构。它内部至少有三个核心寄存器主存地址寄存器MAR、数据计数器DC、控制寄存器CR。这三个家伙的分工可以理解为MAR记住“东西搬到哪”DC记住“还有多少没搬”CR记住“这次搬运有哪些规则”。先看MAR。它的作用有二一是存放DMA传输过程中主存一侧的地址二是在传输完成后保留数据块的末地址。初始时CPU要往MAR里写入本次传输数据块在主存中的首地址。它的位数由主存地址空间决定比如主存按字节编址、地址总线20位MAR就得有20位。408考试里偶尔会让算MAR的位数思路就是看主存地址范围。再看DC。它存的是本次DMA要传送的数据个数初始值由CPU写入每传送一个数据单位就自动减1减到0说明这批数据传完了。DC的位数决定了单次DMA能传送的最大数据块长度。举个具体例子假设DC是16位每次传送一个字节那单次DMA最多传2的16次方等于65536个字节也就是64KB。真题里如果给一个磁盘扇区是512字节问你DC需要多少位至少需要9位因为2的9次方等于512。但如果考虑到可能连续传送多个扇区一般要按最大可能传送长度来算这一点很容易被忽略。CR则用来控制DMA传输的方向——是设备往主存写DMA读也就是设备发数据给主存还是主存往设备写DMA写也就是主存发数据给设备——以及是否允许中断等控制信息。有的教材里还会提到状态寄存器记录DMA传输是否结束、是否有错误等这个了解即可。2.2 为什么DMAC是主设备而不是从设备这里有个概念特别容易绕DMAC到底是主设备还是从设备答案是分情况讨论。在DMA传输开始前CPU要往DMAC的寄存器里写初值这时候DMAC是CPU的从设备CPU是主设备CPU通过地址总线选中DMAC通过数据总线向它写入。但在DMA传输进行中DMAC要接管系统总线向主存发出读/写命令由DMAC来控制总线、发出地址这时候DMAC就变成了主设备主存反而成了从设备。这个“身份转换”是DMA运行的底层逻辑。因为数据要绕过CPU直接在主存和设备之间搬运就必须有硬件代替CPU来发起总线事务这个硬件就是DMAC。你可以把DMAC理解成临时拿到方向盘的人平时是乘客从设备一旦DMA传输开始它接过方向盘控制总线等传完了再把方向盘还给CPU。了解这一点很多选择题就能秒杀。比如题目问“DMA传送过程中由谁控制总线”答案不是CPU而是DMAC。再比如问“DMA控制器和CPU哪个是主设备”要答“DMA传输时DMAC是主设备”。这些表述在真题里反复出现本质上都是在考你是否理解DMAC在DMA阶段的总线控制权。2.3 真题里怎么考DMAC内部结构从408历年真题和各大复习资料的出题风格看DMAC内部结构这块主要有三种考法。第一种是直接给一个场景让你判断某个寄存器该填什么初值。比如磁盘读入一个数据块到内存起始地址为2000H的地方数据块长度512B问你MAR和DC的初值分别是多少。这种题只要抓住MAR存首地址、DC存个数基本不会错。第二种是考总线宽度和DC位数的计算。这种题往往会结合数据传送单位来出比如每次DMA传送一个字字长16位要传送4KB数据问DC初值为多少。这里要先算清楚“个字”是多少4KB等于4096字节每次传2字节所以初值是2048。有的同学一上来就把4096当DC初值写进去就是把“字节”和“字”搞混了。第三种是概念辨析看看DMAC在DMA传输不同阶段扮演什么角色。这类题迷惑性强的选项一般是这样说“DMAC和主存之间可以直接建立数据通路无需经过CPU”这个是对的说“DMA传送过程中CPU完全释放总线控制权”这个就要看用的是哪种周期挪用方式不能一概而论。后面第3节会专门展开。3. 完整DMA传送过程拆解三个阶段决定成败3.1 预处理阶段CPU给DMAC下指令DMA传送开始前CPU要做一系列初始化操作。以从磁盘读一个数据块到主存为例CPU需要做这样几件事先往DMAC的MAR中写入主存接收区的首地址往DC中写入要传送的数据个数往CR中写入传送方向设备到主存和启动命令。这些初值全部就位后CPU就可以返回去执行原来的程序了DMAC开始接管后续的数据传送。注意这个预处理阶段是CPU主动做的一步不是DMAC自己完成的。408考试里常有个干扰选项说“DMA传送开始时由DMA控制器自行完成初始化”这句是错的。初始化永远是CPU的活因为只有CPU才知道本次传送的数据在主存的哪个位置、有多长、方向是什么。DMAC只是执行者不负责做计划。预处理阶段还有一个细节CPU设置完初值后要向设备发出“启动”命令让设备开始准备数据。设备准备好第一个数据后DMAC才开始实际的传送。所以整个DMA过程CPU参与的部分其实集中在开头这一小段之后就撒手了。3.2 数据传送阶段周期挪用是怎么发生的这个阶段是DMA的精髓也是很多人卡壳的地方。DMA数据传送的一种常见理解是DMAC每一次传送一个数据单位后就把总线还给CPU下一次传送前再申请总线。也就是说DMA并不是一口气把整块数据传完而是“传送一个数据单位—暂停—再传送一个数据单位”地反复进行。每传送一个数据单位DMAC占用一次总线占用一个或几个总线周期这个行为在教材里叫“周期挪用”也叫“周期窃取”。为什么不能一口气把所有数据都传完因为主存还要供CPU访问。如果DMAC长时间霸占主存总线CPU取指令、读数据都得等着相当于把系统的全部性能都交给了一个外设这不合理。周期挪用就是让DMA见缝插针CPU不用主存的时候或者CPU正在执行不需要访存的指令的时候DMAC趁这个空档插进来传一个数据。教材里通常会把周期挪用分成三种情况。第一种是CPU正在访问主存时DMAC也要访问主存这时理论上会有冲突解决办法是让DMAC等待一个周期CPU的访存结束后DMAC再插入。第二种是CPU不访问主存时DMAC可以直接挪用总线周期CPU不受影响。第三种是CPU正在访问主存、DMAC也来申请时有的系统中DMAC优先级更高会让CPU暂时停一个周期把总线让给DMAC。具体采用哪种策略取决于系统设计时对CPU和DMA优先级的取舍。这里必须提醒一句周期挪用的本质是“暂停”而不是“中断”。CPU被DMA暂停一个总线周期时不保存现场不需要执行中断服务程序只是单纯把总线让出来一个周期数据传完马上继续原来的工作。之前有人把DMA也归入中断一类说DMA是“优先级更高的中断”这个理解是错的。中断和DMA是两种独立的机制区别后面第4节详细说。3.3 后处理阶段一次DMA的收尾工作当DC减到0也就是一批数据全部传送完毕时DMAC会向CPU发出中断请求CPU响应后转入中断服务程序做后续的收尾工作。这个收尾包括检查本次DMA是否出了错误、确认传送的数据量是否符合预期、处理缓冲区后续逻辑、撤销DMAC上的中断请求等。处理完之后CPU才回到原来的程序继续执行。这里有两个容易混的点。第一DMA传输结束后发的是中断请求不是重新开始一次DMA。很多同学把“DMA结束后会用DMA方式通知CPU”当成正确表述其实不对结束通知用的就是传统中断方式。第二DMA传输过程中设备和主存之间的数据传送不需要CPU干预但传送结束后CPU的那次中断响应还是要耗CPU时间的。所以严格说DMA降低了CPU的I/O负担但没有完全消除CPU的参与。从整体看DMA三个阶段里数据传送阶段是DMAC独立完成的预处理和后处理都离不开CPU。所以复习时可以把DMA总结成一句口诀CPU两头管中间不用管。前头做初始化后头收个尾中间的数据搬运全交给DMAC。4. DMA与中断方式的终极对比一张表消除知识盲区4.1 四个维度对比路径、总线、时机、单位中断方式和DMA方式最容易被搞混因为两者都有“请求—响应—处理”的交互而且DMA结束还要用到中断。但在408考纲里它们是完全不同的两种控制方式。我建议你从四个维度去对比记起来最牢固。对比维度中断方式DMA方式数据传送路径设备→CPU→主存经过CPU中转设备→主存不经过CPU由DMAC控制总线控制权始终由CPU控制DMA传输期间由DMAC控制总线CPU介入频率每传送一个数据都要CPU介入一次CPU只在传送前初始化和传送后处理中断时介入传送单位一个字或一个字节一个数据块这张表里最核心的差别是传送单位。中断方式是“传一个、打断一次”单位小适合低速设备比如键盘、鼠标DMA方式是“整块传完再打断一次”单位是数据块适合高速设备比如磁盘、显卡、网络接口。408真题里有一类经典选择题给你四个设备问哪个适合用DMA方式答案通常是磁盘或高速I/O设备而不是键盘或打印机这类慢速设备。4.2 响应优先级和“程序VS硬件”逻辑再看优先级。在I/O系统中DMA请求的优先级通常高于中断请求。原因很好理解DMA请求一旦提出设备侧的数据如果不及时取走可能会丢失——比如磁盘控制器里的数据缓冲就那么大你不来取下一个数据一到就把旧数据覆盖了。而中断请求晚一点响应最多是CPU处理慢一点数据不会丢。所以系统设计上会让DMA请求优先宁可让CPU暂停一个周期也不能让高速设备的数据丢。从本质上说中断方式属于“程序控制”的范畴它要靠CPU执行中断服务程序来完成数据传送DMA方式属于“硬件控制”的范畴数据传送由DMAC这个硬件逻辑直接完成不需要CPU执行程序。这也是为什么DMA比中断“快”CPU执行一条指令要取指、译码、执行好几个周期而DMAC传送一个数据只需要一两个总线周期。不过要注意DMA传输过程本身不执行程序但DMA结束后的中断处理还是要执行程序。所以更准确的说法是DMA方式减少了CPU执行I/O程序的次数每次DMA结束只执行一次中断服务程序而中断方式每传送一个数据都要执行一次。4.3 从对比反推什么时候该用DMA把这四种控制方式的适用场景串一下程序查询方式适合单设备、低速、CPU空闲时间多的简单系统中断方式适合中低速设备能提高CPU利用率DMA方式适合高速设备成批数据交换通道方式则是DMA的发展形态用专门的I/O处理器管理多台设备但408考纲里通道只是基本概念重点还是DMA。做题时遇到“某设备采用何种控制方式”的题可以按这个思路反推题目强调“每次传送一个字传送频繁要求CPU响应快”——那是中断方式题目强调“成批数据”、“不经过CPU”、“由硬件直接控制”——那就是DMA题目给的是多个低速设备共享一个通道——那是通道方式。按这个逻辑去匹配正确率会高很多。5. 408真题角度DMA考点怎么出、怎么答5.1 选择题高频陷阱盘点先说选择题里最常见的陷阱基本绕不开这几个。第一个陷阱是“DMA传送前由DMA控制器设置初值”。这句话是错的初值由CPU设置。很多教材在画DMA流程图时把“CPU初始化DMAC”这个圆角矩形画在预处理阶段有的同学一看流程图上写“初始化DMAC”就没细想谁在初始化做题时被“DMAC自己初始化”这个选项带偏。记住控制器只是执行机构计划是CPU做的。第二个陷阱是“DMA方式传送数据过程中不需要CPU干预所以CPU可以完全不管I/O”。这话半对半错。DMA传送中间确实不需要CPU干预但CPU在开始时得初始化结束时得响应中断。最准确的说法是“DMA传送过程中CPU可以继续执行原有程序仅在传送结束时接受一次中断”。凡是把“完全不需要CPU”写成绝对表述的选项先画个问号。第三个陷阱是把“周期挪用”和“CPU暂停访问”混为一谈。周期挪用是DMAC在每个数据单位传送时占用一个总线周期传送完就把总线还回去CPU大部分时间照常工作而“CPU暂停访问”是DMA请求到来时CPU被强制停一个周期让出总线这是针对冲突情况的一种处理策略不是周期挪用本身的定义。选择题里常给一句话“DMA方式采用周期挪用的方式占用CPU一个访存周期”有的同学觉得这说法太绝对但它在特定情形下是对的。做题时要看题目前提是“CPU正在访问主存”还是“DMAC访问冲突”。第四个陷阱是DMA应用场景的判断。题干说“某设备数据传输率很高且每次传送的数据量很大”对应DMA方式题干说“设备数据量小传送不频繁”对应中断方式。反过来如果题干说“有一个设备需要在每100微秒就传送一个字节否则数据丢失”这种高频小数据量的场景其实适合DMA因为中断方式的开销可能跟不上100微秒的节奏。这一点容易被忽略因为很多人默认DMA只适合大数据块。5.2 大题计算题的两种典型考法DMA在408大题里通常不单独出一道完整的综合题但会作为计算题的一部分出现。最常见的考法是结合磁盘、总线周期、数据传输率来算DMA传送占用的时间。第一种典型考法给总线频率和数据宽度计算传送一个数据块需要多少个总线周期、占用多长时间。举个例子某系统总线频率为100MHz每次总线传输32位数据DMAC每传送一个32位数需要占用1个总线周期。现在要从磁盘读入512字节的数据到主存问DMAC需要占用多少个总线周期总共占用多长时间。计算步骤是512字节等于4096位每次传32位所以需要4096除以32等于128个总线周期。一个总线周期是1除以100MHz等于10纳秒。128乘以10纳秒等于1280纳秒约1.28微秒。这道题的要点第一是单位的换算第二是别把字节直接当个数要先换算成位再除以总线宽度。第二种典型考法给CPU指令执行周期数计算DMA周期挪用对CPU性能的影响。这类题通常会告诉你CPU执行一条指令平均需要4个总线周期而DMAC每传送一个数据需要占用1个总线周期。假设DMAC连续传送N个数据每个数据都发生一次周期挪用问CPU的有效执行速度降低了多少。思路是传送N个数据DMAC一共需要N个总线周期这些周期里CPU无法使用总线而正常情况下CPU执行N条指令需要4N个总线周期。如果把这N个总线周期的挪用量折算到N条指令上相当于每执行一条指令多等了1个总线周期CPU性能下降比例可以按“被挪用的总线周期数除以原本需要的总线周期数”来算也就是N除以4N等于25%。这类题的关键是理解“周期挪用”是分时占用不是一次性占用。我做题时的习惯是先把“总线周期”“字节”“位”的单位统一再一步步算。DMA计算题出错大多不是思路问题而是单位换算不仔细128个扇区、512字节、32位总线、100MHz这种数字一多最后结果差一位小数都对不上答案。5.3 答题规范DMA过程描述题怎么写才不丢分408的部分题目要求描述DMA传送过程或者判断某个表述正误后说明理由。这种题最容易失分的地方是漏步骤。完整答题应该覆盖三个阶段。第一步写预处理CPU向DMAC的MAR写入主存首地址向DC写入传送数据个数向CR写入传送方向和启动命令。这里要明确指名道姓地把寄存器写出来不要只写“CPU初始化DMA控制器”一句话。第二步写数据传送DMAC获得总线控制权后每次传送一个数据单位每传一个数据单位DC减1MAR加1如果是连续地址的话同时采用周期挪用方式与CPU分时使用总线。这一步最好把DC减到0作为阶段结束的标志写出来。第三步写后处理DC为0时DMAC向CPU发出中断请求CPU响应中断执行中断服务程序做收尾处理原程序恢复执行。如果题目要求画流程图你就按“预处理—数据传送—后处理”三段式画成三个方框中间用箭头连接每个方框旁边注明“CPU完成”“DMAC完成”“CPU完成”的归属这样的图既清晰又能展示你对DMA职责边界的理解。408阅卷是按得分点给分寄存器名字写全了三个阶段齐全了就算文字朴素一点也能拿到大部分分。6. 复习DMA时的三条实战建议6.1 第一遍看不懂很正常先搭框架再填细节我当年复习到这一节的时候看完一遍课本直接懵了尤其是“周期挪用”和“DMA控制器身份切换”这两块翻了三遍才缓过来。后来我发现一个比较管用的顺序第一遍不要抠细节先把“CPU两头管中间不用管”这句口诀记住再记住DMA三个阶段的名字和归属整体框架搭好之后第二遍再去看MAR、DC、CR怎么工作第三遍再去纠结周期挪用的三种情形。三轮下来原本觉得抽象的东西就自然落地了。6.2 画图比背书重要手绘DMA流程图背书效率很低画图效率要高得多。你可以拿一张A4纸把DMA三个阶段的方框图画一遍标注每阶段的完成主体、涉及的寄存器、总线控制权的变化。画完这张图周期挪用是怎么回事、DMAC什么时候当主设备基本就刻在脑子里了。我在复习后期基本不看文字笔记就靠这张图回忆整个DMA流程。6.3 把DMA和中断做成错题对照表DMA和中断的混淆是这章最常见的失分原因。建议你专门做一个两列对照表左边写中断方式右边写DMA方式内容涵盖数据传送路径、CPU介入频率、传送单位、响应优先级、结束后如何通知CPU。做题遇到新的判断题就往表里补充新的角度。这个表做完你再看到“DMA结束后通过中断方式通知CPU”这种说法就不会再犹豫对错了。最后再分享一个小技巧复习I/O方式时别只盯着DMA本身把程序查询、中断、DMA、通道四种方式放在一起比较你会发现它们其实是一条“CPU逐步放手”的演进线。程序查询是CPU全包中断是CPU每次插手一次DMA是CPU只管头和尾通道是CPU连头尾都少管。理清这条线I/O这一章的选择题基本就不会丢分了。根据我个人经验DMA真正难的不是背概念而是把“谁在什么阶段干什么”这件事彻底理清一旦理清做题速度和准确率都会有明显提升。