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

AArch64 Mach-O汇编:如何将标签定义放入.bss段并获取符号地址到寄存器

Mach-O AArch64 汇编中正确使用.bss段缓冲区的方法

问题原因

你遇到的「unknown AArch64 fixup kind」错误,根源在于adr指令的特性限制:它只能生成相对于当前指令的PC相对偏移地址,仅能访问和当前代码(.text段)处于同一加载区域的符号。而Mach-O的.bss段是独立的零初始化数据段,和.text段不在同一内存区域,因此adr无法正确解析buffer的地址,导致链接时出现修复错误。

解决方案

在Mach-O AArch64环境下,需要使用支持跨段访问的地址加载方式,推荐两种可行方法:

方法1:使用ldr指令加载绝对地址

直接用ldr X1, =buffer加载.bss段中buffer的绝对地址,汇编器会自动处理地址重定位逻辑:

.global _start
.align 8

_start: mov X0, #0
        ldr X1, =buffer  // 替换原有的adr指令
        mov X2, #128
        mov X8, #63      // AArch64 macOS系统调用号:read
        svc #0

        mov X0, #1
        mov X2, #5       // 注:此处固定输出5字节,实际可改用read的返回值(存于X0)作为输出长度
        mov X8, #64      // AArch64 macOS系统调用号:write
        svc #0

        mov X0, #0
        mov X8, #93      // AArch64 macOS系统调用号:exit
        svc #0

.section .bss
.align 8                // 建议给bss段的buffer添加对齐,符合AArch64内存规范
buffer: .skip 128

方法2:使用adrp + add组合(AArch64大地址访问标准方式)

adrp加载符号所在页面的基地址,再通过add补充页内偏移,适合大地址空间场景:

.global _start
.align 8

_start: mov X0, #0
        adrp X1, buffer
        add X1, X1, :lo12:buffer  // 组合加载完整的buffer地址
        mov X2, #128
        mov X8, #63
        svc #0

        // 后续write、exit代码与上方示例一致

额外注意事项

  • 你提供的编译命令存在笔误:as as -g hello.s应改为as -g hello.s -o hello.o,修正后的完整编译命令:
    as -g hello.s -o hello.o && ld -o hello.exec hello.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64
    
  • 当前代码中write的输出长度固定为5字节,若要完全实现print(input())的逻辑,可利用read系统调用的返回值(存储在X0寄存器中)作为动态输出长度,避免截断或冗余输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:16:00