前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >riscv:ra寄存器的设置与保存

riscv:ra寄存器的设置与保存

作者头像
灯珑LoGin
发布2024-04-01 08:40:34
1120
发布2024-04-01 08:40:34
举报
文章被收录于专栏:龙进的专栏龙进的专栏

今天在写DragonOS的进程切换代码的时候,对于ra寄存器的设置与保存有点疑惑,于是写这篇文章来分析一下。

探索过程

我编写了这样的一个C程序:

代码语言:javascript
复制
#include <stdio.h>

void b() {
  printf("b\n");
}

void a() {
  printf("a\n");
  b();
}

int main() {
  a();

  return 0;
}

接着使用以下命令编译:

代码语言:javascript
复制
riscv64-linux-musl-gcc -static -o a a.c

接着反汇编:

代码语言:javascript
复制
riscv64-linux-musl-objdump -D a > a.txt

于是得到了以下片段:

代码语言:javascript
复制
0000000000010216 <b>:
   10216:	1141                	addi	sp,sp,-16
   10218:	e406                	sd	ra,8(sp)
   1021a:	e022                	sd	s0,0(sp)
   1021c:	0800                	addi	s0,sp,16
   1021e:	67c5                	lui	a5,0x11
   10220:	23878513          	addi	a0,a5,568 # 11238 <__errno_location+0xa>
   10224:	228000ef          	jal	ra,1044c <puts>
   10228:	0001                	nop
   1022a:	60a2                	ld	ra,8(sp)
   1022c:	6402                	ld	s0,0(sp)
   1022e:	0141                	addi	sp,sp,16
   10230:	8082                	ret

0000000000010232 <a>:
   10232:	1141                	addi	sp,sp,-16
   10234:	e406                	sd	ra,8(sp)
   10236:	e022                	sd	s0,0(sp)
   10238:	0800                	addi	s0,sp,16
   1023a:	67c5                	lui	a5,0x11
   1023c:	24078513          	addi	a0,a5,576 # 11240 <__errno_location+0x12>
   10240:	20c000ef          	jal	ra,1044c <puts>
   10244:	fd3ff0ef          	jal	ra,10216 <b>
   10248:	0001                	nop
   1024a:	60a2                	ld	ra,8(sp)
   1024c:	6402                	ld	s0,0(sp)
   1024e:	0141                	addi	sp,sp,16
   10250:	8082                	ret

0000000000010252 <main>:
   10252:	1141                	addi	sp,sp,-16
   10254:	e406                	sd	ra,8(sp)
   10256:	e022                	sd	s0,0(sp)
   10258:	0800                	addi	s0,sp,16
   1025a:	fd9ff0ef          	jal	ra,10232 <a>
   1025e:	4781                	li	a5,0
   10260:	853e                	mv	a0,a5
   10262:	60a2                	ld	ra,8(sp)
   10264:	6402                	ld	s0,0(sp)
   10266:	0141                	addi	sp,sp,16
   10268:	8082                	ret

分析

可以看到:

  • main函数使用jal指令,跳转到函数a,并且设置了ra寄存器(这是jal指令的操作)。
  • 接着在函数a()内,首先把ra寄存器的值存储到栈上,然后开始执行其他操作。
  • 在函数a()将要返回的时候,从栈上取出ra的值,并设置到ra寄存器内,于是ret指令就能返回到main函数了。

因此,riscv是“调用者设置ra,被调用者保存ra到栈上”。

转载请注明来源:https://longjin666.cn/?p=1852(在新窗口中打开)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024年3月31日2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 探索过程
  • 分析
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档