MacOS Apple Silicon下arm64汇编实现sleep/delay及指令错误修复求助
在Apple Silicon(ARM64)Mac汇编中实现0.1秒睡眠(10FPS)
错误原因分析
你遇到的指令错误是因为mov x8, xzr, [sp, -0x10]!是非法的ARM64指令——ARM64的mov不支持同时完成寄存器赋值和栈指针调整的操作,栈调整需要单独执行或者通过stp/ldp类指令附带完成。
另外需要明确:wait4是用于等待子进程状态的系统调用,和睡眠功能无关,你找错了系统调用接口,应该用nanosleep来实现精确睡眠。
正确的Nanosleep汇编实现
以下是实现0.1秒(100,000,000纳秒)睡眠的完整ARM64汇编代码,适配Apple Silicon Mac:
.global _main .align 4 _main: // 调整栈空间,保存帧指针和返回地址(ARM64函数调用规范要求) stp x29, x30, [sp, #-0x20]! mov x29, sp // 在栈上分配timespec结构体空间(8字节tv_sec + 8字节tv_nsec) // 设置睡眠时长:0秒 + 100,000,000纳秒 = 0.1秒 mov x0, sp // x0指向timespec结构体的地址 mov w1, #0 str w1, [x0] // 写入tv_sec = 0 mov x1, #100000000 str x1, [x0, #8] // 写入tv_nsec = 100000000 // 调用nanosleep系统调用 mov x8, #0x23 // MacOS ARM64上nanosleep的系统调用号是0x23 mov x1, #0 // 第二个参数传NULL,忽略剩余未睡眠的时间 svc #0x80 // 触发系统调用 // 恢复栈和寄存器,退出程序 ldp x29, x30, [sp], #0x20 mov x0, #0 // 程序返回码0 mov x8, #0x1 // exit系统调用号 svc #0x80
关键细节说明
- 系统调用号:MacOS ARM64的
nanosleep系统调用号为0x23,可通过xnu源码中的syscall_sw.h文件确认。 - 参数传递规则:ARM64 MacOS系统调用中,
x0-x7用于传递参数,x8存储系统调用号,通过svc #0x80触发系统调用执行。 - timespec结构体:必须按
tv_sec(秒数,4字节或8字节,此处用8字节适配ARM64)、tv_nsec(纳秒数,8字节)的顺序在栈上存储。
编译运行
使用clang编译并运行:
clang -o sleep_demo sleep_demo.s ./sleep_demo
程序运行后会等待0.1秒再退出,完全满足10FPS的帧间隔需求。
内容的提问来源于stack exchange,提问作者masteronin99
相关产品推荐
相关产品推荐

