汇编语言 文件管理

系统将任何输入或输出数据视为字节流。

有 3 种标准文件流:

  • 标准输入(stdin)
  • 标准输出(stdout)
  • 标准错误(stderr)

文件描述符

文件描述符 是作为 文件id 分配给文件的 16 位整数。创建新文件或打开现有文件时,文件描述符用于访问文件。

标准文件流的文件描述符 -stdinstdoutstderr 分别为 012


文件指针

文件指针 以字节为单位指定文件中后续读/写操作的位置。每个文件都被视为一个字节序列。每个打开的文件都与一个文件指针相关联,该指针指定相对于文件开头的偏移量(以字节为单位)。打开文件时,文件指针设置为 0。


文件处理系统调用

下表简要介绍了与文件处理相关的系统调用:

%eax名称%ebx%ecx%edx
2sys_forkstruct pt_regs--
3sys_readunsigned intchar size_t
4sys_writeunsigned intconst char size_t
5sys_openconst char intint
6sys_closeunsigned int--
8sys_creatconst char int-
19sys_lseekunsigned intoff_tunsigned int

使用系统调用所需的步骤与前面讨论的相同:

  • 将系统呼叫号码放入 EAX 寄存器。
  • 将系统调用的参数存储在寄存器 EBXECX 等中。
  • 调用相关中断(80h)。
  • 结果通常返回到 EAX 寄存器中。

创建和打开文件

要创建和打开文件,请执行以下任务:

  • 将系统调用 sys_creat() 放入 EAX 寄存器中。
  • 将文件名放入 EBX 寄存器。
  • 将文件权限放入 ECX 寄存器。

系统调用返回 EAX 寄存器中创建的文件的文件描述符,如果出现错误,错误代码位于 EAX 寄存器。


打开现有文件

要打开现有文件,请执行以下任务:

  • 将系统调用 sys_open() 放入 EAX 寄存器。
  • 将文件名放入 EBX 寄存器。
  • 将文件访问模式放入 ECX 寄存器。
  • 将文件权限放入 EDX 寄存器。

系统调用返回 EAX 寄存器中创建的文件的文件描述符,如果出现错误,错误代码位于EAX寄存器。

在文件访问模式中,最常用的是:只读(0)只写(1)读写(2)


从文件读取

要读取文件,请执行以下任务:

  • 将系统调用 sys_read() 放入 EAX 寄存器中。
  • 将文件描述符放入 EBX 寄存器。
  • 将指针指向 ECX 寄存器中的输入缓冲区。
  • 将缓冲区大小,即要读取的字节数,放入 EDX 寄存器。

系统调用返回在 EAX 寄存器中读取的字节数,如果出现错误,错误代码位于 EAX 寄存器。


写入文件

要写入文件,请执行以下任务:

  • 将系统调用 sys_write() 放入 EAX 寄存器中。
  • 将文件描述符放入 EBX 寄存器。
  • 将指针指向 ECX 寄存器中的输出缓冲区。
  • 将缓冲区大小,即要写入的字节数,放入 EDX 寄存器。

系统调用返回写入 EAX 寄存器的实际字节数,如果出现错误,错误代码位于 EAX 寄存器中。


关闭文件

要关闭文件,请执行以下任务:

  • 将系统调用 sys_close() 放入 EAX 寄存器中。
  • 将文件描述符放入 EBX 寄存器。

如果出现错误,系统调用将返回 EAX 寄存器中的错误代码。


更新文件

要更新文件,请执行以下任务−

  • 将系统调用 sys_lseek() 放入 EAX 寄存器中。
  • 将文件描述符放入 EBX 寄存器。
  • 将偏移值放入 ECX 寄存器。
  • 将偏移量的参考位置放入 EDX 寄存器。

参考位置可以是:

  • 文件开头 - 值 0
  • 当前位置 - 值 1
  • 文件结尾 - 值 2

如果出现错误,系统调用将返回 EAX 寄存器中的错误代码。


实例

以下程序创建并打开名为 myfile.txt 的文件,并在此文件中写入文本 “Welcome to Cankaoshouce.com”。接下来,程序读取文件并将数据存储到名为 info 的缓冲区中。最后,它显示存储在 info 中的文本。

  1. section .text
  2. global _start ;必须声明才能使用 gcc
  3. _start: ;告诉链接器入口点
  4. ; 创建文件
  5. mov eax, 8
  6. mov ebx, file_name
  7. mov ecx, 0777 ;所有人的读、写和执行
  8. int 0x80 ;调用内核
  9. mov [fd_out], eax
  10. ; 写入文件
  11. mov edx,len ;字节数
  12. mov ecx, msg ;消息
  13. mov ebx, [fd_out] ;文件描述
  14. mov eax,4 ;系统调用号 (sys_write)
  15. int 0x80 ;调用内核
  16. ; 关闭文件
  17. mov eax, 6
  18. mov ebx, [fd_out]
  19. ; 写入指示文件写入结束的消息
  20. mov eax, 4
  21. mov ebx, 1
  22. mov ecx, msg_done
  23. mov edx, len_done
  24. int 0x80
  25. ; 打开文件进行读取
  26. mov eax, 5
  27. mov ebx, file_name
  28. mov ecx, 0 ;用于只读访问
  29. mov edx, 0777 ;所有人的读、写和执行
  30. int 0x80
  31. mov [fd_in], eax
  32. ; 读取文件
  33. mov eax, 3
  34. mov ebx, [fd_in]
  35. mov ecx, info
  36. mov edx, 26
  37. int 0x80
  38. ; 关闭文件
  39. mov eax, 6
  40. mov ebx, [fd_in]
  41. int 0x80
  42. ; 打印信息
  43. mov eax, 4
  44. mov ebx, 1
  45. mov ecx, info
  46. mov edx, 26
  47. int 0x80
  48. mov eax,1 ;系统调用号 (sys_exit)
  49. int 0x80 ;调用内核
  50. section .data
  51. file_name db 'myfile.txt'
  52. msg db 'Welcome to Cankaoshouce.com'
  53. len equ $-msg
  54. msg_done db 'Written to file', 0xa
  55. len_done equ $-msg_done
  56. section .bss
  57. fd_out resb 1
  58. fd_in resb 1
  59. info resb 26

结果如下:

  1. Written to file
  2. Welcome to Cankaoshouce.com