目录
文件管理
打开一个现有文件
从文件读取
写入文件
关闭文件
更新文件
内存管理
文件管理
实际上我们已经做过了文件管理了。标准输出标准输入以及标准错误的文件描述符实际上就是文件管理的特殊文件描述符。我们现在只需要强调的是获取文件描述符使用的是open系统调用!返回的文件描述符号会放在寄存器eax里。使用结束文件需要做的是关闭文件。提供关闭的文件描述符即可。
与文件处理相关的系统调用:
%eax | 名称 | %ebx | %ecx | %edx |
---|---|---|---|---|
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 in |
相应的,一些标准的打开流程:
打开一个现有文件
要打开现有文件,请执行以下任务-
-
将系统调用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寄存器中的错误代码。
; -------------------------------------------------- ; Program written in 10.25 2024 ; Author: Charlie chen ; Functionality: using files ; -------------------------------------------------- ; fast use of common value %define MY_SYS_OPEN 5 %define MY_SYS_CLOSE 6 %define MY_SYS_WRITE 4 %define MY_SYS_READ 3 %define MY_STDOUT 1 ; print string in a simple way %macro PRINT_STRING 2 mov edx, %2 mov ecx, %1 mov ebx, MY_STDOUT mov eax, MY_SYS_WRITE int 0x80 %endmacro section .data file_name db "demo.txt" file_name_new db "copy.txt" section .bss show_msg_from_file resb 20 section .text global _start _start: ; open file with read only and all access for us mov eax, MY_SYS_OPEN mov ebx, file_name mov ecx, 0 mov edx, 0777 int 0x80 ; read mov ebx, eax mov eax, MY_SYS_READ mov ecx, show_msg_from_file mov edx, 20 int 0x80 PRINT_STRING show_msg_from_file, 20 mov ebx, 0 mov eax, 1 int 0x80
内存管理
sys_brk的调用号是45,我们返回的地址放在了ebx当中!而后使用即可!
section .bss buffer resb 256 ; 预留256字节的空间 section .text global _start _start: ; 获取当前程序段的末尾地址 mov eax, 45 ; sys_brk xor ebx, ebx ; 传递NULL以获取当前地址 int 0x80 ; 调用系统 ; 保存当前地址 mov ebx, eax ; 分配256字节 add ebx, 256 mov eax, 45 ; sys_brk int 0x80 ; 调用系统 ; 这里可以使用ebx地址进行操作 ; 释放内存 mov eax, 45 ; sys_brk mov ebx, eax ; 传递当前地址 int 0x80 ; 调用系统 ; 退出程序 mov eax, 1 ; sys_exit xor ebx, ebx ; 返回值0 int 0x80