RISC-V 指令集介绍

1. 背景介绍

        指令集从本质上可以分为复杂指令集(Complex Instruction Set Computer,CISC)和精简指令集(Reduced Instruction Set Computer,RISC)两种。复杂指令集的特点是能够在一条指令内完成很多事情。

        指令架构(Instruction Set Architecture, 缩写为ISA),是软件和硬件的接口,不同的应用需求,会有不同的指令架构。

        RISC-V的不同寻常之处在于:和几乎所有以往的ISA不同,它是模块化的。它的核心是一个名为RV32I的基础ISA,运行一个完整的软件栈。RV32I是固定的,永远不会改变。这为编译器编写者,操作系统开发人员和汇 编语言程序员提供了稳定的目标。模块化来源于可选的标准扩展,根据应用程序的需要, 硬件可以包含或不包含这些扩展。这种模块化特性使得RISC-V具有了袖珍化、低能耗的特点。

2. RISC-V指令格式

常见的RISC-V指令集如下表所示:

基本指令集含义
RV32I32位整数指令集
RV32E

RV32I的子集,用于小型嵌入式场景

RV64I64位整数指令集,兼容RV32I
RV128I128位整数指令集,兼容RV64I和RV32I

RISC-V有六种基本指令格式

  • R-type:用于寄存器-寄存器操作
  • I-type:用于短立即数和访存 load 操作
  • S-type:用于访存 store 操作
  • B-type:用于条件跳转操作
  • U-type:用于长立即数
  • J-type:用于无条件跳转

        指令只有6种格式,并且所有指令都是32位长,指令的低7位固定为opcode,简化了指令解码。在RISC-V中对于所有指令,要读写的寄存器的标识符总是在同一位置,意味着在解码指令之前,就可以先开始访问寄存器,这些格式的立即数字段总是符号扩展,符号位总是在指令中最高位,各种类型的指令构成如下图所示:

字段含义:

  • opcode(操作码):指令的基本操作,这个缩写是它惯用名称。
  • rd:目的操作寄存器,用来存放操作结果。
  • funct3:一个另外的操作码字段。
  • rs1:第一个源操作数寄存器。
  • rs2:第二个源操作数寄存器。
  • funct7:一个另外的操作码字段。
  • imm:立即数


2.1. R型指令

32bit R型指令包括6个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • rd (Destination Register)是目的寄存器,位宽5bit,在指令的7-11bit;
  • funct3+funct7是两个操作字段。funct3占了3bit,funct7占了7bit;
  • rs1 (Source Register 1)是第一个源操作数寄存器,位宽5bit,在指令的15-19bit;
  • rs2 (Source Register 2)是第二个源操作数寄存器,位宽5bit,在指令的25-31bit。

R型指令构成如下:

R型的全部指令(RV32I)

R型指令包括加法、减法、逻辑运算、移位运算。

示例:
add a0, a1, a2  //a0 = a1 + a2
sub a0, a1, a2  //a0 = a1 - a2
sll a0, a1, a2  //a0 = a1 << a2(低位补0)
srl a0, a1, a2  //a0 = a1 >> a2(高位补0)
sra a0, a1, a2  //a0 = a1 >> a2 (算术右移,高位补原来的符号位)
slt a0, a1, a2  //a1 < a2 ? a0 = 1 : a0 = 0
xor a0, a1, a2  //a0 = a1 ^ a2
or  a0, a1, a2  //a0 = a1 | a2
and a0, a1, a2  //a0 = a1 & a2

2.2. I型指令

I型指令包括5个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • rd (Destination Register)是目的寄存器,位宽5bit,在指令的7-11bit;
  • funct3是操作字段。funct3占了3bit,在指令的12-14bit;
  • rs1 (Source Register 1)是第一个源操作数寄存器,占了5bit,在指令的15-19bit;
  • 存放12位的立即数——imm[11:0],在指令的20-31bit。

I型指令构成如下:

I型的全部指令(RV32I)

I型指令包括立即数的运算和load指令。 

