由一段代码解析系统调用的原理

朱宇轲 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

  在本次的实验中,我们将通过用C和汇编实现的同样一段代码来解析系统调用的过程。

     废话少说,开始实验!

     C语言程序如下所示:

/*test.c*/
#include<sys/types.h> #include<sys/stat.h> int main() { int status; int type=S_IRWXG; char string[]="./newdir"; status=mkdir(string,type); return 0; }

  汇编语言程序如下所示:

/*test2.c*/
#include<sys/types.h> #include<sys/stat.h> int main() { int status; int type=S_IRWXG; char string[]="./newdir2"; asm volatile( "mov $0x27,%%eax " "int $0x80 " "mov %%eax,%0 " :"=m"(status) :"b"(string),"c"(type) ); return 0; }

  我们本次使用的API是mkdir函数,它是Linux下的创建目录函数。它的函数原型是:

int mkdir(const char *path, mode_t mode); 

参数:

path是目录名 

mode是目录权限 

返回值: 

返回0 表示成功, 返回 -1表示错误,并且会设置errno值。 

     执行C程序后的运行结果是:

  可以看见编译执行text.c后,home中多出了newdir目录。

  执行汇编程序后的结果是:

  可以看见编译执行text2.c后,home中多出了newdir2目录。

      接下来分析汇编程序。

	asm volatile(
		"mov $0x27,%%eax
	"
		"int $0x80
	"
		"mov %%eax,%0
	"
		:"=m"(status)
		:"b"(string),"c"(type)
	);

  首先,将存储着目录名与权限的变量string和type存入ebx与ecx中,当做mkdir的参数传入(代码第六行)。

     之后,将要调用的系统调用号0x27(十进制的话就是39,对应mkdir函数)传入eax中,然后通过int命令触发中断,进入中断处理程序。带中断处理结束后,再讲eax的内容返回至status变量,这样mkdir就算是调用完成了。

  系统调用的执行过程实际上就是像老师课上讲的那样,分为API->中断处理程序->系统调用三个层次。注意系统调用和API并不是一一对应的,有可能一个API对应多个系统调用,也有可能一个系统调用对应多个API。我个人理解,API实际上可以算是对系统调用的封装。具体的执行过程,如下所示。

  

  本次就分析到这里,谢谢大家。

原文地址:https://www.cnblogs.com/wickedpriest/p/4375392.html