手写RISC-V处理器--基础篇之指令集

发布时间 2023-09-09 22:17:12作者: TomYoung

RISC-V(发音为"risk-five")是一个基于开放标准的指令集架构(ISA),其设计目的是提供一个开放、灵活和可扩展的计算机体系结构,可以用于各种用途,从嵌入式系统到超级计算机。RISC-V定义了一系列不同类型的指令格式,以支持各种计算机操作和数据处理任务。

指令格式类型

R-Type(寄存器类型)

这种指令格式用于操作寄存器中的数据,如加法、减法、逻辑运算等。
通常包括操作码(opcode)、源寄存器(rs1和rs2)、目标寄存器(rd)、功能码(funct3和funct7)等字段。
例如,add rd, rs1, rs2 是一个典型的R-Type指令,用于将rs1和rs2中的值相加,并将结果存储在rd中。

I-Type(立即数类型)

这种指令格式用于对寄存器中的数据执行操作,并使用立即数(immediate value)作为操作数之一。
通常包括操作码(opcode)、源寄存器(rs1)、目标寄存器(rd)、立即数(imm)等字段。
例如,addi rd, rs1, imm 用于将rs1中的值与立即数imm相加,并将结果存储在rd中。

S-Type(存储类型)

这种指令格式用于将一个寄存器的值存储到内存中,或者从内存中加载一个值到寄存器中。
通常包括操作码(opcode)、源寄存器(rs1和rs2)、偏移量(imm)等字段。
例如,sw rs2, imm(rs1) 用于将rs2的值存储到rs1 + imm地址的内存位置。

B-Type(分支类型)

这种指令格式用于条件分支操作,根据条件是否满足来跳转到不同的地址。
通常包括操作码(opcode)、两个源寄存器(rs1和rs2)、分支目标地址的偏移量(imm)以及条件码(例如,等于、不等于等)等字段。
例如,beq rs1, rs2, imm 表示如果rs1等于rs2,则跳转到当前指令地址加上imm的目标地址。

U-Type(上界类型)

这种指令格式用于加载一个大的立即数(20位或32位)到寄存器中,通常用于初始化。
通常包括操作码(opcode)和目标寄存器(rd)等字段。
例如,lui rd, imm 用于将imm左移12位后的结果加载到rd中。

J-Type(跳转类型)

这种指令格式用于无条件跳转或者跳转到一个计算出的地址。
通常包括操作码(opcode)和跳转目标地址的偏移量(imm)等字段。
例如,jal imm 表示无条件跳转到当前指令地址加上imm的目标地址,并将返回地址存储在寄存器中。
这些是RISC-V指令集架构中常见的指令格式类型。RISC-V还支持扩展,以添加额外的指令格式,以满足不同的计算需求。不同的指令格式提供了灵活性和性能优势,使RISC-V能够适应各种应用和场景。

指令结构

处理器译码阶段,就是对取得的指令根据结构解析出正确的指令,为后面的执行做准备。

寄存器

通用寄存器


ABI

ABI(Application Binary Interface)定义了一组规则和约定,用于不同编译器和库之间的二进制兼容性,以及程序与操作系统之间的交互。通用寄存器是ABI的一部分,因为它们定义了程序如何在寄存器中传递参数、保存返回值以及进行函数调用的约定。

调用约定(Calling Convention):ABI规定了函数调用的方式,包括如何传递参数、在哪些寄存器中保存参数、如何保存和恢复寄存器的状态以及如何返回函数的结果。这些规则确保不同编译器生成的代码能够正确地协同工作。

通用寄存器用途(General-Purpose Register Usage):ABI通常规定哪些通用寄存器用于存储参数、局部变量、临时数据和其他数据。这确保了不同函数之间的数据共享和互操作性。

栈(Stack):ABI定义了栈的使用方式,包括如何在栈上分配和释放内存、如何在函数调用期间保存和恢复寄存器状态,以及如何处理函数调用的返回地址。

返回值寄存器(Return Value Registers):ABI规定了哪些寄存器用于存储函数的返回值。通常,RISC-V ABI规定使用一组通用寄存器来保存返回值。

处理和系统调用(Exception Handling and System Calls):ABI还规定了处理异常(例如,硬件中断或软件异常)和进行系统调用时的寄存器使用方式和约定。

调用者保存和被调用者保存寄存器(Caller-Saved and Callee-Saved Registers):ABI可以定义哪些通用寄存器由调用者保存(caller-saved),即在函数调用前要保存和在函数调用后要还原的寄存器,以及哪些由被调用者保存(callee-saved),即函数内部需要保存和恢复的寄存器。