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

64位NASM汇编逻辑异常:rax非零时jz跳转仍触发问题求助

问题根源

你遇到的问题是64位汇编和32位汇编规则混用导致的,核心有两个错误点:

  1. 指令解码异常
    你声明了BITS 64生成64位指令,但大概率汇编的时候生成的是32位目标文件。cmp rax, 0是64位特有指令,在32位模式下会被错误解码为无效指令或者其他逻辑,导致ZF标志位判断错误。而cmp eax, 0的指令编码在32位和64位模式下完全一致,所以修改后判断逻辑正常。
  2. 系统调用接口混用
    int 0x80是32位Linux的标准系统调用接口,在64位环境下仅兼容处理32位参数:
  • 你用mov ecx, str_3传递字符串地址,相当于把64位地址截断为32位,大概率会触发无效地址错误,write系统调用会返回负数错误码写入rax寄存器
  • 你最后退出逻辑用了64位syscall指令,但是赋值rax=1,而64位下exit的系统调用号为60,1对应write系统调用,会导致程序退出逻辑异常

修复方案

你可以选择任意一种规则统一的方案:

方案1:完全使用32位汇编

  • 删除代码开头的BITS 64声明
  • 所有系统调用都用int 0x80实现,最后的退出逻辑也保持mov rax,1 + int 0x80即可
  • 汇编时指定32位格式:nasm -f elf32 你的文件名.asm,链接时也指定32位:ld -m elf_i386 你的文件名.o -o 输出文件名

方案2:完全使用64位汇编

  • 替换所有int 0x80调用为syscall,系统调用号对应为:write=1,exit=60
  • 64位syscall参数寄存器规则为:第1参数存rdi,第2存rsi,第3存rdx
  • 示例64位write调用写法:
; write(1, str_3, 15)
mov rax, 1
mov rdi, 1
mov rsi, str_3
mov rdx, 15
syscall
  • 最后的exit调用写法:
mov rax, 60
mov rdi, 0
syscall
  • 汇编时指定64位格式:nasm -f elf64 你的文件名.asm,链接时用默认64位规则即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:45:08