首页 > 编程知识 正文

系统调用的执行过程,Linux系统调用过程

时间:2023-05-05 18:57:06 阅读:153753 作者:4706

为什么系统调用的原理和详细过程需要系统调用? 由于系统中有限的资源可能被多个不同的APP应用程序访问,因此如果不加以保护,程序冲突将不可避免。 因此,在现代操作系统中,可能存在冲突的系统资源将得到保护,并且来自APP应用程序的直接访问将被阻止。 这些系统资源包括文件、网络、IO和各种设备。

为了允许APP应用程序访问系统资源,以及APP应用程序使用操作系统执行操作系统必须支持的操作。 每个操作系统都提供一组供APP应用程序使用的界面。 这些接口往往通过中断来实现。

不易使用系统调用和运行库(标准库)系统调用的弊端。 在很多情况下,操作系统提供的系统调用接口太原始了,程序员需要知道很多关于操作系统的细节。 如果没有合适的程序包,各操作系统之间的系统调用将不兼容。 首先,Windows系统和Linux系统之间的系统调用基本上完全不同。 同一系列的操作系统的系统调用也不同。 例如,Linux和Unix不一样。 为了解决这个问题,运行库作为系统调用和程序之间的抽象层挺身而出。 它具有以下特点:

很容易使用。 形式统一。 运行库有一个称为标准库的标准,所有遵循该标准的运行库在理论上是相互兼容的,不会随操作系统或编译器的变化而变化。 系统调用原理:现代操作系统通常以两种不同的特权模式执行代码

3354用户状态和内核状态3354限制他们的权力。 系统调用一定会操作有限的资源,并在内核状态下执行。 用户状态程序如何执行内核状态的代码呢? 操作系统通常通过中断从用户状态切换到内核状态。

中断中断是指硬件或软件发出的要求(电信号),要求CPU中断当前工作处理更重要的事情。

中断通常有两个属性:中断号和http://www.Sina.com/(ISR,Interrupt Service Routine )。 内核中有一个名为中断处理程序的数组,其中包含指向中断编号及其相应中断处理程序的指针。 当出现中断时,CPU暂停当前运行的代码,根据中断的中断号在中断向量表中找到对应的中断处理程序,并调用它。 中断处理程序执行完成后,CPU将继续执行上一段代码。

中断有两种类型。 一个称为中断向量表,此中断源于硬件异常或事件的发生。 另一个称为硬件中断,软件中断通常是包含记录中断号的参数的命令。 此命令允许用户手动触发中断并运行中断处理程序。

由于中断号码有限,操作系统倾向于使用一个或少量的中断号码来响应所有系统调用,而不是只使用一个系统调用来响应一个中断号码。 Linux使用int0x80触发所有系统调用。 每个系统调用都对应于软件中断,这个系统调用号码在执行系统调用号命令之前存储在固定寄存器(eax )中,对应的中断代码存储在该系统中

系统调用的详细步骤

1 .触发中断用户程序在代码中调用系统调用,执行int指令前将系统调用号放入eax寄存器,执行int0x80指令

(int指令最后执行的函数是system_call,该函数验证系统调用号码的有效性,查找并执行系统调用函数,最后通过itret从中断处理程序返回。)

2 .堆栈切换(此过程由int指令完成)在实际运行对应于0x80地址中断向量的中断处理程序(system_call )之前,CPU首先从堆栈切换,即用户状态切换到汽车从中断处理程序返回时,程序的当前堆栈将从内核堆栈切换到用户堆栈。

