计算机系统基础(六)之RISC-V汇编
⽂章⽬录
前⾔
之前简单的讲过了RISC-V指令集,接下来我将简单的介绍⼀下RISC-V的汇编。更直观的去了解,C语⾔程序如何⼀步步变成机器语⾔并让机器执⾏程序。
提⽰:以下是本篇⽂章正⽂内容,下⾯案例可供参考
⼀、RISC-V汇编语⾔简介
汇编语⾔(Assembly Language)是⼀种“低级”语⾔,直接接触最底层的硬件,需要对底层硬件⾮常熟悉才能编写出⾼效的汇编程序。并且汇编语⾔属于第⼆代计算机语⾔,⽤⼀些容易理解和记忆的字母,单词来代替⼀个特定的指令。因此在汇编语⾔中,⽤助记符代替机器指令的操作码,⽤地址符号或标号代替指令或操作数的地址。⽐如:⽤“ADD”代表数字逻辑上的加减,“ MOV”代表数据传递等等。
C语⾔程序在翻译成可以在计算机上运⾏的机器语⾔程序,⼤致需要四个步骤。
1. ⾸先将⾼级语⾔程序编译成汇编语⾔程序
2. 然后⽤机器语⾔组装成⽬标模块
3. 链接器将多个模块与库程序组合在⼀起以解析所有引⽤
4. 最后加载器将机器代码放⼊适当的存储器位置以供处理器执⾏
注:所有程序不⼀定严格按照这个四个步骤执⾏。为了加快转换过程,可以跳过或将⼀些步骤组合到⼀起。⼀些编译器直接⽣成⽬标模块,⼀些系统使⽤链接加载器执⾏最后两个步骤。为了识别⽂件类型,UNIX遵循⽂件的后缀约定:C源⽂件命名为x.c,汇编⽂件命名为x.s,⽬标⽂件命名为x.o,静态链接库程序为x.a,动态链接库路径为x.so,以及默认情况下,可执⾏⽂件称为a.out。MS-DOS使⽤后缀.C、.ASM、.OBJ、.LIB、.DLL和 .EXE的效果相同。
汇编语⾔的优缺点
汇编语⾔的缺点:
难读
汇编指令有多少个难写
难移植
汇编语⾔的优点
灵活
强⼤
汇编语⾔的应⽤场景
会要直接访问底层硬件的地⽅
需要对性能执⾏极致优化的地⽅
⼆、汇编语⾔语法介绍
⼀个完整的 RISC-V 汇编程序有多条 语句 (statement) 组成。
⼀条典型的 RISC-V 汇编 语句 由 3 部分组成:[ label:][ operation] [ comment]
label(标号): GNU汇编中,任何以冒号结尾的标识符都被认为是⼀个标号。表⽰当前指令的位置标记。
operation 可以有以下多种类型:
instruction(指令): 直接对应⼆进制机器指令的字符串。例如addi指令、lw指令等。
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 汇编指令分类
RISC-V汇编指令分类主要有以下⼏种:算术运算指令、逻辑运算指令、位移运算指令、内存读写指令、分⽀与跳转指令。如下图所⽰,汇编语⾔的操作与指令是⼀⼀对应的,汇编程序可以很简单快速的翻译成机器指令。
RISC-V 汇编伪指令
伪指令是由多个汇编指令组成
注:【参考 1】:The RISC-V Instruction Set Manual,Volume I: Unprivileged ISA,
Document Version 20191213
四、RISC-V 汇编指令详解
上图中已经显⽰了汇编中主要的分类,这⾥我们将更加具体的讲解每⼀类汇编指令。更加有助于理解,RISC-V 汇编。算术运算指令(Arithmetic Instructions)
ADD:寄存器与寄存器的加法运算
对应的RISC-V的指令集
SUB:寄存器与寄存器的减法运算
ADDI:寄存器与⽴即数的加法运算
注:(1)imm (12): “immediate”, ⽴即数占 12 位
(2)在参与算术运算前该 immediate 会被 “符号扩展” 为⼀个 32 位的数
(3)这个⽴即数可以表达的数值范围为:[-2^11 , +2^11),即[-2048, 2047)。
LUI:寄存器存放⼀个32 bits 的⾼20位的⽴即数。
注:LUI 指令会构造⼀个 32 bits 的⽴即数,这个⽴即 数的⾼ 20 位对应指令中的 imm,低 12 位清零。 这个⽴即数作为结果存放在RD 中。
在中有关于此处的讲解。
LI:是⼀个伪指令,汇编器会根据 IMM 的实际情况⾃动⽣成正确的真实指令。
AUIPC:寄存器存放⼀个32 bits 的⾼20位的⽴即数。
注:构造⼀个 32 bits 的⽴即数,这个⽴即数的⾼ 20 位对应指令中 的 imm,低 12 位清零。但和 LUI 不同的是, AUIPC 会先将这个⽴即数和 PC 值相加,将相加 后的结果存放在 RD 中。
LA:伪指令,常⽤于加载⼀个函数或者变量的地址
注:具体编程时给出需要加载的 label,编译器会根据实 际情况利⽤ auipc 和其他指令⾃动⽣成正确的指令 序列。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。