RISC-V64位/32位提供了32个整型通用寄存器,编号是x0~x31,这些整型通用寄存器的宽度与架构位数一致。
浮点数寄存器与整形寄存器一样也提供了32个:f0~f31,位数与架构位数一致。
x0/zero
x0寄存器又被称为zero寄存器,它的读写是无效的,它的值只能为0,这是为了让编译器进行优化
比如当进行一些运算时:
add x1, x2 , x3
上面这段汇编的作用是进行相加运算,将x2和x3寄存器的值相加的结果并放入x1寄存器,但是如果x3寄存器的值为0
处理器仍然需要去读取一次x3寄存器的值,所以编译器可以进行这样的优化:
add x1, x2, x0
当RISC-V处理器执行这条指令的时不会去读取x0寄存器的值,会直接按0来运算,这样就可以省去与0做运算时读取的步骤。
RISC-V处理器在设计时只要涉及到x0寄存器的读取一律按0来处理不会去读取x0的寄存器,这么做的目的是为了方便编译器优化某些运算。
x1/ra
x1寄存器也称为RA寄存器,意为Return Address。当一个函数被调用时,RA寄存器会被自动保存下来,以便在函数执行完毕后能够返回调用该函数的位置。因此,在函数执行过程中,RA寄存器也可以被用来存储函数的返回地址。它也时常被用来函数传参。
x2/sp
通常用于存储栈指针(stack pointer)。在RISC-V中,栈是一种先进后出(Last-In-First-Out)的数据结构,常用于函数调用时的变量保存和程序现场保护等操作。
x3/gp
x3寄存器是RISC-V架构中的通用寄存器之一,通常用于存储全局指针(global pointer)。在RISC-V中,全局指针是一个特殊的指针,指向全局变量和静态数据区(static data region)的起始地址。
全局变量是在程序启动时就已经被分配好的变量,它们通常存储在静态数据区中,其内存地址在编译时就已经确定。全局指针GP通常指向静态数据区的起始地址,用于访问和管理全局变量。
x4/tp
x4寄存器是RISC-V架构中的通用寄存器之一,通常用于存储线程指针(thread pointer),也称为线程局部存储器指针(thread-local storage pointer)。
在线程级别的编程中,线程指针是一个非常重要的概念。它是一个指针,指向当前线程的局部存储器(thread-local storage),也就是线程私有的数据区域。在多线程编程中,每个线程都有自己独立的线程指针,并且可以在其对应的局部存储器中存储和管理线程私有的数据。
x5/t0、x6/t1、x7/t2、x28/t3、x29/t4、x30/t5、x31/t6
这些寄存器是一个临时寄存器,通常用于临时存储计算中的中间结果或临时变量。
x8/ra
x8是一个通用寄存器,主要用于存储数据和地址。
x8通常被称为ra寄存器,它有一个特殊的作用,即用于存储函数返回地址,因此也被称为返回寄存器。在函数调用时,调用者将函数返回地址压入栈中,然后调用函数时将返回地址存储在ra寄存器中,函数执行完毕后再从ra寄存器中取出返回地址并跳转回调用者。X8寄存器还可以被用作普通的通用寄存器,存储数据和地址。
x9/s1
x9寄存器是RISC-V CPU的一个通用寄存器,通常被称为s1(scratch register 1)。
由于RISC-V代码遵循RISC(Reduced Instruction Set Computing,精简指令集计算机)原则,所以寄存器数量比较有限,因此x9寄存器通常被用作一个通用寄存器,多种指令都会使用到它,比如函数调用时用于保存函数调用者的栈指针,或者作为全局指针等。除此之外,x9寄存器也可以用于实现一些特殊指令的优化,比如乘法指令的高32位运算或者计算指令的中间结果等。
x18/s2
它的作用是用于执行指令时暂存临时数据,比如保存函数调用时的参数、局部变量等等。由于它是一个特殊寄存器,因此在CPU中还有一些特殊的用途。
x18寄存器还可以用于执行一些特殊操作,比如RISC-V CPU中的原子操作。原子操作需要在保证操作的原子性的同时,还需要快速地完成,因此x18寄存器就成了很好的选择。此外,x18寄存器还可以用于实现一些编译器优化,比如进行指令选取、指令调度等等。因此,x18寄存器可以看做是一个非常重要的寄存器,在程序运行过程中扮演着举足轻重的角色。
x19/s3、x20/s4、x21/s6、x22/s7、x24/s8、x25/s9、x26/s10、x27/s11
这些寄存器可以用来存储临时变量或者函数参数等数据。在函数调用时,这些寄存器通常被用来存储调用者保存的寄存器、返回地址或者参数值,具体使用方式取决于编程语言规范和系统调用规范。
x10/a0
x10 寄存器通常被称为 a0 寄存器,在程序中,a0寄存器通常被用于存储函数的输入参数,也可以用于存储函数的返回值。当函数被调用时,输入参数的值被加载到a0寄存器中,并通过函数调用将参数传递给被调用的函数。被调用的函数可以将返回值存储在a0寄存器中,并通过函数调用返回给调用方。
x11/a1、x12/a2、x13/a3、x14/a4、x15/a5、x16/a6、x17/a7
x11 ~ x17用于传递函数参数,从x11到x17分别对应函数第一个参数和第七个参数