Previously on the 系统调用初探
上次用 C 代码所实现的功能为:从当前目录的 src_file/src-asm_file 拷贝内容到 当前目录的 dest_file/dest-asm_file 文件中,具体源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024 /* 每次读写缓存大小,影响运行效率 */
#define OFFSET 10240 /* 拷贝的数据大小 */
#define SRC_FILE_NAME "src_file" /* 源文件名 */
#define DEST_FILE_NAME "dest_file" /* 目标文件名 */
int main()
{
int src_fd, dest_fd;
unsigned char buff[BUFFER_SIZE];
int buff_len;
/* 以只读的方式打开源文件 */
src_fd = open(SRC_FILE_NAME, O_RDONLY);
/* 以只读的方式打开目标文件,若此文件不存在则创建,访问权限为644 */
dest_fd = open(DEST_FILE_NAME, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (src_fd < 0 || dest_fd < 0)
{
printf("Open File Error!\n");
exit(1);
}
/* 将源文件的读写指针移到最后10KB的起始位置 */
lseek(src_fd, -OFFSET, SEEK_END);
/* 读取源文件的最后10KB数据并写到目标文件中,每次读写1KB */
while ((buff_len = read(src_fd, buff, sizeof(buff))) > 0)
{
write(dest_fd, buff, buff_len);
}
close(dest_fd);
close(src_fd);
return 0;
}
注:嵌入汇编的代码就不再贴出,因为通过 C 程序可以很清楚地看出程序的功能,如果想看汇编代码建议点击上面链接。
首先要明白一点,我们分析 system_call 中断处理的过程是分析什么?我们分析的是 entry_32.S 文件中的执行流程,那么到底是什么时候进入 entry_32.S 的呢?我们在触发系统调用时,即用 int 0x80 触发软中断时,就会跳转到 entry_32.S 文件中 system_call,然后根据相应的系统调用号分别进行处理。具体分析如下:
1. 用户空间到内核空间的转换
根据系统调用初探中描述到,用户态与内核态的区别仅仅在于CPU的运行状态、运行权限得到提升。系统调用需要一个从用户空间到内核空间的转换,