示例:
addi a0, a1, 0x5  //a0 = a1 + 0x5
subi a0, a1, 0x05  //a0 = a1 - 0x05
slli a0, a1, 0x05  //a0 = a1 << 0x05(低位补0)
srli a0, a1, 0x05  //a0 = a1 >> 0x05(高位补0)
srai a0, a1, 0x05  //a0 = a1 >> 0x05 (算术右移,高位补原来的符号位)
slti a0, a1, 0x05  //a1 < 0x05 ? a0 = 1 : a0 = 0
xori a0, a1, 0x05  //a0 = a1 ^ 0x05
ori a0, a1, 0x05   //a0 = a1 | 0x05
andi a0, a1, 0x05  //a0 = a1 & 0x05

示例:
lb x10,  0(x1)  //将x1的值加上0,将这个值作为地址, 取出这个地址所对应的内存中的值, 将这个值赋值给x10(取出的是8位数值)
lh x10,  0(x1)  //从内存中取出16位数值
lw x10, 0(x1)  //从内存中取出32位数值
lbu x10, 0(x1) //从内存中取出8位无符号数值
lhu x10, 0(x1) //从内存中取出16位无符号数值

2.3. S型指令

S型指令包括6个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • imm[4:0]+imm[11:5];
  • funct3是操作字段。funct3占了3bit,在指令的12-14bit;
  • rs1 (Source Register 1)是第一个源操作数寄存器,占了5bit,在指令的15-19bit;
  • rs2 (Source Register 2)是第二个源操作数寄存器,占了5bit,在指令的25-31bit。

S型指令构成如下:

S型的全部指令(RV32I)

S型指令包括store指令。 

示例:
sb  x10, 0(x1)  //x1的值加上0,将这个值作为地址, 将x10的值存储到上述地址所对应的内存中去 (只会将x10的值的低8位写入)
sh  x10, 0(x1)  //只会将x10的值的低16位写入
sw  x10, 0(x1)  //只会将x10的值的低32位写入

2.4. B型指令

B型指令包括6个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • imm[4:1]+imm[11]+imm[10:5]+imm[12];(注:imm[0]被丢弃,因为它始终为零)
  • funct3是操作字段。funct3占了3bit,在指令的12-14bit;
  • rs1 (Source Register 1)是第一个源操作数寄存器,占了5bit,在指令的15-19bit;
  • rs2 (Source Register 2)是第二个源操作数寄存器,占了5bit,在指令的25-31bit。

B型指令构成如下:

B型的全部指令(RV32I)

B型指令包括条件跳转指令。 

示例:
beq a1,a2,Label   //if(a1==a2){goto Label;}
bne a1,a2,Label   //if(a1!=a2){goto Label;}
blt a1,a2,Label   //if(a1< a2){goto Label;}
bgt a1,a2,Label   //if(a1> a2){goto Label;}
bge a1,a2,Label   //if(a1<=a2){goto Label;}
ble a1,a2,Label   //if(a1>=a2){goto Label;}

2.5. U型指令

U型指令包括3个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • rd (Destination Register)是目的寄存器,占了5bit,在指令的7-11bit;
  • imm[31:12]:存放高20位的立即数——imm[31:12],在指令的12-31bit。

U型指令构成如下:

U型的全部指令(RV32I)

示例:
lui  x10, 0x65432 //得到立即数的高20位,低位补0,立即数范围为:0x00~0xFFFFF

2.6. J型指令

J型指令包括3个部分:

  • opcode是操作码,位宽7bit,在指令的0-6bit;
  • rd (Destination Register)是目的寄存器,占了5bit,在指令的7-11bit;
  • 立即数划分:imm[19:12]+imm[11]+imm[10:1]+imm[20]:

J型指令构成如下:

J型的全部指令(RV32I)

示例:
jal ra, symbol    // 跳转到Symbol中去, 并把ra设置成返回地址 Symbol 可以是自定义的Label ,也可以是某个函数名
jal ra, 100       // 跳转到pc + 100 * 2的地方中去, 并把ra设置成返回地址  pc相对寻址,对应的是位置无关代码(PIC)
jalr ra, 40(x10)  // 跳转到x10+40 的地方中去, 并把ra设置成返回地址x10+40必须是绝对地址,指向内存中某个确定的地方(往往是函数的开头),非PIC

