【ARM64 常见汇编指令学习 23 -- ARMv8/v9 出入栈介绍】


请阅读【嵌入式开发学习必备专栏 】


ARMv8/v9 出入栈举例

实现一个 C函数调用汇编函数A,然后汇编函数A先进行入栈然后再去读取寄存器MPIDR_EL1的值到X0中最后再进行出栈操作再ret

为了实现这个需求,我们需要创建一个 C 函数,它将调用一个汇编函数 a。汇编函数 a 将执行以下步骤:

  1. 保存必要的寄存器(入栈)。
  2. 读取 MPIDR_EL1 寄存器的值。
  3. 将读取的值移动到 X0 寄存器中。
  4. 恢复保存的寄存器(出栈)。
  5. 返回到 C 函数。

首先,我们定义 C 函数原型:

然后,我们编写对应的汇编函数 a

.global call_asm_function_a 
.text 

call_asm_function_a: 
	// 步骤1: 入栈操作,保存callee-saved寄存器(例如 X29, X30) 
	STP X29, X30, [SP, #-16]! 
	MOV X29, SP // 设置帧指针 

	// 步骤2: 读取MPIDR_EL1寄存器的值 
	MRS X0, MPIDR_EL1 

	// 步骤3: 将读取的值已经在X0中 

	// 步骤4: 出栈操作,恢复callee-saved寄存器 
	LDP X29, X30, [SP], #16 
	
	// 步骤5: 返回到C函数 
	RET 

在 C 代码中,你可以这样调用 call_asm_function_a 函数:

#include <stdio.h>
 #include <stdint.h> 

// 函数原型声明 
uint64_t call_asm_function_a(void); 

int main(void) 
{ 
	uint64_t mpidr_value = call_asm_function_a(); 
	printf("MPIDR_EL1 value: 0x%llx\n", mpidr_value); 

	return 0; 
} 

在此代码中:

  • 使用 STP 指令将链接寄存器 LRX30)和帧指针 FPX29)压栈,并更新栈指针 SP
  • 使用 MRS 指令从 MPIDR_EL1 读取值到 X0 寄存器中。
  • 使用 LDP 指令恢复 LRFP 的值,并更新 SP
  • 最后,使用 RET 指令返回到 C 函数中。

请注意,上面的汇编代码应该与 C 代码在同一个项目中编译,以确保链接时可以正确解析 call_asm_function_a 函数的符号。此外,对于特定系统寄存器的访问可能需要特定的权限,因此这段代码应该在一个有权限的执行环境中运行。

  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主公CodingCos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值