Mac平台NASM编写x64汇编程序时64位模式全局数据32位地址错误
解决Mac x64 NASM汇编中「64位模式下全局数据的32位地址」错误
嘿,我来帮你搞定这个问题!你遇到的错误其实是Mac x64 Mach-O环境下汇编的两个常见坑导致的,咱们一步步拆解解决:
问题根源
- 没给全局变量找对“家”:你代码里用了
myVar但根本没在数据段声明它,NASM不知道这个变量的长度和地址空间,默认会尝试用32位地址来访问,这在64位模式下肯定冲突。 - Mac寻址规则的特殊性:在64位Mach-O格式中,访问全局变量必须用RIP相对寻址或者明确的64位寻址方式,直接写
[myVar]会触发32位地址的错误,因为NASM默认的寻址逻辑在这个场景下不兼容Mac的要求。
修正后的完整代码
global start ; 先给全局变量开辟数据段空间 section .data myVar dq 0 ; 定义一个8字节(64位)的全局变量,初始值设为0 section .text start: mov r10, 3 ; 把3存到r10寄存器 mov r9, 4 ; 把4存到r9寄存器 mov rax, r10 ; 将r10的值移到rax(mul指令要求被乘数必须在rax里) mul r9 ; 执行rax*r9,结果的低64位会存在rax中 mov r9, rax ; 把计算结果从rax移到r9 mov [myVar], r9 ; 将结果存入全局变量myVar(现在有了正确的64位定义,NASM会生成合法的寻址) mov r11, [myVar] ; 从myVar里把结果读回r11寄存器 mov rdi, r11 ; 将结果作为exit系统调用的返回参数(Mac的exit调用用rdi传返回值) mov rax, 0x02000001 ; Mac x64平台的exit系统调用编号 syscall ; 触发系统调用,结束程序
几个关键的修正细节
- 补上
.data段和变量定义:用dq(双四字,对应64位)声明myVar,确保变量宽度和x64寄存器匹配,这样NASM就知道该用64位地址访问它了。 - 完善系统调用逻辑:你的原代码最后少了
syscall指令,程序没法正常退出,我帮你补上了,而且修正了注释里的小错误(exit的参数是存在rdi里,不是rax)。
Mac上的编译运行步骤
用NASM编译成Mach-O目标文件,再用ld链接执行:
nasm -f macho64 your_program.asm -o your_program.o ld -macosx_version_min 10.15 your_program.o -o your_program ./your_program # 执行完用 echo $? 查看退出码,应该是12(也就是3*4的结果)
内容的提问来源于stack exchange,提问作者Drew
相关产品推荐
相关产品推荐

