在汇编中使用文件有两种方式,一种是使用标准的C库函数,例如:fopen(),read()以及write()函数等,这些C库函数本质上是通过Linux内核提供的系统调用来实现的,因此,汇编里操作文件的第二种方式就是直接使用底层提供的系统调用。本章节主要介绍的是第二种方式,所以,下面就对与文件操作相关的系统调用进行介绍...
System Call | Value | Description |
---|---|---|
Open | 5 |
Open a file for access and create a file handle pointing to the file. 打开指定的文件,同时返回操作该文件用的文件句柄 |
Read | 3 |
Read from an open file using the file handle. 通过文件句柄来读取指定文件的内容 |
Write | 4 |
Write to the file using the file handle. 通过文件句柄对目标文件进行数据写入操作 |
Close | 6 |
Close the file and remove the file handle. 关闭掉之前Open系统调用打开的文件,同时移除对应的文件句柄 |
$ man 2 open .................................... int open(const char *pathname, int flags, mode_t mode); .................................... $ |
C Constant C中的常量名 |
Numeric Value 常量对应的数值 (八进制格式) |
Description 常量描述 |
---|---|---|
O_RDONLY | 00 |
Open the file for read-only access. 以只读方式打开文件 |
O_WRONLY | 01 |
Open the file for write-only access. 以只写方式打开文件 |
O_RDWR | 02 |
Open the file for both read and write access. 以既可读又可写的方式打开文件 |
O_CREAT | 0100 |
Create the file if it does not exist. 如果文件不存在则创建该文件 |
O_EXCL | 0200 |
When used with O_CREAT, if the file exists, do not open it. 当与O_CREAT一起使用时,如果目标文件已经存在,则open系统调用会失败 |
O_TRUNC | 01000 |
If the file exists and is open in write mode, truncate it to a length of zero. 若文件存在,且是以可写的方式打开的文件,则将文件的长度截为0,从而将文件的内容全部清空。 |
O_APPEND | 02000 |
Append data to the end of the file. 追加数据到文件的末尾 |
O_NONBLOCK | 04000 |
Open the file in nonblocking mode. 以非阻塞模式打开文件,这样在对文件进行读写操作时,就会立即返回,一般在没有设置非阻塞的情况下,读写操作时,内核会切换到其他的进程,从而将当前的进程阻塞,直到读写操作完成时,内核才会唤醒被阻塞的进程。 |
O_SYNC | 010000 |
Open the file in synchronous mode (allow only one write at a time). 以同步模式打开文件(一次只允许一个写入操作) |
O_ASYNC | 020000 |
Open the file in asynchronous mode (allow multiple writes at a time). 以异步模式打开文件(一次允许多个写入操作) |
movl $0102, %ecx |
movl $02002, %ecx |
Permission Bits 二进制格式的权限位 |
Value 对应的八进制值 |
Access 访问权限 |
---|---|---|
001 | 1 | Execute privileges 执行权限 |
010 | 2 | Write privileges 写权限 |
011 | 3 | Execute and write privileges 执行,写权限 |
100 | 4 | Read privileges 读权限 |
101 | 5 | Execute and read privileges 执行,读权限 |
110 | 6 | Execute and write privileges 读,写权限 |
111 | 7 | Execute, write, and read privileges 读,写,执行权限 |
movl $0644, %edx |
file privs = privs & ~umask |
$ umask 0022 $ |
final privileges = privs & ~umask = 666 & ~022 = 666 & 755 = 644 |
$ umask 000 $ umask 0000 $ |
$ chmod 666 test $ ls -l ................................................ -rw-rw-rw- 1 root root 0 6月 13 00:04 test ................................................ $ |
.section .data filename: .asciz "output.txt" ....................... ....................... .section .text ....................... ....................... movl $filename, %ebx |
movl %esp, %ebp ...................................... ...................................... movl 8(%ebp), %ebx |
movl $5, %eax movl $filename, %ebx movl $0102, %ecx movl $0644, %edx int $0x80 test %eax, %eax js badfile |
$ cat /usr/include/asm/errno.h #include <asm-generic/errno.h> $ cat /usr/include/asm-generic/errno.h #ifndef _ASM_GENERIC_ERRNO_H #define _ASM_GENERIC_ERRNO_H #include <asm-generic/errno-base.h> ....................................... ....................................... $ cat /usr/include/asm-generic/errno-base.h #ifndef _ASM_GENERIC_ERRNO_BASE_H #define _ASM_GENERIC_ERRNO_BASE_H #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Argument list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file number */ #define ECHILD 10 /* No child processes */ #define EAGAIN 11 /* Try again */ #define ENOMEM 12 /* Out of memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #define ENOTBLK 15 /* Block device required */ #define EBUSY 16 /* Device or resource busy */ #define EEXIST 17 /* File exists */ #define EXDEV 18 /* Cross-device link */ #define ENODEV 19 /* No such device */ #define ENOTDIR 20 /* Not a directory */ #define EISDIR 21 /* Is a directory */ #define EINVAL 22 /* Invalid argument */ #define ENFILE 23 /* File table overflow */ #define EMFILE 24 /* Too many open files */ #define ENOTTY 25 /* Not a typewriter */ #define ETXTBSY 26 /* Text file busy */ #define EFBIG 27 /* File too large */ #define ENOSPC 28 /* No space left on device */ #define ESPIPE 29 /* Illegal seek */ #define EROFS 30 /* Read-only file system */ #define EMLINK 31 /* Too many links */ #define EPIPE 32 /* Broken pipe */ #define EDOM 33 /* Math argument out of domain of func */ #define ERANGE 34 /* Math result not representable */ #endif $ |
# open.s -- open a file that not exist
.section .data
filename:
.asciz "output.txt"
.section .text
.global _start
_start:
movl $5, %eax
movl $filename, %ebx
movl $0002, %ecx
movl $0644, %edx
int $0x80
test %eax, %eax
js badfile
movl $0,%ebx
movl $1,%eax
int $0x80
badfile:
movl $-1,%ebx
movl $1,%eax
int $0x80
|
$ as -o open.o open.s -gstabs $ ld -o open open.o $ gdb -q open Reading symbols from /root/asm_example/opfile/open...done. (gdb) b _start Breakpoint 1 at 0x8048074: file open.s, line 8. (gdb) r Starting program: /root/asm_example/opfile/open Breakpoint 1, _start () at open.s:8 8 movl $5, %eax (gdb) n 9 movl $filename, %ebx (gdb) n 11 movl $0002, %ecx (gdb) n 12 movl $0644, %edx (gdb) n 13 int $0x80 (gdb) n 14 test %eax, %eax (gdb) p $eax $1 = -2 (gdb) |
#define ENOENT 2 /* No such file or directory */ |
$ man 2 close .............................. #include |
movl filehandle, %ebx movl $6, %eax int $0x80 |