3. 通用寄存器

RV32I有32个通用寄存器,以及一个PC寄存器。其中有一个通过硬件设置的值恒为 0 的 x0 寄存器

注:RISC-V的32个寄存器x0~x31是用0~31这些数字来表示。


参考文档、博客:

RISC-V官方文档

riscv指令集基础_konghhhhh的博客-CSDN博客

计算机系统基础(五)之RISC-V指令集_riscv指令集_深度学习的学习僧的博客-CSDN博客

RISC-V指令集_riscv指令集_点灯大师~的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/19870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云安全攻防(四)之 云原生技术

云原生技术 容器技术 容器与虚拟化 虚拟化&#xff08;Virtualization&#xff09;和容器&#xff08;Container&#xff09;都是系统虚拟化的实现技术&#xff0c;可实现系统资源的”一虚多“共享。容器技术可以理解成一种”轻量的虚拟化“方式&#xff0c;此处的”轻量“主…

安全加固服务器

根据以下的内容来加固一台Linux服务器的安全。 首先是限制连续密码错误的登录次数&#xff0c;由于RHEL8之后都不再使用pam_tally.so和pam_tally2.so&#xff0c;而是pam_faillock.so 首先进入/usr/lib64/security/中查看有什么模块&#xff0c;确认有pam_faillock.so 因为只…

UG\NX 二次开发 相切面、相邻面的选择控件

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan 简介&#xff1a; 有群友问“UFUN多选功能过滤面不能选择相切面或相邻面之类的吗&#xff1f;” 这个用Block UI的"面收集器"就可以&#xff0c;ufun函数是不行的。 效果&am…

js 模块化

js 模块化 模块化主要是用来抽离公共代码&#xff0c;隔离作用域&#xff0c;避免变量冲突等。 模块化的整个发展历史如下&#xff1a; IIFE&#xff1a;使用自执行函数来编写模块化&#xff0c;特点&#xff1a;在一个单独的函数作用域中执行代码&#xff0c;避免代码冲突。…

18 个JS优化技巧,可以解决 90% 的屎山代码!!!

文章目录 18 个JS优化技巧&#xff0c;可以解决 90% 的屎山代码&#xff01;&#xff01;&#xff01;1.箭头函数2.解构赋值变量3.使用模版字面量进行字符拼接4.使用展开运算符进行数组和对象操作5.简化循环6.简化判断7.使用对象解构和默认参数简化函数参数8.使用函数式编程概念…

Debeizum 增量快照

在Debeizum1.6版本发布之后&#xff0c;成功推出了Incremental Snapshot&#xff08;增量快照&#xff09;的功能&#xff0c;同时取代了原有的实验性的Parallel Snapshot&#xff08;并行快照&#xff09;。在本篇博客中&#xff0c;我将介绍全新快照方式的原理&#xff0c;以…

HTML+CSS+JavaScript:实现B站评论发布效果

一、需求 1、用户输入内容&#xff0c;输入框左下角实时显示输入字数 2、为避免用户输入时在内容左右两端误按多余的空格&#xff0c;在发送评论时&#xff0c;检测用户输入的内容左右两端是否带有空格&#xff0c;若有空格&#xff0c;发布时自动取消左右两端的空格 3、若用…

浏览器的同源策略 - 跨域问题

1.什么是跨域 跨域问题的实质是浏览器的同源策略造成的。浏览器同源策略是浏览器为 JavaScript 施加的限制。简单点说就是非同源会出现如下等限制&#xff1a; 无法访问其他源下的网页的 Cookies&#xff0c;Storage等&#xff1b;无法访问其他源下的DOM对象和 JS 对象;无法使…

uni iOS 消息推送扩展:实现离线语音播报

文章目录 引言I 前期准备1.1 配置扩展1.2 测试报文II iOS Extension(扩展)2.1 插件作者配置2.2 插件使用者配置see also引言 HBuilderX3.1.5+版本uni原生插件支持iOS Extension(扩展)。 消息推送离线语音播报插件获取方式: 公z号:iOS逆向: 离线包x10, 源码是x15。 实…

java环境搭建 Ubuntu Linux

