C语言编译成RISC-V汇编代码后的执行步骤

本文介绍了RISC-V指令集架构,包括其32个通用寄存器的布局,如临时和保存寄存器的使用。RISC-V指令特点是定长32位,分为六种类型。接着详细讲解了存取、运算、堆栈和跳转指令,并通过C语言程序展示了对应的RISC-V汇编代码。
摘要由CSDN通过智能技术生成

引言

​ 本文在学习了x86和ARM6两种指令集架构之后,以ISA的寄存器、寻址方式、常用指令、堆栈操作等为基础,从程序员的角度介绍RISC-V指令集架构的基础工作流程。对一个指令集架构学习的流程一般分为两个部分:寄存器布局和指令集。

1. 寄存器布局

​ 与x86和ARM64不同的是,对于RV32I、RV64I、RV128I,RISC-V都定义了32个通用寄存器,名称以及用法如下图所示。

​ RISC-V软件将19个寄存器分为两组:x5-x7以及x28-x31是临时寄存器,在过程调用中不被被调用者保存;x8-x9以及x18-x27是保存寄存器,在过程调用中必须被保存。而x10-x17八个参数寄存器,用于传递参数或返回值,x1一个返回地址寄存器,用于返回到起始点。
请添加图片描述

2. 指令特点

​ 与x86和ARM64不同的是,RISC-V的指令是定长的,都为32位,且只有6种类型,这样做简化了指令解码。具体六种指令格式如下,其中,

  • R类型用于寄存器-寄存器操作;

  • I类型用于短立即数和访存load操作;

  • S类型用于访存store操作;

  • B类型用于条件跳转操作;

  • U类型用于长立即数;

  • J类型用于无条件跳转。

其中R、I、S和U类型是四种基础指令,B和J类型都只包含一条指令,具体指令格式如下:

请添加图片描述

3. 常用指令

​ 接下来介绍RISC-V中一些常用指令,后面将给出一个简单的C语言程序与其对应的RISC-V汇编语言伪代码。

3.1 存取指令

​ 内存和寄存器之间传输数据的指令,称为数据传输指令。

取双字

​ 取内存中的A[8]至寄存器x9,字节寻址8×8偏移地址为64

ld	x9, 64(x22)	//x22存放内存中数组的基址,偏移64,取出的数据A[8]存放至寄存器x9

存双字

​ 将寄存器x9中数据存至内存的A[12],字节寻址8×12偏移地址为96

sd	x9, 96(x22) 	//x22存放内存中数组的基址,偏移96,寄存器x9的数据存至A[12]

3.2 运算指令

立即数加法

addi	x22, x22,4				//x22 = x22 + 4

寄存器加法

add     x10,x5,x6				//x10=x5+x6,结果保存在x10中

3.3 堆栈指令

​ 在使用需要保存的寄存器时进行参数传递等操作时(例如x1用来保存函数的返回地址),需要先把寄存器的当前值换出到栈中保存,再用寄存器进行函数调用,调用结束后,换回寄存器的旧值。

​ RISC-V中,寄存器x2用来保存栈指针,别名也叫做sp。栈的增长方向是由高地址向低地址方向增长。

//例如现在需要将x1和x10两个寄存器的值保存在栈中
addi sp,sp,-16	//sp增长16位,用来保存x1和x10的旧值
sd x1,8(sp)		//保存x1的值
sd x10,0(sp)	//保存x10的值

ld x10,0(sp)	//恢复x10的值
ld x1,8(sp)		//恢复x1的值
addi sp,sp,16	//恢复栈针

3.4 跳转指令

无条件跳转

jalr x0, 0(x1) 	//返回x1存储的地址

jal x0, func	//跳转到函数func,返回地址保存在x1中

3.5 C语言与对应的RISC-V汇编语言

C语言程序

int g(int x)
{
	return x+3;
}
int f(int x)
{
	return g(x);
}
int main(void)
{
	return f(8)+1;
}

RISC-V汇编语言伪代码

g:
addi x10,x10,3  //x10=x10+3,传入的参数加3
jalr x0,0(x1)   //函数返回

f:
jal x1,g		//调用函数g
jalr x0,0(x1)	//返回

main:
addi sp,sp,-16	//sp增长16位,用来保存x1和x10的旧值
sd x1,8(sp)		//保存x1的值
sd x10,0(sp)	//保存x10的值
addi x10,x0,8	//x10=0+8,将立即数8放入寄存器x10中
jal x1,f		//调用函数f,返回地址存在x1	

addi x10,x10,1  //x10=x10+1,即f(8)+1
ld x10,0(sp)	//恢复x10的值
ld x1,8(sp)		//恢复x1的值
addi sp,sp,16	//恢复栈针
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值