Mac下x86_64架构汇编链接指针未对齐及地址错误解决问询
解决Mac下x86_64汇编链接时的指针未对齐与地址格式错误
问题现象
一段在Debian上可正常运行的x86_64汇编代码,在Mac上编译链接时出现两个问题:
- 链接器报错指针未对齐:
ld: warning: pointer not aligned at address 0x100003FA3 (_main + 7 from print.o) ld: unaligned pointer(s) for architecture x86_64
- 将
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
问题根源与解决要点
- Mach-O 64位地址限制:Mac的Mach-O格式不支持32位绝对地址,直接使用
mov rcx, msg1这种绝对寻址方式会导致链接错误,必须改用RIP相对寻址。添加default rel指令让NASM默认生成相对寻址代码,配合lea rsi, [rel msg1]即可正确获取数据段地址。 - 指针未对齐问题:原代码中绝对地址的重定位操作破坏了指令的对齐要求,改用相对寻址后,重定位方式改变,指令对齐恢复正常,解决了链接器的未对齐警告。
- 系统调用参数差异:Mac x86_64的系统调用参数寄存器与Linux不同,sys_write的第一个参数(文件描述符)需要放在
rdi而非rbx,修正后才能正确调用系统调用。
内容的提问来源于stack exchange,提问作者John554
相关产品推荐
相关产品推荐

