系统调用API,系统调用指令和异常机制(中断)之间的关系
我试图理解C语言系统调用API,系统调用汇编程序指令和用于在进程之间切换上下文的异常机制(中断)之间的关系.我自己要研究很多,所以请耐心等待.
我的理解是正确的,C语言系统调用是由编译器作为系统调用实现的,其中各自的代码在汇编中,而这些代码又由OS实现为异常机制(中断)? 所以在以下C代码中调用write函数: #include <unistd.h> int main(void) { write(2,"There was an error writing to standard outn",44); return 0; } 作为系统调用指令编译为程序集: mov eax,4 ; system call number (sys_write) syscall 反过来,指令由OS实现为异常机制(中断)? 解决方法
TL; DR
syscall指令本身就像一个美化的跳跃,它是一种硬件支持的方式,可以有效,安全地从无特权的用户空间跳转到内核. 在x86_64之前,使用了另外两种机制:int指令和sysenter指令. C语言不涉及系统调用,它依赖于the C runtime来执行与未来程序环境的所有交互. C运行时通过特定于环境的机制实现上述交互. 术语API用于表示合同,严格来说使用API??不需要调用一段内核代码(趋势是在用户空间中实现非关键功能以限制可利用的代码),这里我们只对此感兴趣在需要权限切换的API子集中. 在Linux下,内核公开了一组可从用户空间访问的服务,这些入口点称为system calls. C运行时调用OS API,在Linux的情况下,系统调用是直接使用的,因为它们是公共的(在某种意义上,在各个版本中是稳定的),而对于Windows,通常的DLL,如kernel32.dll,被标记为依赖项和使用. 我们被简化到一个用户模式程序,它是C运行时(Linux)的一部分或API DLL(Windows)的一部分,需要调用内核中的代码. x86架构历史上提供了不同的方法,例如,call gate. >这是BIOS和DOS在他们的时代所做的. 随着架构的现代化,这种机制变得有一个很大的缺点:它很慢. 随着Pentium Pro / II[1]的出现,引入了一对新的指令sysenter和sysexit,以便更快地进行系统调用. 随着x86-64的出现,AMD对sysenter的响应,即syscall / sysret对,开始了从用户模式切换到内核模式的事实上的方式. Linux和Windows的64位版本都使用系统调用. 总结一下,可以通过三种机制给内核控制: >软件中断. Here is a nice page to put it in a better shape. C运行时通常是一个静态库,因此是预编译的,它使用上述三种方法之一.
术语异常在CS中重载,C有异常,Java和C#也是如此. 异常是通过中断发送的,它们是一种中断. 使用软件中断(也是同步的);机制几乎完全相同(异常可以在内核堆栈上推送状态代码)但语义不同.我们从不引用空指针,访问未映射的页面或类似的方法来调用系统调用,我们使用int指令代替. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |