📜  程序集-文件管理

📅  最后修改于: 2020-11-05 05:10:40             🧑  作者: Mango


系统将任何输入或输出数据视为字节流。有三个标准文件流-

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

文件描述符

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

标准文件流的文件描述符-stdin,stdoutstderr分别为0、1和2。

文件指针

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

文件处理系统调用

下表简要描述了与文件处理相关的系统调用-

%eax Name %ebx %ecx %edx
2 sys_fork struct pt_regs
3 sys_read unsigned int char * size_t
4 sys_write unsigned int const char * size_t
5 sys_open const char * int int
6 sys_close unsigned int
8 sys_creat const char * int
19 sys_lseek unsigned int off_t unsigned int

使用系统调用所需的步骤与我们之前讨论的相同-

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

创建和打开文件

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

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

系统调用在EAX寄存器中返回已创建文件的文件描述符,如果发生错误,则错误代码在EAX寄存器中。

打开一个现有文件

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

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

系统调用在EAX寄存器中返回已创建文件的文件描述符,如果发生错误,则错误代码在EAX寄存器中。

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

从文件读取

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

  • 将系统调用sys_read()3放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 将指针放在ECX寄存器中的输入缓冲区。

  • 将缓冲区大小(即要读取的字节数)放入EDX寄存器中。

系统调用返回在EAX寄存器中读取的字节数,如果发生错误,则错误代码在EAX寄存器中。

写入文件

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

  • 将系统调用sys_write()编号4放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 将指针放到ECX寄存器中的输出缓冲区。

  • 将缓冲区大小(即要写入的字节数)放入EDX寄存器中。

系统调用返回写入EAX寄存器的实际字节数,如果发生错误,则错误代码在EAX寄存器中。

关闭档案

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

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

发生错误时,系统调用将返回EAX寄存器中的错误代码。

更新文件

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

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

参考位置可以是:

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

发生错误时,系统调用将返回EAX寄存器中的错误代码。

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

section    .text
   global _start         ;must be declared for using gcc
    
_start:                  ;tell linker entry point
   ;create the file
   mov  eax, 8
   mov  ebx, file_name
   mov  ecx, 0777        ;read, write and execute by all
   int  0x80             ;call kernel
    
   mov [fd_out], eax
    
   ; write into the file
   mov    edx,len          ;number of bytes
   mov    ecx, msg         ;message to write
   mov    ebx, [fd_out]    ;file descriptor 
   mov    eax,4            ;system call number (sys_write)
   int    0x80             ;call kernel
    
   ; close the file
   mov eax, 6
   mov ebx, [fd_out]
    
   ; write the message indicating end of file write
   mov eax, 4
   mov ebx, 1
   mov ecx, msg_done
   mov edx, len_done
   int  0x80
    
   ;open the file for reading
   mov eax, 5
   mov ebx, file_name
   mov ecx, 0             ;for read only access
   mov edx, 0777          ;read, write and execute by all
   int  0x80
    
   mov  [fd_in], eax
    
   ;read from file
   mov eax, 3
   mov ebx, [fd_in]
   mov ecx, info
   mov edx, 26
   int 0x80
    
   ; close the file
   mov eax, 6
   mov ebx, [fd_in]
   int  0x80    
    
   ; print the info 
   mov eax, 4
   mov ebx, 1
   mov ecx, info
   mov edx, 26
   int 0x80
       
   mov    eax,1             ;system call number (sys_exit)
   int    0x80              ;call kernel

section    .data
file_name db 'myfile.txt'
msg db 'Welcome to Tutorials Point'
len equ  $-msg

msg_done db 'Written to file', 0xa
len_done equ $-msg_done

section .bss
fd_out resb 1
fd_in  resb 1
info resb  26

编译并执行上述代码后,将产生以下结果-

Written to file
Welcome to Tutorials Point