位置:首页 > > Assembly 文件管理

Assembly 文件管理

系统认为任何输入或输出数据的字节流。有三种标准的文件流:

  • 标准输入 (stdin)

  • 标准输出 (stdout)

  • 标准错误 (stderr)

文件描述

文件描述符是一个16位的整数,分配到一个文件作为一个文件ID。当一个新的文件被创建,或者打开现有的文件,文件描述符用于访问该文件。

标准的文件流 - 标准输入,输出和错误文件描述符分别为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寄存器

  • 将输入缓冲区的指针放入 EBX寄存器

  • 将缓冲区的大小,即要读取的字节数放到EDX寄存器中

系统调用返回EAX寄存器中读取的字节数,错误代码是在错误的情况下,在EAX寄存器中。

写入文件

写入到一个文件中,执行以下任务:

  • 把系统调用 sys_write() 数字4放到 ECX 寄存器

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

  • 输出缓冲区的指针放入 EBX 寄存器

  • 将缓冲区的大小,即要写入的字节数放入 EBX 寄存器

系统调用返回EAX寄存器中写入的字节的实际数量,在错误的情况下,错误代码是在EAX寄存器中。

关闭文件

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

  • 把系统调用sys_close() 数字 6放到 ECX 寄存器

  • 把文件描述符放入到EBX寄存器

系统调用返回时,在错误的情况下,在EAX寄存器中的错误代码。

更新文件

对于更新文件,请执行以下任务:

  • 把系统调用sys_lseek () 数字19放到 ECX 寄存器中

  • 将文件描述符放到 ECX 寄存器中

  • 将偏移值放到 ECX 寄存器中

  • 将基准位置的偏移量放在EDX寄存器中

参考位置可以是:

  • 文件开始的位置 -  0

  • 当前文件位置-  1

  • 文件尾 -  2

系统调用返回时,在错误的情况下,在EAX寄存器中的错误代码。

例子:

下面的程序创建和打开一个文件,名为myfile.txt,并写入一个文本'Welcome to Yiibai“到这个文件中。接下来,从文件中读取的程序和存储数据到一个缓冲区中的命名信息。最后,它显示的文本信息存储。

section	.text
   global _start         ;must be declared for using gcc
_start:   ;tell linker entry yiibai
;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]
    
; 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 codeinn.net'
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 codeinn.net