简介:这份PDF面向嵌入式开发、体系结构学习者与编译器/操作系统底层研究者,系统讲解RISC-V指令集架构的设计理念与实现方法,帮助读者从零建立对开源ISA的整体认知。资源包共1个PDF文件,约8.1MB,内容为完整中文译本,由勾凌睿、黄成、刘志刚等翻译、包云岗校阅,含参考卡、致谢、前言、译者序与翻译团队介绍。正文从「为什么要有RISC-V」切入,阐述模块化与增量型ISA思路及ISA设计101的指令格式、寄存器组织、指令执行等基本原则,再逐章展开RV32I基础整数指令集,涵盖指令格式、寄存器、整数计算、Load/Store与条件分支等核心内容,目录结构清晰,便于按章节检索与对照查阅。已有4955人学习,适合作为课程配套读物或案头速查手册使用。
1. 从“看不懂芯片手册”说起:RISC-V 到底是什么
很多人第一次听到 RISC-V,反应是“这仨字母加一横杠,念都不会念”。我当初也一样,以为是什么高深莫测的芯片黑科技,直到有人告诉我:你可以把它理解成一份“给芯片下命令的说明书”。芯片本身只会做加减、读写、跳转这些最基础的动作,而它到底认识哪些命令、每条命令长什么样、怎么编码,全都写在这份说明书里——这份说明书就叫指令集架构,英文缩写 ISA。RISC-V 就是其中一种开源、免费、谁都能拿去用的指令集架构。
那它解决什么问题?过去你想设计一颗芯片,得先向某家公司买指令集的授权,价格不透明、条款还多。RISC-V 把这份“命令清单”公开出来,学生、小团队、爱好者都能直接拿来学、拿来改、拿来造。这本《RISC-V 中文手册》就是那份清单的中文讲解版,从最基础的整数指令讲到浮点、向量、特权模式,还拿 ARM、MIPS、x86 做对照。适合谁?适合刚接触计算机底层、想搞明白“程序到底怎么被芯片执行”的零基础新手,也适合想动手玩嵌入式或芯片设计但被英文文档劝退的人。
2. 为什么值得学:先搞懂它和你想的不一样
2.1 它不是又一种“编程语言”,而是语言脚下的地板
新手最容易犯的迷糊,是把 RISC-V 当成 C 语言、Python 那样的编程语言。不是的。你写的 Python 代码要经过解释器,C 代码要经过编译器,最后都会变成一串“机器指令”,而 RISC-V 规定的就是这串机器指令的格式和含义。换句话说,编程语言是你跟计算机说话的方式,指令集架构是计算机真正听得懂的“母语”。
这本手册第一章就点明了这个定位:它讲的是 ISA 设计的基本功——指令格式怎么排、寄存器怎么组织、指令怎么执行。你不需要先会写编译器才能读,但读完你会突然明白,为什么同样一段循环,在不同芯片上跑出来的指令条数不一样。手册里专门拿插入排序这个例子,把 RV32I、ARM-32、MIPS-32、x86-32 四种指令集放在一起比,谁的命令更精简、谁更啰嗦,一目了然。这种“横向对照”是这本书最值钱的地方之一,它不逼你死记,而是让你看见设计取舍。
2.2 模块化设计:像点菜一样挑你要的部分
RISC-V 最讨喜的设计叫“模块化与增量型 ISA”。翻成大白话:它不是一个必须全盘接受的大套餐,而是一张可以单点的菜单。最核心的底座叫 RV32I,只有四十来条基础整数指令,小到能塞进教学芯片里;你想要乘法除法,加个 M 扩展;想要单精度浮点,加个 F;想要压缩指令省空间,加个 C;想要向量计算,加个 V。手册从第二章到第九章,基本就是按这张菜单一道道讲过去的。
这对新手意味着什么?意味着你不需要一上来就啃完几百页。你可以先只学 RV32I,把“寄存器、Load/Store、条件分支、无条件跳转”这几样弄明白,就已经能读懂一小段汇编、能理解一个函数调用是怎么在芯片上发生的了。我第一次学的时候就是死磕 RV32I 这一章,其他的先跳过,反而没被吓退。手册的目录结构本身就在教你“怎么循序渐进”,这是它比很多厚砖头教材友好的地方。
2.3 学它到底能换来什么:三个看得见的去处
第一个去处是“看懂底层”。你天天写代码,但栈溢出、野指针、函数调用开销这些词一直像玄学。读完汇编语言那一章(第三章),函数调用规范、汇编器、链接器、加载器这些黑匣子会被一个个打开,你会知道参数是怎么塞进寄存器、返回地址存在哪、静态链接和动态链接差在哪。这些知识不会让你立刻涨薪,但会让你排查问题时少一层“凭感觉”。
第二个去处是“上手嵌入式与教学芯片”。RV32I 足够简单,很多教学用的处理器核、FPGA 小项目都拿它当起点。手册里讲的特权架构(第十章)虽然偏深,但前面讲的机器模式、异常处理,是理解“芯片怎么从一条指令跳到处理中断”的钥匙。你不需要造芯片,但你能看懂别人开源的小核是怎么跑的。
第三个去处是“建立判断力”。手册反复拿 RISC-V 和 ARM、MIPS、x86 对比,还专门有一章讲“未来的可选扩展”(第十一章),把 B、E、H、J、L、N、P、Q 这些扩展挨个点名。读完之后,你再看到“某芯片支持向量扩展”这种新闻,不会一头雾水,而是能判断它大概强在哪、适合什么场景。这种判断力,是零基础的人最缺、也最该先补的。
3. 零基础怎么迈第一步:先跑通一个最小例子
3.1 先别急着装工具,把“寄存器”这个概念吃透
真正动手之前,有一个概念必须先落地:寄存器。你可以把它想成芯片手边的一排小抽屉,编号从 x0 到 x31,一共 32 个,每个能放一个 32 位的数。芯片做任何计算,都得先把数从内存搬进抽屉,算完再搬回去。手册第二章 2.3 节专门讲 RV32I 的寄存器,其中 x0 是个特殊抽屉,永远装着 0,你往里写什么都没用——这个设计看着奇怪,其实是让“清零”“比较”这类操作少写指令。
为什么先讲这个?因为后面所有指令都围着寄存器转。Load 是从内存往抽屉里搬,Store 是从抽屉往内存里放,整数计算是在抽屉之间加减,条件分支是看抽屉里的数决定跳不跳。你把这 32 个抽屉想明白了,后面看指令就像看“把 3 号抽屉的数加到 5 号抽屉”这么直白。我第一次学的时候画了一张表,把 x0 到 x31 抄了一遍,标上哪些是临时用、哪些要保存,后面看函数调用规范时省了大力气。
3.2 第一个能跑的例子:两条指令看懂“加法”
零基础不需要一上来就搭环境。手册本身是 PDF,你手上只要有纸笔或者一个文本编辑器,就能跟着推演。下面这段是最小化的 RV32I 加法示意,用汇编写法表示,注释我写得很白:
# 把立即数 5 装进 x1 号抽屉(寄存器) addi x1, x0, 5 # 把立即数 3 装进 x2 号抽屉 addi x2, x0, 3 # 把 x1 和 x2 里的数相加,结果放回 x3 add x3, x1, x2逐行解释一下。第一行addi x1, x0, 5,意思是“拿 x0(永远是 0)加上立即数 5,存进 x1”,效果就是 x1 变成 5。第二行同理,x2 变成 3。第三行add x3, x1, x2是纯寄存器加法,x3 就是 8。这里的关键词是“立即数”,就是直接写在指令里的常数,手册 2.4 节讲整数计算时反复用到。
你可能会问:这跟我在电脑上跑程序有什么关系?关系在于,任何复杂的程序,剥到最底层都是这种“搬数、加数、比较、跳转”的组合。手册 2.9 节用插入排序做对比,就是把一个你熟悉的排序算法拆成这四种动作,然后数一数不同指令集各要多少条。你先把这三行看懂,再去看插入排序的汇编,就不会觉得是天书。
3.3 想真跑起来:找一个模拟器,把上面的例子喂进去
光推演还不够,想有“跑通”的实感,可以找一个 RISC-V 模拟器。入门阶段不用碰真芯片,模拟器就是一台用软件假装出来的 RISC-V 机器,你给它指令,它给你结果。常见做法是装一个轻量的模拟环境,把上面那段汇编存成文件,汇编、链接、运行三步走。命令大致长这样(不同工具链名字略有差异,以你装的那套为准):
# 把汇编源文件汇编成目标文件 riscv64-unknown-elf-as add.s -o add.o # 链接成可执行文件 riscv64-unknown-elf-ld add.o -o add # 用模拟器运行,查看寄存器结果 spike pk add这三步对应手册第三章讲的“汇编器、链接器、加载器”。as是汇编器,负责把助记符翻译成机器码;ld是链接器,负责把目标文件拼成可执行文件;spike是模拟器,负责一条条执行。跑完之后你可以用调试方式看 x3 是不是 8。第一次看到自己写的三行指令真的被“执行”了,那种感觉比读十页理论都管用。如果工具链名字对不上,别慌,手册第三章 3.3 到 3.6 节把这几步的原理讲得很清楚,你照着原理去找对应命令就行。
提示:入门阶段跑不通工具链非常正常,八成是路径或工具名不对。先把“汇编→链接→运行”这三步的概念记住,命令可以慢慢调。
4. 避坑指南:新手最容易翻车的五个地方
4.1 一上来就啃特权架构,直接被劝退
现象:翻开第十章“RV32/64 特权架构”,看到机器模式、监管者模式、页式虚拟内存,脑子嗡一下,合上书再也不想打开。原因:这一章是给要写操作系统或做芯片验证的人准备的,零基础直接读等于还没学会走就想跑。解决:按手册目录顺序来,先把第二章 RV32I 和第三章汇编语言吃透,特权架构留到你能独立读懂一段函数调用的汇编之后再碰。我当初就是跳着读,结果回头补基础花了两倍时间。
4.2 把“扩展”当成必学,贪多嚼不烂
现象:看到 M、F、D、C、V 一堆扩展,觉得少学一个就亏了,挨个硬啃,最后哪个都没记住。原因:RISC-V 的模块化设计本来就是让你按需取用,不是让你全修。解决:入门只认 RV32I 这一个底座,顶多再加一个 M(乘除法)感受一下扩展是怎么“插”进来的。手册第四章讲乘除法、第五章讲浮点,你完全可以等有具体需求了再回来看。贪多的血泪经验就是:基础指令没熟,扩展学得越多越乱。
4.3 寄存器编号和别名混着记,看代码就懵
现象:手册里一会儿写 x1,一会儿写 ra,一会儿写 sp,你不知道是不是同一个东西。原因:RV32I 的 32 个寄存器有编号名(x0–x31)和约定别名(ra 返回地址、sp 栈指针、a0–a7 参数寄存器等),手册第三章讲函数调用规范时会大量用别名。解决:初学阶段先死记 x0 恒为 0,其余的先按编号理解;等读到函数调用规范,再回头把别名和编号对上一张表。别一上来就背别名表,容易记串。
4.4 以为 PDF 读完就会了,从不动手
现象:手册从头翻到尾,感觉都看懂了,一让你写两行汇编就卡住。原因:指令集这种东西,看和做是两回事,格式、偏移量、跳转条件这些细节只有动手才会暴露。解决:每读完一小节,就把书上的例子手抄一遍,能跑模拟器就跑一遍。手册 2.9 节那个插入排序对比,你哪怕只把 RV32I 版本抄下来跑通,理解深度也远超读三遍。我自己的习惯是每章至少留一个能跑的最小例子,跑不通就不往下走。
4.5 被英文缩写吓住,其实每个都有大白话
现象:ISA、RV32I、ABI、SIMD、DAXPY 一串缩写砸过来,直接放弃。原因:手册是翻译版,术语密度高,但每个缩写第一次出现时基本都有解释。解决:准备一张纸,遇到缩写就记下“中文意思 + 一句话作用”,比如 ISA 就是指令集架构、ABI 就是函数调用时参数怎么传的约定。手册第五章用 DAXPY 程序做浮点对比,DAXPY 说白了就是“一个向量乘常数加到另一个向量上”,拆开看一点都不玄。
5. 下一步学什么:一条能走通的自学路线
走到这里,你已经知道 RISC-V 是什么、为什么值得学、第一个加法例子怎么跑。接下来最怕的是“然后呢”。我给你一条我自己走过、也带过新手走通的路线,按顺序来,别跳。
第一步,把 RV32I 的六类指令过一遍:整数计算、Load/Store、条件分支、无条件跳转、杂项,加上寄存器。对应手册第二章 2.4 到 2.8 节。目标不是背,而是给你一条指令,你能说出它动的是哪个寄存器、结果去哪。这一步大概花一周,每天半小时就够。
第二步,读第三章汇编语言,重点盯函数调用规范和汇编器、链接器、加载器三件套。这一步是把“单条指令”串成“一个函数怎么被调用”的关键。你可以拿一段最简单的 C 函数,用工具链编成汇编,对照着手册看参数怎么进 a0–a7、返回地址怎么进 ra。这一步走通,栈溢出、野指针这些词就不再是玄学。
第三步,挑一个扩展感受模块化。建议选 M(乘除法,第四章),因为它最短、最直观。看完你会明白“扩展”不是另起炉灶,而是在基础指令旁边加几条新命令。之后想学浮点(第五章)或压缩指令(第七章),按兴趣来。
第四步,等前三步稳了,再碰第十章特权架构。这时候你已经有汇编底子,看机器模式、异常处理、页式虚拟内存会顺很多。如果目标是嵌入式,重点看 10.2 到 10.4;如果对操作系统感兴趣,10.5 和 10.6 值得多读两遍。
| 阶段 | 对应手册章节 | 建议投入 | 检验标准 |
|---|---|---|---|
| 打底座 | 第二章 RV32I | 约一周 | 能口述六类指令作用 |
| 串流程 | 第三章 汇编语言 | 约一周 | 能看懂一个简单函数的汇编 |
| 试扩展 | 第四章 乘除法 | 两三天 | 能说清扩展怎么插入 |
| 进阶 | 第十章 特权架构 | 按需 | 能理解异常处理流程 |
最后说个我自己的习惯。从那以后我每次学新的指令集,都强制走一遍“抄一个最小例子 → 跑通 → 改一个参数看结果变不变”的流程,绝不只读不练。手册再清楚,也是别人的总结,只有你亲手让 x3 变成 8 的那一刻,它才真正变成你的。希望帮到你。
本文还有配套的精品资源,点击获取