jdk的安装和配置环境变量 使用apt sudo apt install default-jdk若是安装成功了在终端输入java -version来查看是否安装成功 使用官网下载的jdk包 直接在百度上搜索jdk&#xff0c;选择图片这个 网址:jdk下载网址 若是arm就选择带有arm的&#xff0c;反之选择x64的&#…

[SQL挖掘机] - 窗口函数 - 聚合函数类

在 sql 中&#xff0c;sum、count、avg等函数是常见的聚合函数&#xff0c;它们用于计算结果集中某个列的总和、计数和平均值。而使用这些聚合函数作为窗口函数时&#xff0c;它们会对窗口内的行进行计算&#xff0c;并返回结果作为每一行的一个列。 下面是一些常用的聚合类窗…

vscode 通过mongoose 连接mongodb atlas

了解mongodb 的项目结构 1.代表集群名称 > 2.代表数据库名称>3.代表每个 collection名称 三者范围为从大到小的关系 &#xff08;一对多&#xff09;。每个集群有不同的连接地址、用户信息&#xff08;Database Access&#xff09;、ip配置信息&#xff08;Network Acce…

51单片机(普中HC6800-EM3 V3.0)实验例程软件分析 实验一 点亮第一个LED

目录 前言 一、原理图及知识点介绍 1.1、LED原理图 1.2、MCU51原理图 二、代码分析 知识点一&#xff1a;#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 知识点二&#xff1a;你知道sfr P0 0x80;是怎么来的呢为什么要赋值0x80&#xff…

Firewall,iptablesl放火墙的使用

Firewall放火墙的使用 1.查看当前防火墙运行状态&#xff1a; firewall-cmd --state systemctl start firewalld.service 开启防火墙 systemctl stop firewalld.service 关闭防火墙 systemctl disable firewalld.service 彻底关闭防火墙&#xff0c;开机不启动 systemctl ena…

C语言二维数组指针有关内容

定义一个a指针指向二维数组&#xff0c;则 表示形式含义a&#xff1a;表示二维数组名&#xff0c;即二维数组首地址a、a[0]、&#xff08;a0&#xff09;:0行0列元素的地址a1、&a[1]:一行起始地址a[1]、*(a1):1行0列元素的地址a[1]2、*(a1)2、&a[1][2]:1行2列元素的地…

vxworks文件系统分析

参考https://www.freebuf.com/articles/endpoint/335030.html 测试固件 https://service.tp-link.com.cn/detail_download_7989.html 固件提取 binwalk解压固件&#xff0c;在第一部分即为要分析的二进制文件&#xff0c;可以拖进ida分析 设置为arm小端字节序&#xff0c;点…

数组中出现次数超过一半的数字——剑指 Offer 39

文章目录 题目描述法一 哈希表法二 摩尔投票 题目描述 法一 哈希表 使用哈希映射&#xff08;HashMap&#xff09;来存储每个元素以及出现的次数。对于哈希映射中的每个键值对&#xff0c;键表示一个元素&#xff0c;值表示该元素出现的次数。 class Solution { public:int maj…

Web与HTTP

目录 DNS与域名 DNS解析的方式 过程 注册域名 html 名词解释 html的语法 web web2.0 静态页面特点 动态页面 动态页面特点 http协议 工作流程 http的请求方式 get post 状态码 常用状态码 通信套接字 套接字调用的端口 DNS与域名 网络是基于tcp/ip协议进…

java中的字符流

使用字节流读取中文的时候&#xff0c;如果使用的编码是GBK&#xff0c;则占用2个字节&#xff1b;如果使用UTF-8编码&#xff0c;则占用3个字节&#xff0c;意味着我们读取中文文档的时候如果每次读取1个字节&#xff0c;那么输出的将会是乱码&#xff0c;因为是不完整的中文。…

面试攻略,Java 基础面试 100 问(六)

JAVA 泛型 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许程序员在编译时检测到非法的类型。泛型的本 质是参数化类型&#xff0c;也就是说所操作的数据类型被指定为一个参数。比如我们要写一个排序方法&#xff0c; 能够对整型数组、字符串数组甚至其他任何类型的…