求助:如何在Aarch64汇编中实现符合指定C接口的_syscall系统调用处理函数
解决Aarch64通用系统调用包装函数的实现问题
我来帮你搞定这个Aarch64汇编的_syscall函数,先理清楚核心逻辑和你之前踩的坑:
首先看你参考的x86代码,它的作用是通用系统调用入口:把第一个函数参数作为系统调用号,调整后续参数到系统调用要求的寄存器,触发syscall后直接返回结果(错误码会转为正数返回)。要移植到Aarch64,得先对齐两个架构的规则:
Aarch64关键规则
- 函数调用约定:前7个参数依次存在
x0(num)、x1(a0)、x2(a1)、x3(a2)、x4(a3)、x5(a4)、x6(a5) - 系统调用规则:系统调用号必须放到
x8,系统调用的参数依次用x0-x5(对应你的a0到a5) - 错误处理:系统调用返回错误时,
x0会是负数(值为-errno),我们需要把它转为正数返回(和x86逻辑一致)
正确的Aarch64汇编实现
.globl _syscall _syscall: // 1. 将函数第一个参数(系统调用号x0)移到系统调用号寄存器x8 mov x8, x0 // 2. 把函数参数映射到系统调用的参数寄存器 mov x0, x1 // 函数的a0 → 系统调用参数x0 mov x1, x2 // 函数的a1 → 系统调用参数x1 mov x2, x3 // 函数的a2 → 系统调用参数x2 mov x3, x4 // 函数的a3 → 系统调用参数x3 mov x4, x5 // 函数的a4 → 系统调用参数x4 mov x5, x6 // 函数的a5 → 系统调用参数x5 // 3. 触发系统调用 svc #0 // 4. 处理错误返回:如果x0是-1到-4095(标准errno范围),转为正数 cmn x0, #(4095 + 1) // 等价于检查 x0 >= -4095 cneg x0, x0, hi // 满足条件则将x0取反(-errno → errno) // 5. 返回结果 ret
你之前代码的问题说明
- 寄存器名称错误:Aarch64没有
r7这种寄存器,64位寄存器都是x0-x31,你要访问的函数第一个参数是x0,不是r7 - 参数映射缺失:你只把系统调用号放到了
x8,但没把后续的函数参数(a0-a5)映射到系统调用要求的x0-x5寄存器,导致系统调用拿到的参数完全错误 - 错误处理的逻辑是对的,但前提是参数传递正确,所以之前的代码无法正常工作
这个实现完全匹配你定义的C函数接口,和x86版本的功能完全一致,直接编译使用就可以了。
内容的提问来源于stack exchange,提问作者Achmed
相关产品推荐
相关产品推荐

