汇编 - 文件管理

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

  • 标准输入(stdin),

  • 标准输出(stdout)和

  • 标准错误(stderr).

文件描述符

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

标准文件流的文件描述符 -   stdin,stdout stderr 分别为0,1和2.

文件指针

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

文件处理系统调用

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

%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寄存器中.

  • 将参数存储在EBX,ECX等寄存器中

  • 调用相关的中断(80h).

  • 结果通常在EAX寄存器中返回.

创建和打开文件

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

  • 将系统调用sys_cre at()编号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寄存器中.

参考位置c应该是:

  • 文件的开头 - 值0

  • 当前位置 - 值1

  • 文件结束 - 值2

如果出现错误,系统调用将返回EAX中的错误代码注册.

示例

以下程序创建并打开名为 myfile.txt 的文件,并写入文本'欢迎使用此文件中的"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