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

Android NDK编译ARM64汇编程序遇_start重复及main未定义错误求助

ARM64汇编Hello World编译错误分析与解决

错误原因拆解

1. 重复符号_start错误

使用clang编译时,默认会链接标准C库的启动代码,这套代码中已经定义了程序入口符号_start。你的汇编代码中又手动定义了_start,导致链接器检测到重复符号冲突。

2. 未定义符号main错误

当你把_start改为start1后,标准C库的启动代码仍然会尝试调用程序的main函数作为入口(这是C程序的默认约定),但你的汇编代码中并没有定义main,因此链接器报未定义符号错误。

两种解决方案

方案一:不依赖标准C库,自定义完整入口

直接编写包含系统调用的独立汇编程序,编译时禁用标准库链接:

  1. 修正后的汇编代码(hello64bit.s):
.global _start

_start:
    // 系统调用:write(1, msg, len)
    mov     x0, #1          // 文件描述符:stdout
    ldr     x1, =msg        // 字符串地址
    ldr     x2, =len        // 字符串长度
    mov     x8, #64         // Android ARM64 系统调用号:write=64
    svc     #0              // 触发系统调用

    // 系统调用:exit(0)
    mov     x0, #0          // 退出码:0
    mov     x8, #93         // Android ARM64 系统调用号:exit=93
    svc     #0

msg:
    .ascii  "Hello, World!\n"
len = . - msg               // 计算字符串长度
  1. 正确编译命令:
./aarch64-linux-android27-clang -nostdlib -o hello64 hello64bit.s
  • -nostdlib:告诉编译器不链接标准C库及其启动代码,避免_start冲突
  • -o hello64:生成可执行文件(你之前写的hello64.o是目标文件,不是可执行程序)

方案二:适配标准C库的入口约定

将汇编程序的入口改为main,符合C程序的默认入口规则,无需禁用标准库:

  1. 修正后的汇编代码(hello64bit.s):
.global main

main:
    // 系统调用:write(1, msg, len)
    mov     x0, #1
    ldr     x1, =msg
    ldr     x2, =len
    mov     x8, #64
    svc     #0

    mov     x0, #0          // 返回0表示程序正常结束
    ret                     // 返回到标准库启动代码,完成退出

msg:
    .ascii  "Hello, World!\n"
len = . - msg
  1. 编译命令:
./aarch64-linux-android27-clang -o hello64 hello64bit.s

此时clang会自动链接标准C库的启动代码,它会调用你定义的main函数,最终完成程序退出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 13:40:04