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

ARM64架构macOS汇编调用C标准库函数链接失败求助

ARM64 macOS汇编调用C库puts函数链接失败问题解决

问题描述

使用Apple Silicon M4(ARM64架构)的macOS系统,编写汇编代码调用标准C库puts函数,代码如下:

.global main                                                        // 1 
main:                                                                   // 2 
    stp     x21, x30, [sp, -16]!    // push onto stack                  // 3 
    mov     x21, x1                 // argc -> x0, argv -> x1           // 4 

top:                                                                    // 6 
    ldr     x0, [x21], 8            // argv++, old value in x0          // 7 
    cbz     x0, bottom              // if *argv == NULL goto bottom     // 8 
    bl      puts                    // puts(*argv)                      // 9 
    b       top                     // goto top                         // 10 

bottom:                                                                 // 12 
    ldp     x21, x30, [sp], 16      // pop from stack                   // 13 
    mov     x0, xzr                 // return 0                         // 14 
    ret                                                                 // 15 

    .end                       

执行编译链接命令clang -lc -arch arm64 test2.s -e main时失败,错误信息:

Undefined symbols for architecture arm64:
  "puts", referenced from:
      main in test2-8965bb.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

尝试添加-lSystem参数仅收到重复库警告,问题未解决。

为验证C库可用性,编写对应C代码:

#include <stdio.h>

int main(){
  puts("Hello, World!");
  return 0;
}

编译生成的汇编代码可正常运行,其中调用C库函数的部分为bl _puts。

问题原因

macOS的C库符号遵循下划线前缀命名规则,所有标准C库函数的符号名实际是_函数名(比如puts对应符号_puts)。你编写的汇编代码中直接调用puts,链接器无法找到对应的符号,导致报错。

解决方法

1. 修改汇编代码中的函数调用

将汇编代码里的bl puts改为bl _puts,修改后的完整代码:

.global main                                                        // 1 
main:                                                                   // 2 
    stp     x21, x30, [sp, -16]!    // push onto stack                  // 3 
    mov     x21, x1                 // argc -> x0, argv -> x1           // 4 

top:                                                                    // 6 
    ldr     x0, [x21], 8            // argv++, old value in x0          // 7 
    cbz     x0, bottom              // if *argv == NULL goto bottom     // 8 
    bl      _puts                   // 修正为带下划线的符号名           // 9 
    b       top                     // goto top                         // 10 

bottom:                                                                 // 12 
    ldp     x21, x30, [sp], 16      // pop from stack                   // 13 
    mov     x0, xzr                 // return 0                         // 14 
    ret                                                                 // 15 

    .end                       

2. 简化编译命令

clang默认会自动链接System库(包含C库),且默认入口为main,因此无需添加-lc或-e main参数,直接执行:

clang -arch arm64 test2.s

运行生成的可执行文件a.out即可看到正确输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:03:14