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

如何使用x86-64 Linux系统调用实现文件追加写入及相关疑问

你的Linux汇编文件操作问题解答

一、为什么追加写入总是覆盖内容?

这个问题的根源是你打开文件时用错了flags参数,把创建文件的权限mode和打开模式的flags搞混啦:

  • 你用mov rsi, 2调用sys_open,这里的2对应O_WRONLY(只写模式),这种模式下写入操作会从文件起始位置开始,直接覆盖原有内容,自然没法追加。
  • 你听到的“用400实现追加”是个误解——400是创建文件时的权限值(对应八进制的0400,表示所有者只读),和打开文件的追加flag完全不是一回事。

要实现追加写入,打开文件时必须在flags里加上O_APPEND(十进制64,十六进制0x40),正确的打开代码应该是这样:

; 打开已存在的文件,以追加模式写入
mov rax, 2          ; sys_open的系统调用号
mov rdi, path       ; 文件路径的地址
mov rsi, 0x42       ; O_WRONLY | O_APPEND (2 | 64 = 66)
syscall
mov r8, rax         ; 保存文件句柄(记得检查返回值,负数表示出错哦)

另外,其实你可以把「创建文件」和「打开文件」合并成一次sys_open调用,省掉多余的步骤:

; 一次性完成文件创建+追加打开,权限设为0400
mov rax, 2
mov rdi, path
mov rsi, 0x242      ; O_WRONLY | O_CREAT | O_APPEND(2 + 0x200 + 0x40 = 578)
mov rdx, 0400o      ; 文件权限(八进制,只有当指定O_CREAT时这个参数才生效)
syscall
mov r8, rax

二、能不能用\0终止字符串,不用手动指定rdx长度?

可惜的是,Linux的sys_write系统调用本身并不支持以\0作为字符串终止符。它是非常底层的调用,只会严格按照你在rdx里传入的字节数写入数据,不会主动扫描字符串去找末尾的\0。

如果想要实现类似C语言里puts那种自动识别\0的功能,你得自己先写一段代码计算字符串长度,比如这样:

; 计算以\0结尾的字符串长度,结果存到rdx中
mov rdx, 0
mov rcx, output     ; output是你的字符串起始地址
count_loop:
cmp byte [rcx], 0   ; 检查当前字节是否为\0
je count_finish     ; 是\0就跳出循环
inc rdx             ; 长度加1
inc rcx             ; 指针移到下一个字节
jmp count_loop
count_finish:

; 现在rdx就是字符串长度,可以调用sys_write了
mov rax, 1
mov rdi, r8
mov rsi, output
syscall

这样就能通过\0来自动确定写入长度啦。


内容的提问来源于stack exchange,提问作者мајдејсаремех

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:41:12