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

NASM汇编命令行传参打开文件失败求助:sys_open调用异常

Troubleshooting sys_open Failure with Command-Line Arguments in NASM

嘿,我之前也踩过这个一模一样的坑!当硬编码文件名能正常运行,但命令行传参就触发sys_open失败,返回0xffffffffffffffffe(也就是64位下的**-2**,对应ENOENT错误——看似是文件不存在,但大概率是你对命令行参数的处理出了问题),给你拆解几个最常见的问题和解决思路:

1. 你可能没正确获取argv[1]的地址

在x86_64 Linux环境下,程序启动时的栈布局是固定的:

  • 栈顶rsp首先指向参数个数argc
  • 紧接着是argv[0](程序自身路径的指针)
  • 再往后才是argv[1](第一个命令行参数的指针)

很多新手会犯的错是:直接取rsp+8当作argv[1],但如果程序启动后你做过push操作修改了rsp,或者没考虑栈的初始结构,就会拿到错误的指针。

给你一个正确获取argv[1]的示例代码:

section .text
global _start

_start:
    ; 先取出argc,检查是否传入了至少一个参数
    pop rdi                ; rdi = argc
    cmp rdi, 2
    jl exit_no_arg         ; 如果argc < 2,说明没传路径参数

    ; 跳过argv[0](程序自身路径),取出argv[1]
    pop rsi                ; rsi = argv[0](没用,跳过)
    pop rsi                ; rsi = argv[1](我们要的文件路径指针)

    ; 调用sys_open
    mov rax, 2             ; x86_64下sys_open的系统调用号
    mov rdi, rsi           ; 第一个参数:文件路径指针
    mov rsi, 0             ; 第二个参数:O_RDONLY(只读模式)
    mov rdx, 0             ; 第三个参数:权限(只读打开时可设为0)
    syscall

    ; 检查系统调用是否失败
    cmp rax, -1
    jl exit_open_fail

    ; 后续读取逻辑...

2. 先确认你拿到的参数内容是对的

你看到的ENOENT错误,大概率是因为sys_open拿到的路径根本不是你输入的内容。可以加个调试步骤:把argv[1]的内容输出到终端,看看是不是正确的路径。

示例调试代码(在获取argv[1]之后添加):

; 输出argv[1]的内容到stdout
mov rdx, 200              ; 假设路径最长200字节,可根据实际调整
mov rsi, rsi              ; 要输出的内容指针(就是argv[1])
mov rdi, 1                ; stdout的文件描述符
mov rax, 1                ; sys_write的系统调用号
syscall

如果输出的是乱码或者不完整的路径,那肯定是你获取argv[1]的方式错了。

3. 检查系统调用的参数顺序

x86_64 Linux的系统调用参数顺序是严格固定的:rdi→rsi→rdx→r10→r8→r9,返回值存在rax里。

sys_open的正确参数要求是:

  • rdi: 文件路径的字符串指针
  • rsi: 打开标志(比如O_RDONLY=0,O_WRONLY=1)
  • rdx: 创建文件时的权限(只有打开标志包含O_CREAT时才需要,否则设为0即可)

如果你把参数顺序搞反了(比如把路径放到rsi,标志放到rdi),那sys_open肯定会失败。

4. 用strace精准定位问题

如果上面的方法都没找到问题,直接用strace工具调试——它会把程序所有的系统调用、参数和返回值都打印出来,一眼就能看到sys_open到底传入了什么路径,以及具体的错误原因。

运行命令:

strace ./your_program /path/to/your/target/file

在输出里找open相关的行,比如:

open("/wrong/path/you/passed", O_RDONLY) = -2 ENOENT (No such file or directory)

这样就能明确看到是不是路径参数传错了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:02:07