x86 汇编入门(06):文件读写
程序不能只跟终端打交道。配置文件、日志、数据文件——都离不开文件 I/O。这一篇用 06_file_io.asm 完成「写入 → 关闭 → 重新打开 → 读取 → 输出」全流程,也是本系列的收官之作。
这是「x86 汇编入门」系列的第 6 篇,也是最后一篇。前五篇覆盖了输出、输入、算术、循环和函数。这一篇综合运用文件相关系统调用,并回顾整个系列的学习路径。
一、文件相关系统调用
| 调用号 | 名称 | 作用 |
|---|---|---|
| 2 | sys_open |
打开或创建文件 |
| 0 | sys_read |
从 fd 读取 |
| 1 | sys_write |
向 fd 写入 |
| 3 | sys_close |
关闭 fd |
sys_open 参数:
| 寄存器 | 含义 |
|---|---|
rdi |
文件路径(以 \0 结尾的 C 字符串) |
rsi |
打开标志 flags |
rdx |
权限 mode(创建文件时有效) |
返回值 rax |
文件描述符;失败时为负数 |
常用 flags(可位或组合):
| 标志 | 值 | 含义 |
|---|---|---|
O_RDONLY |
0 | 只读 |
O_WRONLY |
1 | 只写 |
O_CREAT |
0x40 | 不存在则创建 |
O_TRUNC |
0x200 | 截断(清空) |
写入模式组合:O_WRONLY | O_CREAT | O_TRUNC = 0x241。
二、程序流程
06_file_io.asm 分三步:
第一步:创建并写入
1 | mov rax, 2 |
第二步:只读打开并读取
1 | mov rax, 2 |
第三步:把读到的内容打印到 stdout
1 | mov rax, 1 |
三、错误处理
打开文件失败时,rax 为负数。程序用 test rax, rax + js .error 检测符号位:
1 | .error: |
生产级代码还会打印 errno,入门 demo 保持简洁。
四、运行输出
1 | make |
1 | [写入] 数据已写入 /tmp/asm_test.txt |
文件在容器内的 /tmp/asm_test.txt,可以 cat 验证。
五、系列回顾
| 篇 | 主题 | 核心技能 |
|---|---|---|
| 00 | 环境搭建 | Docker、nasm、ld、make |
| 01 | Hello World | section、syscall、sys_write / sys_exit |
| 02 | 用户输入 | sys_read、.bss、缓冲区 |
| 03 | 算术运算 | add/sub/imul/idiv、数字转字符串 |
| 04 | 循环 | cmp、条件跳转、jmp |
| 05 | 函数 | call/ret、栈帧、递归 |
| 06 | 文件 I/O | sys_open/read/write/close |
从 20 行 Hello World 到读写磁盘文件,你没有借助 printf、没有链接 libc,每一行都是自己和内核的直接对话。
六、可以继续往哪走?
- 调试:gdb 单步、查看寄存器和栈;strace 跟踪系统调用
- 更多 syscall:目录操作、内存映射(mmap)、网络 socket
- 和 C 互调:汇编写性能关键路径,C 写业务逻辑
- 对照学习:用
gcc -S看 C 编译出的汇编,理解编译器怎么做函数调用和循环
七、小结
本篇完成了文件创建、写入、读取、关闭的完整流程,并串联了系列全部知识点。汇编入门最难的是迈出第一步——如果你跟着系列走到了这里,已经比大多数人更靠近机器的真相。
x86 汇编入门系列全部 7 篇完。感谢阅读,去写你自己的第一条
syscall吧。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 WALL-E`s Blog!







