如何在M1 Mac(ARM)上编译x86_64汇编代码?

6

我在大学修了编译器课程,其中涉及到制作基于纳米传递的编译器和创建传递步骤。因此,在此过程中有一步

gcc -g -std=c99 runtime.o tests/var_test_1.s

runtime.o是runtime.c文件的编译结果。

但我遇到了一个错误:

tests/var_test_1.s:3:12: error: unknown token in expression
 movq $42, %rax
           ^
tests/var_test_1.s:3:12: error: invalid operand
 movq $42, %rax
           ^
tests/var_test_1.s:4:2: error: unrecognized instruction mnemonic, did you mean: cmp?
 jmp _conclusion
 ^
tests/var_test_1.s:9:8: error: unknown token in expression
 pushq %rbp
       ^
tests/var_test_1.s:9:8: error: invalid operand
 pushq %rbp
       ^
tests/var_test_1.s:10:7: error: unknown token in expression
 movq %rsp, %rbp
      ^
tests/var_test_1.s:10:7: error: invalid operand
 movq %rsp, %rbp
      ^
tests/var_test_1.s:11:11: error: unknown token in expression
 subq $0, %rsp
          ^
tests/var_test_1.s:11:11: error: invalid operand
 subq $0, %rsp
          ^
tests/var_test_1.s:12:2: error: unrecognized instruction mnemonic, did you mean: cmp?
 jmp _start
 ^
tests/var_test_1.s:16:11: error: unknown token in expression
 addq $0, %rsp
          ^
tests/var_test_1.s:16:11: error: invalid operand
 addq $0, %rsp
          ^
tests/var_test_1.s:17:7: error: unknown token in expression
 popq %rbp
      ^
tests/var_test_1.s:17:7: error: invalid operand
 popq %rbp
      ^
tests/var_test_1.s:18:2: error: unrecognized instruction mnemonic, did you mean: eret, ret?
 retq
 ^

进一步阅读后,我发现这是因为M1 Mac采用ARM架构,无法直接编译x86_64汇编代码。 是否有任何标志或gcc的任何版本可用于在ARM架构上编译x86代码?
我已经看到了Rosetta和qemu,但我不想为这样的任务运行虚拟机。 qemu-static在M1上似乎并不那么简单。
以下是var_1_test.s的内容(此文件由仅支持x86的编译器生成[按照其性质])
    .align 16
_start:
    movq    $42, %rax
    jmp _conclusion

    .globl _main
    .align 16
_main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $0, %rsp
    jmp _start

    .align 16
_conclusion:
    addq    $0, %rsp
    popq    %rbp
    ret

如果需要更多详细信息,我很乐意提供。谢谢!

2
你需要一个交叉编译器。 - Paweł Łukasik
1
你不行。句号。 - Jake 'Alquimista' LEE
2
如果MacOS按照正常的主线clang构建方式构建,它将支持多个目标。例如:clang -target x86-64 -c foo.s应该可以组装。不过,不清楚是否能链接到可执行文件;这将需要跨链接器和可能需要库(如果您没有编写自己的_start并使用-nostdlib)。在MacOS上,如果您没有安装真正的GCC,则gcc命令实际上是clang,您可以从gcc --version中看到,但如果您正在使用针对clang的特定选项,则应将其作为clang调用。 - Peter Cordes
1个回答

5

在查阅了更多的 Stack Overflow 答案后(感谢 @paweł-Łukasik),通过交叉编译器这个术语,我得到了一个答案,即如何使用 Rosetta 2 在命令行界面上运行 x86 代码,或者说在 x86 架构上运行任何命令。

如何在 M1 MacBook 上使用 Rosetta 2 运行 Homebrew 安装程序

我对 makefile 做了改动,添加了 arch -x86_64 ...,然后其它所有部分都完美地运行了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接