RISC-V学习基础(四)

算术运算指令
ADD指令是R-type类型(寄存器类型,操作数有三个,都是寄存器,最终存放结果的寄存器放在第一个参数)
add rd,rs,rs2:将RS1里取出一个值,再从RS2里取出一个值,两个值相加,放进RD中。
例如:
add x5,x6,x7
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
GNU编译出来的文件都是ELF格式的。

有符号数在计算中的表示:二进制补码。

RISC-V基础整数指令集

在这里插入图片描述
图2.1是RV32I基础指令集的一页图形表示。对于每幅图,将有下划线的字母从左到右连接起来,就可以组成完整的RV32I指令集。

  • {}列举了指令的所有变体,变体用加下划线的字母或下划线字符_表示。特别的,下划线字符_表示对于此指令变体不需用字符表示。
    在这里插入图片描述
    上图表示了4个RV32I指令:slt、slti、sltu、sltiu

RV32I指令格式
在这里插入图片描述
图2.2展示了六种基本指令格式。

  • R类型指令:用于寄存器到寄存器的操作。
  • I类型指令:用于短立即数和访存load操作。
  • S类型指令:用于访存store操作。
  • B类型指令:用于条件跳转操作。
  • U类型指令:用于长立即数。
  • J类型指令:用于无条件跳转。

在这里插入图片描述
图2.3使用图2.2的指令格式列出了图2.1中所出现的所有RV32I指令的操作码。

  • RISC-V指令只有六种格式。
  • 所有的指令都是32位长,这简化了指令解码。
  • RISC-V指令提供了三个寄存器操作数。
  • RISC-V中所有指令,要读写的寄存器的标识符总是在同一位置,意味着在解码指令之前,就可以先访问寄存器。
  • 指令中立即数字段总是符号扩展,符号位总是在指令中最高位。这意味着可能成为关键路径的立即数符号括号,可以在指令解码之前进行。
  • 所有位全部是0是非法的RV32I指令。因此,视图跳转到被清零的内存区域的错误跳转,会立即触发异常,这可以帮助调试。所有位全部是1的指令也是非法指令,它将捕获其它常见的错误,例如未编程的非易失性内存设备、断开连接的内存总线或者是坏掉的内存芯片。

RV32I寄存器

在这里插入图片描述
图4列出了RV32I寄存器以及有RISC-V应用程序二进制接口(ABI)所定义的寄存器名称。
RV32I有31个寄存器加上一个值恒为0的x0寄存器。
为常量0单独分配一个寄存器是RISC-V ISA能如此简单的一个很大的因素。

RV32I整数计算

  • 简单的算术指令(add,sub)、逻辑指令(and,or,xor)以及移位指令(sll,srl,sra)和其他ISA差不多。他们从寄存器读取两个32位的值,并将32位结果写入目标寄存器。

  • RV32I还提供了这些指令的立即数版本。

  • 程序可以根据比较结果生成布尔值。为应对这种使用场景,RV32I提供了一个当小于时置位的指令。如果第一个操作数小于第二个操作数,将目标寄存器设置为1。对于这个指令,有一个符号版本(slt)和无符号版本(sltu),分别用于处理有符号和无符号的整数比较。相应的,上述两条指令也有立即数版本(slti、sltiu)。

  • 虽然RV32I分支指令可以检查两个寄存器之间的所有关系,但一些条件表达式涉及多对寄存器之间的关系。对于这些表达式,编译器或汇编语言程序员可以将slt以及与或异或等逻辑指令组合使用来解决更复杂的条件表达式。

  • 图2.1剩下的两条整数计算指令主要用于构造大的常量数值和链接。加载立即数到高位(lui(load upper immediate))将20位常量加载到寄存器的高20位。接着就可以使用标准的立即指令来创建32位常量。这样子,仅仅使用两条32位RV32I指令,就可以创造一个32位常量。

  • 向PC高位加上立即数(auipc(add upper immediate to pc)),让我们仅使用两条指令,就可以基于当前PC以任意偏移量转移控制流或者访问数据。

  • 将auipc(add upper immediate to pc)中的20位立即数与jalr(jump add link register)中12位立即数组合,我们就可以将执行流转移到任意32位PC相对地址。

  • 将auipc加上普通加载或存储指令中的12位立即数偏移量,我们就可以访问任何32位PC相对地址的数据。

  • RISC-V操作始终是以完整的寄存器宽度。内存访问需要的能量比算术运算高几个数量级,因此低宽度的数据访问可以节省大量的能量,但低宽度的运算不会。

  • RV32I提供了单独的移位指令,不包含乘法和除法,它们包含在可选的RV32M扩展中。

  • 即使处理器没有添加乘除法扩展,完整的RISC-V软件栈也可以运行,这可以缩小嵌入式芯片的面积。

RV32I的Load和Store

  • 除了提供32位字的lw,sw(load word,store word),如图2.1中说明,RV32I支持加载有符号和无符号字节和半字(lb、lbu、lh、lhu)和存储字节和半字(sb、sh)。有符号字节和半字符号扩展为32位再写入目的寄存器。
  • 即使是自然数据类型更窄,低位宽数据也会被扩展后再处理,这使得后续的整数计算指令能正确处理所有的32位。常用的无符号字节和半字,在写入目标寄存器之前都被无符号扩展到32位。
  • 加载和存储支持的唯一寻址模式是符号扩展12位立即数到基地址寄存器。
  • RV32I省略了复杂寻址模式。RV32I寻址不会歧视任何数据类型。
  • RISV-V没有特殊的堆栈指令。将31个寄存器中的某一个作为堆栈指针,标准寻址模式使用起来和压栈(push)和出栈(pop)类似。

