M2 Mac运行ARM64汇编Hello World时出现无效系统调用错误
Apple Silicon Mac上ARM64汇编Hello World运行报错解决
问题根源
Apple Silicon(M系列芯片)的macOS限制了用户态程序直接通过svc指令发起系统调用,这是苹果的安全机制导致的。直接使用svc #0或svc #0x80触发系统调用会被内核拦截,抛出"invalid system call"或"Bad system call"错误。
正确实现方式
通过调用libc提供的封装函数(而非直接系统调用)来实现Hello World,这是macOS上兼容且稳定的做法:
汇编代码(hello.s)
.global _main .align 4 _main: // 调用 write(1, msg, 13):向标准输出打印字符串 mov X0, #1 // 第一个参数:文件描述符1(stdout) adr X1, msg // 第二个参数:字符串地址 mov X2, #13 // 第三个参数:字符串长度("Hello World!\n"共13字节) bl _write // 跳转调用libc的write函数 // 调用 exit(0):正常退出程序 mov X0, #0 // 第一个参数:退出码0 bl _exit // 跳转调用libc的exit函数 .data msg: .ascii "Hello World!\n"
编译链接命令
方式1:手动汇编+链接
as -arch arm64 hello.s -o hello.o ld -o hello hello.o -lSystem -syslibroot $(xcrun -sdk macosx --show-sdk-path) -arch arm64
方式2:用Clang一键编译(更简便)
clang -arch arm64 hello.s -o hello
运行验证
./hello
输出:Hello World!
为什么之前的代码失败?
你之前的两段代码都直接使用svc指令发起系统调用,但Apple Silicon macOS的用户态环境不允许这种操作——系统调用必须通过libSystem库的封装函数来触发,这些函数会处理苹果专属的系统调用入口(如Mach traps或BSD系统调用的兼容层),同时确保libc的初始化流程正常执行。
另外,使用_start作为程序入口时,需要手动完成libc的初始化工作(如设置栈、初始化全局变量等),这会增加代码复杂度;而使用_main作为入口,链接器会自动添加libc的初始化代码,简化开发流程。
内容的提问来源于stack exchange,提问作者Salty4141
相关产品推荐
相关产品推荐