% E6 % 89 % 80 % E8 % B0 % 93 % E7 % 9a % 84 % E5 % BD % 93 % E5 % 89 % 8d % E6 % A0 % 88 % ef % BC % 8c % E5 % 80 % BC % E5 % E5 % E5 % BC % E5 % E5 % E5 % E5 % E5 % E5 % E5 % e 84 % E8 % 8c % 83 % E5 % 9b % E5 % 86 % ef % BC % 8c % e9 % 82 % a3 % E4 % B9 % 88 % E7 % A8 % 8b % E5 % 20 % B7 % E6 % A0 % 80 % A0 % A0 % a3 % E4 E8 % af % a5 % E6 % 8c % 87 % E5 % 90 % E5 % BD % 93 % E5 % 89 % E6 % A0 % 88 % E6 % 89 % E5 % 9c % 20 % BD % 93 % E5 % 89 % E5 % e9 % BD % E6 % 98 % af % ef % BC % 9a % 20 % ef % BC % 881 % ef % BC % 89 % 20 % E4 % BF % 9d % E5 % 204 % BF % 9d % E8 % af % 81 e % 8c % E6 % 88 % 90 % ef % BC % 89 % 0a % 20 % ef % BC % 89 % 20 % ef5 % BC % 86 eer % 20b8% E6 % A0 % E7 % 6 % E5 % 88 % E5 % a5 % E5 % 86 % E6 % A0 % b8 % E6 % 81 % E4 % B9 % E5 % a4 % 96 % ee6 % 25 % 208 % 97 % E5 % 87 % A0 % E4 % 6 % af % 8f % E4 % b8 % b8 % aa % E8 % BF % E7 % A8 % A8 % e9 % 83 % BD % E6 % b8 % AC % 89 % 25 % 20 % 882 % ef % BC % 882 % E3 % 80 % 81e flags % E3 % 80 % 81cs % E3 % 80 % 81e IP % E8 % 80 % 80c % E5 % BD % 93 % E5 % 86 % 20 % 9b % 9e % E7 % 9a % 84 ef % BC %8ciret % E6 % 8c % 87 % E4 % bb % a4 % E5 % 88 % 99 % E4 % BC % E4 % bb % 8e5% 86 % E6 % A0 % 25 % 2081 esp % E3 % 84 E5 % 20 % E7 % 9a % 84 % E7 % 8a % B6 % E6 % 81 % E3 % 82 % 0a % 203.% E4 % b8 % ad6 % E6 % 96 % ad5 % E5 % a4 % 84 % ee % 24 % ee % a1 % A8 % E4 % b8 % ad % E7 % e9a % 840 X80 % E5 % B7 % b8 % E6 % a5 % a4 % E7 % 90 % 25 % 20 % E5 % ba % 94 % E7 % 9a % 84 % a % 8f % e9 % a6 % 96 % E5 % 88 % E6 % a3 % E6 % 9f % a5 % E7 % B3 % bb % 9f % 25 % 2086 % 8d % E6 % A0 % B9 % E6 % 8d % aeee ax % A8 % E4 % b8 % E6 % 89 % be5 % B0 % E7 % b8 % b8 % E5 % ba94 % E7 % 20 % 82 % E8 % B0 % 83 % E7 % A8 % E5 % ae8c % E6 % E8 % E8 % E8 % E6 % E8 % E8 % E8 % E8 1 % ef % BC % 9a % 20 % 2f % 20 system _ call % E7 % 9a % 84 % 20d % 98 % E5 % ad % 98 % E5 % 99 % A8 % E7 % 84

eax寄存器中的值和系统调用号大1的值(验证系统调用号的有效性)jae syscall_badsys// 如果系统调用无效,指向syscall_badsys// 如果系统调用号有效,则会执行以下代码syscall_call:call *sys_call_table(0, %eax, 4)// 查找中断服务程序并执行, sys_call_table其实就是系统调用表.....RESTORE_REGS// 恢复之前保存的寄存器......iret// 从中断程序返回

4. 从中断处理程序返回

在3中有描述

总结

用户运行库函数(系统调用的封装),函数里面其实是执行的int 0x80指令。系统调用先把系统调用号保存在eax寄存器中,然后执行int0x80指令。int 0x80指令先进行切换堆栈(找到进程的堆栈,将寄存器值压入到内核栈中,将esp,ss设置成对应内核栈的值),查找相应中断向量的中断处理程序(system_call)并调用,随后system_call 从系统调用表中找到相应的系统调用进行调用,调用结束后从system_call中返回。

参考文献

程序员的自我修养-链接、装载与库

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。