RV32I条件分支

  • RV32I可以比较两个寄存器并根据比较结果进行分支跳转。比较可以是:相等beq(branch equal)、不相等(branch not equal)、大于等于bge(branch greater equal)、小于blt(branch less than)。最后两种是有符号比较,RV32I也提供相应的无符号版本比较:bgeu和bltu。
  • 剩下的两个比较关系(大于和小于等于)可以通过简单交换两个操作数,完成比较。
  • RISC-V指令长度必须是两个字节的倍数。
  • 分支指令的寻址方式是12位的立即数乘以2,符号扩展它,然后将得到的值加到PC上作为分支的跳转地址。

RV32I无条件跳转

  • 图2.1中的跳转并链接(jal)具有双重功能。若将下一条指令PC+4的地址保存到目标寄存器中,通常是返回地址寄存器ra(return adress),便可以用它来实现过程调用。
  • 如果使用零寄存器(x0)替换ra作为目标寄存器,则可以实现无条件跳转,因为x0不能更改。像分支跳转一样,jal将其20位分支地址乘以2,进行符号扩展后再添加到PC上,便到了跳转地址。
  • 跳转和链接指令的寄存器版本(jalr)同样是多用途的,它可以调用地址是动态计算出来的函数,或者也可以实现调用返回(ra作为源寄存器,零寄存器(x0)作为目的寄存器)。
  • switch和case语句的地址跳转,也可以使用jalr指令,目的寄存器设为x0.RV32I避开了错综复杂的程序调用指令。

RV32I杂项

  • 图2.1中的控制状态寄存器指令csrrc(control status register read & clear bit)、csrrs(control status register read & set bit)、csrrw(control status register read & write)、csrrci(control status register read & clear bit immediate)、csrrsi(control status register read and set bit immediate)、csrrwi
    (control status register read & write immediate),使我们可以轻松地访问一些程序性能计数器。
  • 对于这些64位计数器,我们一次可以读取32位。这些计数器包括了系统时间,时钟周期以及执行的指令数目。
  • 在RISC-V指令集中,ecall指令用于向运行时环境发出请求,例如系统调用。调试器使用ebreak指令将控制转移到调试环境。
  • fence指令:对外部可见的访存请求,如设备I/O和内存访问等进行串行化。
  • 外部可见指对处理器的其它核心、线程,外部设备或协处理器可见。fence.i指令:同步指令和数据流。

RV32I从RISC-I继承了如下特性:

  • 32位字节可寻址的地址空间
  • 所有指令均32位长
  • 31个寄存器,全部32位宽,寄存器0硬连线为0
  • 所有的操作都在寄存器之间(没有寄存器到内存的操作)
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【The RISC-V READER】中文版 v2.1 欢迎! RISC-V 自 2011 年推出以来迅速地普及。我们认为一个精简的程序员指南将进一步促进 它的发展,并促使新人理解为什么它是一个有吸引力的指令集,以及它与传统指令集架构 (ISA)的不同。 我们的灵感部分来源于其它指令集架构书籍,但我们希望 RISC-V 自身的简洁性能让我 们写得比 See MIPS Run 一类 500 多页的详尽书籍少很多。我们把全书的长度控制到了前述 的三分之一,至少在这个意义上我们成功了。实际上,介绍模块化 RISC-V 指令集的每个组 成部分的十章只用了 100 页——即便为了有助于快速阅读,平均每页用到了一张图片(一共 75 张)。 在解释指令集设计的原理之后,我们将阐述 RISC-V 架构师在设计指令集的时候,如何 在过去 40 年的指令集的基础上取其精华,去其糟粕。要评判一个指令集架构,不仅要看它 包括了什么,而且要看它省略了什么。 随后我们会按顺序介绍这个模块化架构的每个组成部分。每一章都会包含一个用 RISCV 汇编语言写成的程序,这是为了展示那一章所述的指令的用法,这样有助于汇编语言程序 员学习 RISC-V 汇编。有时,我们还会列出用 ARM,MIPS 和 x86 写成的同样的程序,从而 突出 RISC-V 在简洁性,以及成本、功耗、性能方面的优势。 为了增加本书的趣味性,我们在页边加入了将近 50 个侧边栏,这里面放了一些有关书 中内容的评论,希望它们能带来一些乐趣。我们还在页边放了大约 75 个图片,用于展示设 计良好 ISA 的例子。(我们充分利用了侧边的空间!)最后,对于那些愿意钻研的读者,我们 在全书中加入了大概 25 段补充说明。如果你对某个主题感兴趣,可以深入研究这些可选部 分。略过这些部分不会影响对书中的其他内容的理解,所以如果你对他们不感兴趣的话,尽 管跳过它们。对于计算机体系结构爱好者,我们援引的 25 篇论文和书籍能够开阔你的视野。 在写这本书的过程中,我们从它们当中学到了很多东西!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饼干饼干圆又圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值