RISC-V 汇编语言入门
汇编语言概念简介
汇编语言(Assembly Language)是一种“低级”语言。
汇编语言的缺点:
- 难读
- 难写
- 难移植
汇编语言的优点
- 灵活
- 强大
汇编语言的应用场景
- 需要直接访问底层硬件的地方
- 需要对性能执行极致优化的地方
汇编语言语法介绍
一个完整的 RISC-V 汇编程序有多条 语句
(statement) 组成。
一条典型的 RISC-V 汇编 语句
由 3 部分组成:
label
(标号): GNU汇编中,任何以冒号结尾的标识符都被认为是一个标号。operation
可以有以下多种类型:- instruction(指令): 直接对应二进制机器指令的字符串
- pseudo-instruction(伪指令): 为了提高编写代码的效率,可以用一条伪指令指示汇编器产生多条实际的指令(instructions)。
- directive(指示/伪操作): , 通过类似指令的形式(以“.”开头),通知汇编器如何控制代码的产生等,不对应具体的指令。
- macro:采用 .macro/.endm 自定义的宏
comment
(注释): 常用方式,“#” 开始到当前行结束。
RISC-V 汇编指令总览
RISC-V 汇编指令操作对象
寄存器:
- 32个通用寄存器,x0 ~ x31(注意:本章节课程仅涉及 RV32I 的通用寄存器组);
- 在 RISC-V 中,Hart 在执行算术逻辑运算时所操作的数据必须直接来自寄存器。
内存:
- Hart 可以执行在寄存器和内存之间的数据读写操作;
- 读写操作使用字节(Byte)为基本单位进行寻址;
- RV32 可以访问最多 2^32 个字节的内存空间。
RISC-V 汇编指令编码格式
- 指令长度:ILEN1= 32 bits (RV32I)
- 指令对齐:IALIGN = 32 bits (RV32I)
- 32 个 bit 划分成不同的 “域(field)”
- funct3/funct7 和 opcode 一起决定最终的指令类型
- 指令在内存中按照 小端序 排列
指令格式(format)
- R-type:(Register),每条指令中有三个 fields,用于指定 3 个 寄存器参数
- I-type: (Immediate),每条指令除了带有两个寄存器参数外,还带有一个立即数参数(宽度为 12 bits)。
- S-type: (Store),每条指令除了带有两个寄存器参数外,还带有一个立即数参数(宽度为 12 bits,但 fields 的组织方式不同于 I-type)
- B-type: (Branch),每条指令除了带有两个寄存器参数外,还带有一个立即数参数(宽度为 12 bits,但取值为 2 的倍数)。
- U-type: (Upper),每条指令含有一个寄存器参数再加上一个立即数参数(宽度为 20bits,用于表示一个立即数的高 20 位)
- J-type: (Jump),每条指令含有一个寄存器参数再加上一个立即数参数(宽度为 20bits)
主机字节序 (HBO - Host Byte Order)
一个 多字节整数 在计算机内存中存储的字节顺序称为主机字节序(HBO- Host Byte Order,或者叫本地字节序);不同类型 CPU 的 HBO 不同,这与 CPU 的设计有关。分为 大端序(Big-Endian) 和 小端序(Little-Endian)。
RISC-V 汇编指令分类
RISC-V 汇编伪指令一览
RISC-V 汇编指令进阶
算术运算指令
_start:
la x5, _start # x5 = _start
jr x5
逻辑运算指令
移位运算指令
10010000
->11001000
高位为1补1,为0补0
内存读写指令
条件分支指令
无条件跳转指令
RISC-V 指令寻址模式总结
RISC-V 汇编函数调用约定
函数调用过程概述
汇编编程时为何需要制定函数调用约定
有关寄存器的编程约定
函数跳转和返回指令的编程约定