Mac平台汇编程序访问.data节字符串字面量地址异常问题
解决macOS上汇编程序调试时寄存器地址不匹配的问题
嘿,我来帮你捋清楚这个问题——这本质上是macOS的**地址空间随机化(ASLR)**加上Mach-O二进制的寻址特性在搞鬼!
问题根源
你用ld链接生成的可执行文件,macOS默认会启用ASLR:每次程序运行时,整个二进制都会被加载到随机的虚拟内存基地址上。你提到的string_1位于0x2000,这个地址其实是**__DATA段的偏移地址**(相对于段起始的位置),而不是程序运行时的实际虚拟地址。
当你写mov r12, string_2时,nasm在fmacho64格式下,会把string_2的偏移值(而非实际运行时的虚拟地址)直接塞进r12寄存器里。但程序实际加载时,所有数据的地址都是「基地址 + 偏移值」,所以你看到r12里的地址自然和实际的string_2地址对不上。
解决方法
要正确获取运行时的实际地址,你需要用PC相对寻址来计算——因为PC(程序计数器)的偏移是固定的,不受ASLR影响。修改你的汇编代码:
global start section .text start: lea r12, [rel string_2] ; 用lea + rel前缀实现PC相对寻址 section .data string_1: db 'string one',0 string_2: db 'string two',0
验证调试结果
重新汇编链接:
nasm -fmacho64 -o string.o ./string.x64 && ld -o string ./string.o
用lldb调试时:
- 设置断点:
breakpoint set --name start - 运行程序:
run - 查看r12寄存器:
register read r12 - 验证内存内容:
memory read --size 1 --format c $r12
这时候你会看到r12里的地址就是string_2的实际运行时地址,内存里的内容也会是string two。
额外小技巧
如果你想手动计算实际地址,也可以在lldb里用image list查看程序的加载基地址,然后把基地址加上string_2的偏移(比如string_1在0x2000,string_2的偏移就是0x2009,因为"string one"是9个字符加终止符),相加后就是实际地址。
内容的提问来源于stack exchange,提问作者Drew
相关产品推荐
相关产品推荐

