macOS 64位NASM两数相加代码:编译调试异常问题问询
问题分析与修复方案
嘿,我仔细看了你的macOS 64位NASM汇编代码和调试情况,核心问题出在没正确读取变量的数值,还有一些细节需要调整。下面一步步帮你搞定:
1. 最关键的错误:变量读取方式错了
你用dw定义了16位的x和y,但直接写mov rax, x是把变量的内存地址塞进rax,而不是变量里存的10这个值!要读取变量的实际数值,得用内存寻址[x],还要考虑16位值适配64位寄存器的问题——用movzx(零扩展)把16位值安全加载到64位寄存器里,避免出现截断或符号问题。
2. 修复后的完整代码
section .data x dw 10 ; 16位变量,存数值10 y dw 10 section .text global _main _main: ; 先清空rax,再读取x的数值并零扩展到64位 xor rax, rax movzx rax, word [x] ; 用word指定操作数大小,读取x的16位值到rax ; 同样处理y,加载到rbx xor rbx, rbx movzx rbx, word [y] ; 两数相加,结果存在rax里 add rax, rbx ; 这里可以留个nop方便断点调试 result: nop exit: mov rax, 0x2000001 ; macOS 64位的exit系统调用号,你这部分是对的 mov rdi, 0 ; 退出码0表示程序正常结束 syscall
3. 编译调试的正确操作
你的编译命令nasm -f macho64 hello.asm和gcc -m64 hello.o -o hello是没问题的。调试时程序停下来,大概率是你之前在result标签处设了断点(这是正常的),你可以在lldb里这么操作看结果:
- 启动程序:
r - 程序停住后,输入
register read rax查看寄存器值,此时应该显示0x0000000000000014,也就是十进制的20,正好是10+10的结果 - 想让程序正常退出就输入
c继续执行
4. 额外小提示
- macOS 64位的系统调用都要加
0x2000000前缀,所以exit是0x2000001,你这部分没写错 - 如果以后用32位变量(
dd),可以用mov eax, [x],然后rax会自动零扩展(或者直接mov rax, [x]也可以) - 调试时如果没设断点程序却停了,那可以检查下有没有其他内存访问错误,但你现在的问题主要是变量读取的问题
内容的提问来源于stack exchange,提问作者Pavel Perevezencev
相关产品推荐
相关产品推荐

