Linux系统调用之系统调用过程

对于日常使用的应用也不是脱离了硬件进行执行的,为了方便使用,就出现了操作系统,如果操作系统不是开放的,那就失去了操作系统的意义,为了方便使用操作系统,操作系统预留出了一些接口,这些接口就是系统调用函数。

当然系统调用函数肯定不同于库函数,接下来我将讲解Linux中的系统调用过程。

下图是软硬件的简单关系。

库函数:调用在用户态,执行在用户态

系统调用函数,调用在用户态,执行在内核态。

操作系统:管理软硬件资源,为用户提供人机交互的平台。

 

本文使用了系统调用里的文件函数open,read,write,close(可以查看我的博客,文件函数)

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

int main()
{
	int fdr = open("passwd", O_RDONLY);
	assert(fdr != -1);

	int fdw = open("./newpasswd", O_WRONLY | O_CREAT, 0600);
	assert(fdw != -1);

	char buff[256] = {0};
	int num = 0;
	while((num = read(fdr, buff, 256)) > 0)
	{
		write(fdw, buff, num);
	}

	close(fdr);
	close(fdw);
	exit(0);	
}

当程序遇到第一个系统调用函数open时,发生系统调用,接下来我将从程序的执行方面讲述:

第一步:程序进入操作系统查找系统调用号,并将系统调用号保存到eax寄存器中。

              一般情况下Linux中open函数的系统调用号为5

第二步:将eax中的值作为系统调用表的下标执行系统内核函数

第三步:系统内核返回文件描述符,并将文件描述符保存给eax寄存器带出,赋值给fdr

              一般情况下第一次打开的文件所返回的文件描述符为3,第二个为4(具体可以参考我的博客,文件描述符)

第四步:程序继续执行

大概过程如下所示

上面是对程序运行方面进行理解的,理解比较粗糙。

当发生系统调用时具体发生了以下事情:

1.将程序上下文保存

2.将函数对应的系统调用号保存到eax寄存器

3.出发0x80中断,切换到内核态执行中断处理

ps:因为每当发生系统调用都会执行上面的步骤,所以输入输出函数都会带有缓冲区,以减少发生系统调用的次数

猜你喜欢

转载自blog.csdn.net/HDong99/article/details/84962936