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

GNU汇编中使用write系统调用写入文件却为空的问题排查

问题分析与解决方案

你的汇编代码中,open系统调用的标志参数仅设置了O_CREAT(八进制0100),这是导致写入失败的核心原因:

  • 单独使用O_CREAT时,open默认会以只读模式打开文件(隐含O_RDONLY),此时得到的文件描述符没有写入权限,后续的write调用实际执行失败(只是你未检查系统调用返回值,没发现这个错误)。
  • 当你把文件描述符换成1(标准输出)或2(标准错误)时,这两个描述符本身就具备写入权限,所以write能正常输出到终端。

修复步骤

1. 修改open的标志参数

在O_CREAT基础上添加写入相关的标志:

  • O_WRONLY(八进制01):以只写模式打开文件
  • O_TRUNC(八进制01000):如果文件已存在,清空原有内容(可选,根据需求添加)

示例:将mov rsi, 0100改为mov rsi, 0101(O_CREAT | O_WRONLY),或者mov rsi, 010101(O_CREAT | O_WRONLY | O_TRUNC)。

2. 补充错误检查(可选但推荐)

系统调用可能因权限不足等原因失败,添加检查逻辑可以快速定位问题:

  • open调用后,若返回值rax小于0,说明调用失败,直接退出并返回错误码。

修正后的完整代码

.global _start
.intel_syntax noprefix

.text
_start:
    /* 创建并以只写模式打开文件 */
    mov rax, 2              // open系统调用号
    lea rdi, [rip+file]     // 文件路径
    mov rsi, 0101           // O_CREAT | O_WRONLY
    mov rdx, 0700           // 文件权限
    syscall

    /* 检查open是否成功 */
    cmp rax, 0
    jl exit_error           // fd小于0则跳转到错误处理

    mov rdi, rax            // 传递文件描述符给write
    lea rsi, [rip+message]  // 写入内容的缓冲区指针
    mov rdx, 13             // 写入内容长度
    mov rax, 1              // write系统调用号
    syscall

    /* 可选:关闭文件(进程退出时系统会自动关闭,但显式关闭是好习惯) */
    mov rax, 3              // close系统调用号
    syscall

exit_success:
    mov rax, 60             // exit系统调用号
    mov rdi, 0              // 正常退出码
    syscall

exit_error:
    mov rax, 60
    mov rdi, 1              // 错误退出码
    syscall

.data
message:
    .ascii "Hello sailor\n" // 要写入的内容
file:
    .asciz "main"           // 空终止文件名

额外说明

  • 如果需要保留文件原有内容并在末尾追加写入,可以把标志换成O_CREAT | O_WRONLY | O_APPEND(八进制0201)。
  • 所有标志的八进制值对应Linux系统定义的宏,可通过man 2 open查看完整标志列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:03:16