1.系统调用的过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengonghao/article/details/51288084

         什么是系统调用?我的理解是系统调用是操作系统提供的一组函数,比如I/O读写磁盘等。由于是操作系统提供的,故只能在内核态中执行。用户编写的程序平时运行在用户态,需要用系统调用时只能通过特定的方式(int 0x80中断进入内核,eax寄存器指定具体的系统调用,用edi、esi等寄存器向系统调用传递参数)来使用系统调用。

         大致的执行逻辑如下所示:


         应用程序在用户态执行时可能会请求系统调用,比如读写磁盘的I/O操作,这时就需要int 0x80指令。int 0x80指令是一条硬件中断指令,该指令的执行意味着程序将从用户态进入内核态,同时由硬件负责保存用户态的执行现场,并把程序的用户态堆栈转换为内核态堆栈。

         Int0x80之后就进入到内核代码了,在内核中首先执行到system_call的位置,pushl %eax的意思是把eax寄存器的值压入程序内核态堆栈,eax中存放着系统调用号,系统调用号标识了不同的系统调用。用户态程序传递给系统调用的参数存放在ebx、ecx、edx等等寄存器中,而ebx、ecx、edx等寄存器的值通过SAVE_ALL宏压入内核堆栈。

         系统调用处理完之后由RESTORE_ALL宏把SAVE_ALL压入的寄存器反向弹出。

         Iret指令与int 0x80相反,iret从内核态返回到用户态,一次系统调用完成。

 

         下图更具体的说明了这一过程:


sys_call_table意为系统调用表,维护了每个系统调用函数的内存入口地址。eax寄存器保存着系统调用号,4 * (eax),在32位系统中一个指针大小为4字节,4 * (eax)就指向了某一个具体的系统调用程序所在的内存位置。

展开阅读全文

没有更多推荐了,返回首页