RISC-V基础知识
文章平均质量分 76
D了一天bug忘了编译
欢迎交流!
展开
-
RISC-V基础之浮点指令(包含实例)
例如,FMV.X.W指令将一个单精度浮点数从浮点寄存器移动到整数寄存器,FMV.W.X指令将一个32位整数从整数寄存器移动到浮点寄存器。- 浮点比较指令:用来在浮点寄存器之间进行浮点数的相等、小于、小于等于等比较,并将布尔结果记录在整数寄存器中。例如,FCVT.S.D指令将一个双精度浮点数转换为一个单精度浮点数,FCVT.W.S指令将一个单精度浮点数转换为一个32位整数。例如,FLW指令从内存加载一个单精度浮点数到浮点寄存器,FSW指令将一个单精度浮点数从浮点寄存器存储到内存。原创 2023-08-04 16:03:45 · 3441 阅读 · 3 评论 -
RISC-V基础之内存分布与映射
RISC-V要求sp保持16字节对齐,这意味着sp的值必须是16的倍数。因此,sp每次减少16的倍数来为栈腾出空间,即使需要更少的栈空间也是如此。例如,如果一个函数需要在栈上分配8个字节的空间,那么sp就要减少16个字节,而不是8个字节。RISC-V要求sp保持16字节对齐,以便与RISC-V基础指令集RV128I兼容,它可以操作128位(即16字节)的数据。因此,sp每次减少16的倍数来为栈腾出空间,即使需要更少的栈空间也是如此。内存映射是指将地址空间划分为不同的部分或段,每个段有不同的用途和属性。原创 2023-08-04 15:28:46 · 1525 阅读 · 0 评论 -
RISC-V基础之函数调用(五)函数递归调用及函数参数数量溢出(超出现有寄存器个数)约定(包含实例)
第一次调用恢复 n(到 t1)为 3,恢复 ra,调用者的返回地址,释放栈帧,并返回 a0 = 3 × 2 = 6。当阶乘返回到调用者时,栈指针在它的原始位置(0xFF0),栈指针以上的栈内容没有改变,并且所有的保留寄存器保持它们的原始值。另外,在函数调用过程中如果一个RISC-V函数需要的参数超过了八个寄存器,即a0到a7,那么它应该按照标准调用约定的规则,将多余的参数通过堆栈(stack)传递。例如,如果一个函数需要10个整数参数,那么它可以将前八个参数放在寄存器a0到a7中,将后两个参数压入堆栈中。原创 2023-08-04 15:01:28 · 1525 阅读 · 0 评论 -
RISC-V基础之函数调用(四)非叶函数调用(包含实例)
一个优化的编译器可以观察到 f2 是一个叶过程,并可以将 r 分配给一个非易失性寄存器,避免了保存和恢复 s4 的需要。在调用 f2 之前,f1 将 a0 和 a1 保存到栈中,以遵循调用者保存规则,因为这些是非易失性寄存器,f2 可能会改变它们,而 f1 在调用后仍然需要它们。一般来说,被调用函数需要保护非易失性寄存器的值,即在使用之前将其压入栈中,在返回之前将其弹出栈中。叶函数是指不调用其他函数,也不改变任何非易失性寄存器的函数2。非叶函数是指调用其他函数的函数,叶函数是指不调用其他函数的函数。原创 2023-08-04 14:44:29 · 677 阅读 · 0 评论 -
RISC-V基础之函数调用(三)保留寄存器(包含实例)
非保留寄存器,也称为临时寄存器,是指在函数调用中可以自由修改的寄存器,不需要保存和恢复。函数调用时,如果一个函数需要修改保留寄存器的值,那么它必须在修改前将它们保存到堆栈上,并在返回前将它们从堆栈上恢复。而如果一个函数只修改非保留寄存器的值,那么它就不需要保存和恢复它们,因为调用者不会再使用它们。如果一个函数需要修改保留寄存器的值,那么它必须在修改前将它们保存到堆栈上,并在返回前将它们从堆栈上恢复。而如果一个函数只修改非保留寄存器的值,那么它就不需要保存和恢复它们,因为调用者不会再使用它们。原创 2023-08-03 20:01:56 · 1689 阅读 · 0 评论 -
RISC-V基础之函数调用(二)栈与寄存器(包含实例)
在函数结束时,diffofsums从堆栈上恢复这些寄存器的值,释放它的堆栈空间,并返回。堆栈指针sp(寄存器2)是一个普通的RISC-V寄存器,按照惯例,指向堆栈的顶部。函数调用时,为了避免函数修改除了a0之外的其他寄存器的值,造成主程序的寄存器内容被破坏,需要在函数执行前将需要修改的寄存器的值保存到堆栈上,然后在函数返回前将它们从堆栈上恢复。上图代码示例展示了一个改进的diffofsums函数,它在修改t0,t1和s3寄存器之前将它们保存到堆栈上,并在返回前将它们从堆栈上恢复。原创 2023-08-03 19:53:01 · 2836 阅读 · 0 评论 -
RISC-V基础之函数调用(一)简单的函数调用(包含实例)
主函数通过执行jal simple来调用simple函数,这个指令做了两件事:它跳转到目标指令的地址,即simple所在的地址(0x0000051C),并且把返回地址,即jal后面的指令的地址(在这个例子中是0x00000304)存储在返回地址寄存器(ra)中。在RISC-V程序中,惯例是调用者在进行函数调用前将最多八个参数放在寄存器a0到a7中,而被调用者在完成前将返回值放在寄存器a0中。RISC-V的约定是,函数使用a0到a7这八个寄存器来传递输入参数,其中a0是最左边的参数,a7是最右边的参数。原创 2023-08-03 19:45:59 · 2689 阅读 · 0 评论 -
RISC-V基础指令之shift移动指令slli、srli、srai、sll、srl、sra
其中,opcode是指令的操作码,rd是目的寄存器,funct3是功能码,rs1和rs2是源寄存器,funct7是扩展功能码。不同的shift指令有不同的功能码和扩展功能码。其中,opcode是指令的操作码,rd是目的寄存器,funct3是功能码,rs1是源寄存器,imm是立即数。RISC-V的shift指令是用于对一个寄存器或一个立即数进行位移运算,并将结果存放在另一个寄存器中的指令。这些shift指令都有两种格式,一种是I-Format,用于对一个寄存器和一个立即数进行位移运算;原创 2023-08-03 17:05:14 · 13250 阅读 · 0 评论 -
RISC-V基础指令之逻辑指令 and、or、xor、not
其中,opcode是指令的操作码,rd是目的寄存器,funct3是功能码,rs1和rs2是源寄存器,funct7是扩展功能码。xor指令的funct3是0100000,funct7是0000000。其中,opcode是指令的操作码,rd是目的寄存器,funct3是功能码,rs1是源寄存器,imm是立即数。RISC-V的逻辑指令是用于对两个寄存器或一个寄存器和一个立即数进行按位的逻辑运算,并将结果存放在另一个寄存器中的指令。按位的逻辑运算就是把两个操作数的每一位分别进行相应的逻辑运算,得到一个新的位。原创 2023-08-03 16:51:46 · 3055 阅读 · 0 评论 -
RISC-V基础指令之lw和sw(包含使用说明及实例)
LW和SW指令是用于加载和存储字(word)的指令,一个字是32位(4个字节)的数据。SW指令将一个寄存器中的字写入内存中。用于结构体成员的访问:如果结构体成员是一个字,那么可以用LW和SW指令来读取或修改结构体成员。用于函数参数和返回值的传递:如果函数参数或返回值是一个字,那么可以用LW和SW指令来传递它们。用于数组元素的访问:如果数组元素是一个字,那么可以用LW和SW指令来读取或修改数组元素。可以看到,它们的opcode、funct3、rs1和imm都有不同的值,而rs2只在SW指令中有意义。原创 2023-08-03 16:30:07 · 21971 阅读 · 5 评论 -
RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)
但是,如果我们想要生成一个32位的立即数0x1234F678,我们就不能用上面的方法了。lui指令的全称是Load Upper Immediate,它的功能是把一个20位的立即数加载到寄存器的高20位,低12位为0。注意这里要理解好补码的意义,负数的补码,是能够和其相反数相加通过溢出从而使计算机内计算结果变为0的二进制码,所以之前的地方采取了+1的操作。addi指令的全称是Add Immediate,它的功能是把一个寄存器的值和一个12位的立即数相加,并把结果存入另一个寄存器。对补码更详细介绍转至。原创 2023-08-03 16:12:34 · 15074 阅读 · 5 评论