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
关键问题点解释
fopen宏的正确性
你原来的fopen宏没写完,Linux的open系统调用必须用rax=2,参数顺序是rdi=文件名、rsi=打开标志、rdx=权限。打开标志一定要加O_WRONLY(只写)、O_CREAT(创建文件)、O_TRUNC(清空原有内容),否则要么写不了,要么文件不存在时创建失败,要么原有内容还留在文件里。文件描述符的使用
open调用成功后,rax会返回一个正整数(文件描述符),必须把这个值存起来——如果你不小心用了rdi=1(stdout的描述符),内容会输出到终端而不是文件,这是新手常犯的错。必须调用close
Linux内核为了效率会把写入内容暂时存在缓冲区,如果不调用close,程序退出时内核可能会自动刷新,但显式调用close能确保数据100%写入磁盘,避免意外丢失。文件名的格式
文件名必须是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
相关产品推荐
相关产品推荐

