??本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记,计划从RISC-V的底层汇编指令学起,结合C语言,在Ubuntu 20.04上开发一个简易的操作系统。一个目的是通过实践操作学习和了解什么是操作系统,第二个目的是为之后学习RISC-V的集成电路设计打下一定基础。本系列持续不定期更新,分享出来和大家一同交流进步。
??博主是微电子科学与工程专业的学生,对软件和操作系统难免有理解不到位的地方。如有谬误敬请不吝告知,不胜感激。
??参考课程及文章:
??【Bilibili】[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春
??汇编语言(Assembly Language)是一种“低级”语言。不同的架构的汇编语言是不同的,因为底层的寄存器的个数和功能不同。例如x86的机器语言在RISC-V的机器上是无法运行的,但是使用高级语言时完全不需要考虑底层的机器语言。我们使用不同的编译器将高级语言翻译成不同的机器语言,来完成对内存和指令的管理和优化。而正是由于这一点,使用汇编语言时完全不需要考虑不同编译器的影响,这也是汇编语言的灵活性的体现。本课程学习和使用的汇编语言是RISC-V汇编语言,其依赖于RISC-V独有的GNU汇编器,所以将RISC-V的汇编程序移植到其他架构的处理器上也是无法运行的。
??一个完整的RISC-V汇编程序有多条语句(statement)组成,汇编文件一般由.s
结尾(不包含预处理语句,是纯粹的汇编语句)。一条典型的RISC-V汇编语句由3部分组成,分为标签、操作和注释:
[label:] [operation] [comment]
add
。li
。在理解和做法上与自定义的函数类似。.text
、.global
、.end
、.macro
、.endm
等。在理解和应用上类似C语言中的#define
语句。.macro
/.endm
自定义的宏,汇编器碰到宏时会自动将宏替换成对应定义的内容。#
开始到当前行结束,也有些汇编器定义;
或//
开头的注释格式。??下面是一个简单的RISC-V的汇编语言程序:
# fitst RISC-V Assemble Sample
.macro do_nothing
nop
nop
.endm
.text
.global _start
_start:
li x6, 5 # x6 = 5
li x7, 4 # x7 = 4
add x5, x6, x7 # x5 = x6 + x7
do_nothing
stop:
j stop # jump to stop
.end
XLEN
表示机器的字长,RV32I的ISA对应的XLEN
对应的就是32位。x0
寄存器很特殊,其中的值恒为0,且不允许写操作,读出的值恒为0。pc
即指针计数器寄存器在RISC-V中是禁止被访问的。获取程序当前运行的位置需要用特殊的方法实现。??做底层开发的时候,经常需要进行逐字节对照查阅指令。可以根据手册(RISC-V非特权指令集)查阅每个指令的含义。
指令长度:在RISC-V汇编指令的规范中,所有的指令的长度都是固定的(在非压缩的情况下讨论)。RV32I中指令长度ILEN1
= 32bit。
指令对齐:指一条指令开始的地址,IALIGN
= 32bit表示指令开始的地址一定是4的倍数,程序加载的时候一定从这样一个指令开始的地方开始加载。
每个32bit构成一个域。
funct3/funct7
和opcode
共同决定了最终的指令类型。以add
指令为例,它对应的opcode
为0110011,通过查阅下标可以发现它是一条OP类型的指令。
指令在程序中按小端序(Little-Endian)排列(底字节存入低地址,高字节存入高地址)。不同的CPU规定的主机字节序不同。
RISC-V中有六种不同的指令格式(format):
??RISC-V中常用的汇编指令如下表所示:
??伪指令很多,一条伪指令具体执行哪些代码可以在 RISC-V非特权指令集手册 中的 RISC-V Assembly Programmer’s Handbook 章节查阅到。
??原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记。