M1芯片macOS编译x86_64汇编文件报错求解决方案
在M1芯片macOS上解决acwj 04_Assembly章节的汇编编译问题及QEMU运行方案
一、解决汇编编译链接错误的方案
方案1:利用Rosetta 2转译x86_64编译链
M1芯片的macOS支持通过Rosetta 2运行x86_64架构程序,直接调用x86_64版本的clang编译生成的x86_64汇编:
arch -x86_64 cc -o out out.s
编译完成后直接执行./out即可,系统会自动通过Rosetta转译运行x86_64可执行文件。
方案2:使用x86_64-elf-gcc时跳过标准库链接
你安装的x86_64-elf-gcc是面向裸机/嵌入式环境的工具链,默认不包含系统标准库(crt0.o、libc)。而acwj 04章节生成的汇编代码逻辑简单,完全不需要依赖标准库,因此添加-nostdlib参数跳过标准库链接即可:
x86_64-elf-gcc -nostdlib -o out out.s
生成的是x86_64 ELF格式可执行文件,需要用QEMU模拟运行。
方案3:修改代码生成ARM64架构汇编
如果想直接生成适配M1的ARM64汇编,可修改项目中的gen.c文件,将原x86_64汇编指令替换为ARM64指令:
- 替换x86_64寄存器(如
%eax、%ebx)为ARM64通用寄存器(如w0、w1) - 替换栈操作指令(
pushl、popl)为ARM64的栈操作(str、ldr,配合sp寄存器) - 调整系统调用逻辑:macOS下ARM64的系统调用使用
svc #0,exit的系统调用号为1,与x86_64不同
修改后重新编译编译器,生成的out.s就是ARM64架构的,直接用系统cc编译即可运行。
二、用QEMU运行x86_64代码的可行性
完全可以用QEMU运行x86_64代码,分两种场景:
- 针对
x86_64-elf-gcc生成的ELF格式可执行文件,直接用QEMU x86_64模拟器运行:qemu-x86_64 out - 针对Rosetta编译的x86_64 Mach-O格式可执行文件,需指定对应架构的库路径运行:
qemu-x86_64 -L /usr/local/x86_64-apple-darwin23 ./out
(注:/usr/local/x86_64-apple-darwin23需根据你的Rosetta环境实际库路径调整)
内容的提问来源于stack exchange,提问作者ge1mina023
相关产品推荐
相关产品推荐

