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

Mac下x86_64架构汇编链接指针未对齐及地址错误解决问询

解决Mac下x86_64汇编链接时的指针未对齐与地址格式错误

问题现象

一段在Debian上可正常运行的x86_64汇编代码,在Mac上编译链接时出现两个问题:

  1. 链接器报错指针未对齐:
ld: warning: pointer not aligned at address 0x100003FA3 (_main + 7 from print.o)
ld: unaligned pointer(s) for architecture x86_64 
  1. 将mov指令改为lea尝试解决时,NASM报错:
error: Mach-O 64-bit format does not support 32-bit absolute addresses

进一步发现:mov rcx, msg1之后添加任何指令(包括nop)都会触发链接器的指针未对齐错误,注释掉后续的call _print则报错消失。

原错误代码

bits 64

section .text
    global  _main                               ;must be declared for linker (ld)
    global  _print

_print:
    mov     rbx, 1                              ;file descriptor (stdout)
    mov     rax, 0x4                            ;system call number (sys_write)
    bts     rax, 25
    syscall
    ret

_main:
    mov     rdx, len1
    mov     rcx, msg1
    call    _print                              ;will not compile if this is not commented out

    ; <any instruction between mov rcx, msg1 and mov rax, 0x2000001
    ; causes LD to throw a pointer misalignment error
    ; ld: warning: pointer not aligned at address 0x100003FA3 (_main + 7 from print.o)
    ; ld: unaligned pointer(s) for architecture x86_64

    mov   rax, 0x2000001                ; system call 0x1 with 0x2000000 offset
    mov   rbx, 0x0                  ; set the exit code to be 0x0
    syscall

section .data
    msg1    db 'here 1', 0xa
    len1    equ $ - msg1
    msg2    db 'here 2', 0xa
    len2    equ $ - msg2
    msg3    db 'here 3', 0xa
    len3    equ $ - msg3
    msg4    db 'here 4', 0xa
    len4    equ $ - msg4
    msg5    db 'here 5', 0xa
    len5    equ $ - msg5

编译链接命令

nasm -f macho64 print.asm
ld -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem print.o -o print

可运行的修正代码

添加default rel启用默认相对寻址,改用RIP相对方式获取数据地址,并修正系统调用的参数寄存器:

bits 64

default rel

section .text
    global  _main                               ;must be declared for linker (ld)
    global  _print

_print:
    mov     rdi, 1                              ;file descriptor (stdout)
    mov     rax, 0x4                            ;system call number (sys_write)
    bts     rax, 25
    syscall
    ret

_main:
    lea     rsi, [rel msg1]
    lea     rdx, [rel len1]
    call    _print

    nop
    nop
    nop

    mov   rax, 0x2000001                ; system call 0x1 with 0x2000000 offset
    mov   rbx, 0x0                    ; set the exit code to be 0x0
    syscall

section .data
    msg1    db 'here 1', 0xa
    len1    equ $ - msg1
    msg2    db 'here 2', 0xa
    len2    equ $ - msg2
    msg3    db 'here 3', 0xa
    len3    equ $ - msg3
    msg4    db 'here 4', 0xa
    len4    equ $ - msg4
    msg5    db 'here 5', 0xa
    len5    equ $ - msg5

相关工具输出

objdump -dx 错误输出

print:  file format mach-o 64-bit x86-64
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: 'print': Invalid/Unsupported object file format

objdump -d 反汇编输出

print:  file format mach-o 64-bit x86-64

Disassembly of section __TEXT,__text:

0000000100003f83 <_print>:
100003f83: bf 01 00 00 00               movl    $1, %edi
100003f88: b8 04 00 00 00               movl    $4, %eax
100003f8d: 48 0f ba e8 19               btsq    $25, %rax
100003f92: 0f 05                        syscall
100003f94: c3                           retq

0000000100003f95 <_main>:
100003f95: 48 8d 35 64 00 00 00         leaq    100(%rip), %rsi         ## 0x100004000 <msg1>
100003f9c: 48 8d 14 25 07 00 00 00      leaq    7, %rdx
100003fa4: e8 da ff ff ff               callq   0x100003f83 <_print>
100003fa9: 90                           nop
100003faa: 90                           nop
100003fab: 90                           nop
100003fac: b8 01 00 00 02               movl    $33554433, %eax         ## imm = 0x2000001
100003fb1: bb 00 00 00 00               movl    $0, %ebx
100003fb6: 0f 05                        syscall

otool -dtvr print.o 输出

% otool -dtvr print.o      
test.o:
Relocation information (__TEXT,__text) 1 entries
address  pcrel length extern type    scattered symbolnum/value
0000000f False quad   True   UNSIGND False     msg1
(__TEXT,__text) section
_print:
0000000000000000    movl    $0x1, %edi
0000000000000005    movl    $0x2000004, %eax                ## imm = 0x2000004
000000000000000a    syscall
000000000000000c    retq
_main:
000000000000000d    movabsq $0x0, %rsi
0000000000000017    movl    $0x7, %edx
000000000000001c    callq   0x0
0000000000000021    movl    $0x2000001, %eax                ## imm = 0x2000001
0000000000000026    movl    $0x0, %ebx
000000000000002b    syscall
(__DATA,__data) section
000000000000002d    68 65 72 65 20 31 0a 68 65 72 65 20 32 0a 68 65 
000000000000003d    72 65 20 33 0a 68 65 72 65 20 34 0a 68 65 72 65 
000000000000004d    20 35 0a 

问题根源与解决要点

  1. Mach-O 64位地址限制:Mac的Mach-O格式不支持32位绝对地址,直接使用mov rcx, msg1这种绝对寻址方式会导致链接错误,必须改用RIP相对寻址。添加default rel指令让NASM默认生成相对寻址代码,配合lea rsi, [rel msg1]即可正确获取数据段地址。
  2. 指针未对齐问题:原代码中绝对地址的重定位操作破坏了指令的对齐要求,改用相对寻址后,重定位方式改变,指令对齐恢复正常,解决了链接器的未对齐警告。
  3. 系统调用参数差异:Mac x86_64的系统调用参数寄存器与Linux不同,sys_write的第一个参数(文件描述符)需要放在rdi而非rbx,修正后才能正确调用系统调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:03:36