You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64(Apple M1)汇编调用nanosleep触发SIGSYS错误解决

问题现象

在Apple M1(对应AArch64架构)平台编写汇编代码调用nanosleep系统调用时,进程被异常终止,触发SIGSYS信号,报错信息如下:

terminated by signal SIGSYS (Bad system call)

复现逻辑为:尝试将可正常运行的C代码中bl nanosleep的调用逻辑替换为直接系统调用实现,参考公开的32位ARM系统调用表,认为0x65是nanosleep对应的系统调用号,编写的完整汇编逻辑如下:

mov x0, 2
str x0, [sp, 56]
str xzr, [sp, 48]
ldr x0, [sp, 56]
str x0, [sp, 24]
ldr x0, [sp, 48]
str x0, [sp, 32]
add x0, sp, 24
mov x1, 0
mov x16, 0x65
svc 0x80
问题产生原因

触发SIGSYS错误的核心原因是系统调用的参考依据和平台约定完全不匹配,具体有两点:

  • 参考的系统调用表对应错误:查阅的是32位ARM EABI架构、ChromeOS系统的系统调用表,和Apple M1运行的macOS(Darwin内核)AArch64环境的系统调用号定义完全不兼容,0x65在macOS AArch64下根本不是nanosleep的有效调用号,内核识别到非法调用号就会发送SIGSYS终止进程。
  • 系统调用的触发规则不符合macOS平台要求:
    1. macOS AArch64的系统调用号按类型加固定偏移,BSD类系统调用需要在基础调用号上加0x2000000的类偏移,nanosleep属于BSD类系统调用,基础调用号是0x57,实际传入x16寄存器的正确值应该是0x2000057。
    2. 系统调用触发指令的约定不匹配:svc 0x80是32位类Unix平台的旧触发约定,macOS AArch64下触发系统调用只需要使用svc #0即可。
正确调用方法

直接触发原始系统调用的正确汇编片段

; 栈上分配16字节空间存放timespec结构体
sub sp, sp, #16
; 给timespec赋值:tv_sec=2(睡眠2秒),tv_nsec=0(0纳秒)
mov x9, #2
str x9, [sp]
str xzr, [sp, #8]
; 配置系统调用参数:x0指向timespec结构体,x1传0表示不需要存储剩余睡眠时长
mov x0, sp
mov x1, #0
; 写入正确的nanosleep系统调用号
mov x16, #0x2000057
; 触发系统调用
svc #0
; 回收栈空间
add sp, sp, #16

兼容性更好的实现方案

不推荐在用户态汇编代码里直接硬编码系统调用号,优先选择链接系统libc,直接通过bl _nanosleep调用libc封装好的nanosleep函数即可,这种方式不需要关心不同系统版本的调用号、调用约定变动,兼容性更强。

额外注意:macOS平台用户态直接发起原始系统调用时,需要严格遵守Darwin平台的调用约定,包括进入系统调用前的栈16字节对齐、参数寄存器的正确使用、返回值的错误码处理规则,否则即使调用号正确,也可能出现未知运行时错误。

内容的提问来源于stack exchange,提问作者jevoso5871

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 06:48:22