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

Ubuntu环境下NASM程序无法写入同目录a.txt文件求助

Ubuntu汇编程序无法写入a.txt文件的问题排查与解决

看起来你在写x86_64汇编程序时卡在了文件写入这一步——明明逻辑上要写a.txt,结果执行后文件是空的。结合你给出的代码片段,我猜问题大概率出在文件操作的系统调用没有完全遵循Linux的规范,毕竟汇编里的系统调用容错性很低,参数顺序、调用号、标志位错一点都不行。

先给你梳理下Linux下汇编文件操作的核心步骤:打开文件 → 写入内容 → 关闭文件,每一步都不能少,而且参数必须准确。我先把你未完成的代码补全并修正,再拆解关键点:

完整可运行的示例代码

%macro print 2
    mov rax,1
    mov rdi,1
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro

%macro accept 2
    mov rax,0
    mov rdi,0
    mov rsi,%1
    mov rdx,%2
    syscall
%endmacro

%macro exit 0
    mov rax,60
    mov rdi,0
    syscall
%endmacro

; 补全fopen宏:参数1=文件名,参数2=打开标志,参数3=文件权限(仅O_CREAT时有效)
%macro fopen 3
    mov rax,2        ; Linux x86_64的open系统调用号是2
    mov rdi,%1       ; 第一个参数:文件名的内存地址
    mov rsi,%2       ; 第二个参数:打开标志(比如创建、只写、截断)
    mov rdx,%3       ; 第三个参数:文件权限(八进制0644对应十六进制0x1a4)
    syscall
%endmacro

; 新增fwrite宏:参数1=文件描述符,参数2=内容缓冲区,参数3=内容长度
%macro fwrite 3
    mov rax,1        ; write系统调用号是1(不管是stdout还是文件都用这个)
    mov rdi,%1       ; 第一个参数:文件描述符(open返回的有效值)
    mov rsi,%2       ; 第二个参数:要写入的内容地址
    mov rdx,%3       ; 第三个参数:内容的字节长度
    syscall
%endmacro

; 新增fclose宏:参数1=文件描述符
%macro fclose 1
    mov rax,3        ; close系统调用号是3
    mov rdi,%1       ; 要关闭的文件描述符
    syscall
%endmacro

section .data
    filename db 'a.txt',0   ; 文件名必须以0结尾(C风格字符串)
    content db 'Hello from x86_64 assembly!',0xa
    content_len equ $-content  ; 计算内容长度
    open_err_msg db 'Failed to open file (check permissions?)',0xa
    err_len equ $-open_err_msg

section .bss
    fd resq 1  ; 用来保存open返回的文件描述符

section .text
    global _start

_start:
    ; 打开文件:创建(不存在则建)、只写、清空原有内容,权限0644
    ; 0x61 = O_WRONLY(1) | O_CREAT(0x40) | O_TRUNC(0x20)
    fopen filename, 0x61, 0x1a4
    cmp rax, 0
    jl open_failed  ; rax<0表示打开失败(比如权限不够)
    mov [fd], rax   ; 保存文件描述符,后面要用

    ; 写入内容到文件
    fwrite [fd], content, content_len

    ; 必须关闭文件!内核会缓冲写入内容,close会强制刷到磁盘
    fclose [fd]

    ; 终端提示写入完成
    print content, content_len
    exit

open_failed:
    print open_err_msg, err_len
    exit

关键问题点解释

  1. fopen宏的正确性
    你原来的fopen宏没写完,Linux的open系统调用必须用rax=2,参数顺序是rdi=文件名、rsi=打开标志、rdx=权限。打开标志一定要加O_WRONLY(只写)、O_CREAT(创建文件)、O_TRUNC(清空原有内容),否则要么写不了,要么文件不存在时创建失败,要么原有内容还留在文件里。

  2. 文件描述符的使用
    open调用成功后,rax会返回一个正整数(文件描述符),必须把这个值存起来——如果你不小心用了rdi=1(stdout的描述符),内容会输出到终端而不是文件,这是新手常犯的错。

  3. 必须调用close
    Linux内核为了效率会把写入内容暂时存在缓冲区,如果不调用close,程序退出时内核可能会自动刷新,但显式调用close能确保数据100%写入磁盘,避免意外丢失。

  4. 文件名的格式
    文件名必须是C风格的字符串(以0结尾),否则open会找不到文件。

编译运行命令

用nasm和ld编译运行:

nasm -f elf64 your_file.asm -o your_file.o
ld your_file.o -o your_file
./your_file

运行后打开a.txt,就能看到写入的内容了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:36:11