type
status
date
slug
summary
tags
category
icon
password

RISC-V指令集简略学习笔记

本文主要记录的是对riscv的学习笔记(什么废话)

ISA

Instruction Set Architecture,指令集架构,是硬件电路向上层软件程序提供的接口规范。其中包括了数据类型、寄存器、指令、寻址方法、中断处理等等。著名的ISA有x86、ARM、SPARC、MIPS、RISC-V等等。
notion image
IBM 360是第一台定义了指令集架构的机器(石头门也干了
好处就是上层开发不用关心硬件的内部逻辑。

CISC与RISC

Complex Instruction Set Computing:复杂指令集,指令数目多,程序长度短。x86就是一种复杂指令集
Reduced Instruction Set Computing:精简指令集,指令个数少,程序长度长。
RISC-V可以通俗理解为精简指令集的一个版本,最早是用于教学目的。(经典大学出神人

ISA的宽度

指的是CPU中通用寄存器的宽度,决定了寻址范围的大小。
值得注意的是,ISA的宽度与指令编码长度无关

RISC-V ISA的命名规范

RV+数字(字宽,bit为单位)+字母(指令集模块集合)
如:RV32IMA、RV64GC等(特定组合IMAFD⇒G,通用指令集)
notion image
notion image

通用寄存器

notion image
pc(程序指针寄存器)在risc-v的是非暴露的,并不能通过指令集访问。

HART

Hardware Thread,硬件线程,
notion image
HART的概念类似于“处理器上的虚拟机”,与具体的指令执行流一一对应,而和真实处理器核数无关。一般不讨论真实处理器个数,只讨论HART个数。

特权级别(Privileged level)

notion image
由上到下用户权限逐渐升高,不同的级别下有不同的一套寄存器,低级别不能够跨级别访问高级寄存器

内存管理与保护

notion image
M级别下下访问的都是实际地址,不支持虚拟地址访问。

异常&中断

notion image
异常:遇到异常之后会执行异常处理程序,执行完会回到原来出错的指令
中断:遇到中断之后会执行中断处理程序,执行完之后会跳转到原指令的下一个指令

RISC-V 汇编语言编程

一个完整的的RISC-V汇编程序由多条语句(statement)组成。每条语句由[label:][operation][comment]三个部分组成(支持缺项,三个都缺就是空行)。
[label:]:任何以冒号结尾的都会被认为是标号,相当于是给地址起了个名字
[comment]:注释,以#开始的内容都会在程序执行时被忽略
[operation]:
instruction:指令,直接对应二进制字符串。
pseudo-instruction:伪指令,汇编器会将其翻译成多条实际指令。(提高编写效率)
directive:指示,以’.’开头,控制汇编器产生代码的方式等,不与实际指令相对应。不属于risc-v指令集的一部分,只与汇编器有关
macro:采用.macro/.endm自定义的宏(两个语句夹着的就是一个宏定义)

指令操作对象

寄存器:通用寄存器(RV32I对应的寄存器)共有32个,以x0~x31编号,其中x0不可写,读取时值恒为零,其他寄存器均可读可写,在RV架构上,Hart在执行算术运算和逻辑运算时,所操作的数据必须直接来自于寄存器
内存:Hart可以执行寄存器和内存之间的数据读写操作,读写操作使用字节(Byte)为单位进行寻址。

指令编码格式

notion image
不同类型的type对应不同的field划分。
不同的指令格式(format):R-Register、I-Immediate、S-Store、B-Branch、U-Upper、J-Jump
funct3/7的含义是对应的function占用3/7个bit位
notion image
查表:inst[1:0]代表这个域的第一和第零位始终唯一,在此基础上,结合横纵的数据确定具体的opcode,如10 011 11代表NMADD指令,在RISC-V手册中就有所有指令对应的编码格式与指令对照表。
小端序排列,较小的地址位于右侧
notion image
感觉这个东西只要规定好了就无所谓吧qwq

指令编写与应用

先放一个网上扒的程序在这里……

栈&堆

notion image
notion image
和学C语言时候的堆栈没啥区别,不如说实际上堆、栈的定义和使用啥语言本来就无关(什么爸爸像儿子
栈区的管理是由程序自动进行的,函数结束就会把栈帧回收,栈区不算太大,如果递归调用太多或者函数内声明太多变量啥的就会爆栈(stackoverflow)在栈区的变量叫自动变量,不需要人为维护
堆区是程序运行时用于动态分配内存的区域。它在程序的生命周期内可以动态地分配和释放内存,适用于需要在运行时确定大小的数据结构。堆区在 RISC-V 编程中与其他架构中的作用相同,主要用于管理动态内存分配。

内存布局

典型的程序内存布局如下:
堆区位于栈区和 BSS 段之间,随着内存的动态分配和释放,堆区的大小可以动态变化。初始化过的全局变量啥的位于读写数据段(.data段)

示例代码

以下是一个简单的示例,展示了如何在 RISC-V 编程中使用堆区进行动态内存分配:
在这个示例中,malloc 函数用于在堆区动态分配一个整数数组,free 函数用于释放已分配的内存。

函数调用约定

函数调用时,所使用到的调用参数、返回地址、返回的参数或数据信息由谁声明、存储或管理,需要有Caller和Callee的约定。
  • 有关寄存器的编程约定
notion image
  • 有关函数跳转和返回指令的编程约定
notion image
  • 有关被调用函数实现方式的编程约定
notion image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
编译技术学习-词法分析LLVM IR学习笔记
Loading...
XiaoYi
XiaoYi
一个摆烂电兵⚡
Announcement

🧑‍🦽冲刺!冲刺!冲! 🧑‍🦽

🌈 欢迎光临我的博客!