系统调用

程序运行的时候,本身是没有权限访问多少系统资源的。系统资源有限,如果操作系统不进行控制,那么各个程序难免会产生冲突。线程操作系统都将可能产生冲突的系统资源保护起来,阻止程序直接访问。比如文件、网络、IO、各种设备等。

系统调用涵盖的功能很广,有程序运行锁必须的支持,如创建和退出进程、线程,进程内存管理,对系统资源的访问等。

Linux系统调用与中断

在x86下,系统调用是通过0x80中断完成,各个通用寄存器用于传递参数。EAX寄存器用于表示系统调用的接口号。

比如:EAX=1表示退出进程,EAX=2表示创建进程,EAX=3表示读文件或IO,EAX=4表示写文件或IO。每个系统调用对应到内核源码中的一个函数,他们都是以sys_开头的,比如exit调用对应内核中的sys_exit函数

如果直接使系统调用会有非常多的问题:

  • 使用不方便,操作系统提供的系统调用接口往往过于原始。程序员需要了解很多跟操作系统相关的细节
  • 各个操作系统之间系统调用不兼容

于是增加一个层来解决,系统调用与程序之间增加一个抽象层。这个层就是前面所说的glibc,或者API.

系统调用原理

这里单单以Linux为例,至于Windows调用原理暂时省略。

用户态、内核态、中断与系统安全

现代操作系统中有两种特权级别,分为用户模式和内核模式。

多个模式存在,那么操作系统就可以让不同代码运行在不同模式下,进而限制代码的权限,提高稳定性、安全性。一般普通程序在用户态,操作会受到限制。系统调用运行在内核态,应用程序基本都是运行在用户态被限制。

用户态的程序通过中断来运行内核态的代码,进而从用户态切换到内核态。

比如Linux中int 0x80为例,系统调用号使用eax来传入,用户将系统调用号保存在eax,然后使用int 0x80调用中断,中断服务传给信号就可以从eax取得系统调用号,进行调用相应的函数。

切换堆栈

在实际执行中断向量表中的第0x80好中断之前,CPU还要进行堆栈的奇幻,在Linx中,用户态和内核态使用的是不同的栈,两者各自负责各自的函数调用,互不干扰。

在执行0x80中断的时候,程序从用户态切换到内核态。这时相应的栈也必须切换到内核栈,从中断处理函数中返回时,程序当前栈需要从内核栈切换到用户栈。

当前栈是指ESP值所在的栈空间,如果ESP的值位于用户栈范围能,那么程序的当前栈就是用户栈。内核栈同理。并且SS的值需要指向当前栈所在的页。所以用户栈切换到内核栈就是:

  • 保存当前ESP、SS的值
  • 将ESP、SS的值设置为内核栈的值

(反过来同理)

  • 恢复原理ESP、SS的值
  • 用户态的ESP和SS的值保存在内核栈上,

当发生中断的时候,CPU除了进入内核态之外还会做如下事情:

  • 找到当前进程的内核栈(每一个进程都有一个内核栈)
  • 在内核栈中一猜压入用户态的寄存器SS、ESP、EFLAGS、CS、EIP

当内核从系统调用中返回,则调动iret指令回到用户态,iret指令会从内核栈里面弹出SS、ESP、EFLAGS、CS、EIP的值。使得栈恢复到用户态的状态。

 

作者:纸简书生
链接:https://www.jianshu.com/p/4b9c40e6b8ae
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

《程序员的自我修养》读书笔记——系统调用、API的更多相关文章

  1. 第八周读书笔记(人月神话X月亮与六便士)——到底什么才是一个程序员的自我修养?

    写了这么久的读书笔记,涉及到问题大多是一些如何把软件工程做好,如何把自己的职业生涯做好.但总感觉逻辑链上缺了一环,亦即:我们为什么要把软件工程做好,我们成为一名优秀的职业生涯的意义到底在于什么?我觉得 ...

  2. pwn学习日记Day21 《程序员的自我修养》读书笔记

    Linux内核装载ELF过程 (1)bash进程调用fork()系统调用创建一个新的进程 (2)新的进程调用execve()系统调用执行指定的ELF文件,原先的bash进程继续返回等待刚才启动的新进程 ...

  3. pwn学习日记Day20 《程序员的自我修养》读书笔记

    可执行文件的装载与进程 覆盖装入和页映射是两种典型的动态装载方法 进程建立的三步 1.创建一个独立的虚拟地址空间 2.读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系. 3.将CPU的指令寄存 ...

  4. pwn学习日记Day19 《程序员的自我修养》读书笔记

    windows PE/COFF章总结 本章学习了windows下的可执行文件和目标文件格式PE/COFF.PE/COFF文件与ELF文件非常相似,它们都是基于段的结构的二进制文件格式.Windows下 ...

  5. gcc ld 链接器相关知识,调试指令(程序员的自我修养----链接、装载与库)

    最近解决一个动态链接上的问题,因为以前从来没有接触过这方面的知识,所以恶补了一下,首先要了解gcc编译指令(makefile),ld链接器的选项(还有连接脚本section指定内存位置),熟悉查看连接 ...

  6. 程序员的自我修养(2)——计算机网络(转) good

    相关文章:程序员的自我修养——操作系统篇 几乎所有的计算机程序,都会牵涉到网络通信.因此,了解计算机基础网络知识,对每一个程序员来说都是异常重要的. 本文在介绍一些基础网络知识的同时,给出了一些高质量 ...

  7. 《程序员思维修炼》读书笔记——week4

    <程序员思维修炼>读书笔记——week4 PB16061441 陈昶金 这周读的是Andy Hunt的著作<程序员思维修炼>,这本书对于我这种刚刚入门的新手很友好,大多是讲一些 ...

  8. pwn学习日记Day18 《程序员的自我修养》读书笔记

    知识杂项 obj文件:当前源代码编译成二进制目标文件 exe文件:将.obj文件与库文件.lib等文件链接生成的可执行文件 一个现代编译器的主要工作流程如下: 源程序(source code)→ 预处 ...

  9. Java程序员的自我修养

    一.自我修养路线图 如图,这是笔者所走的路.且不论这路走的对不对,这个过程中行业环境会影响到你,大可不必钻牛角尖.附上这张图的目的是为了说,如果你想成为一个优秀的程序员,那么你一定要有规划.当然,别想 ...

随机推荐

  1. [日常]nginx与网络事件模型

    Nginx 的特点: 1.处理静态文件 2.反向代理加速 3.fastCGI,简单的负载均衡和容错 4.模块化的结构 5.分阶段资源分配技术,使得它的 CPU 与内存占用率非常低,保持 10,000 ...

  2. Java类加载机制(加载、验证、准备、解析、初始化)

    如下图所示,Java的类加载机制主要分为三个部分,分别为加载.链接.初始化.其中链接又分为三个小部分--验证.准备.解析. 加载--在经过对Java代码进行编译后,JVM将Java类编译后的二进制文件 ...

  3. 【Linux】nginx常用命令

    相关内容链接 Centos之安装Nginx及注意事项 [nginx]详细配置说明 nginx常用命令 [重新加载配置]sudo nginx -s reload [打开nginx配置]sudo vim ...

  4. 洛谷P2421 [NOI2002]荒岛野人(扩展欧几里得)

    题目背景 原 A-B数对(增强版)参见P1102 题目描述 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,…,M.岛上住着N个野人,一开始依次住在山洞C1,C2,… ...

  5. CentOS7防火墙firewalld设置

    添加80端口  重启后永久生效 firewall-cmd --zone=public --add-port=80/tcp --permanent   查看防火墙状态 systemctl status ...

  6. Activiti实现流程自由跳转

    import org.activiti.engine.ProcessEngine; import org.activiti.engine.TaskService; import org.activit ...

  7. 实战 | Android中文图混排时文图的居中对齐 FontMetrics以及自定义ImageSpan实现

    这个标题有点长,乍一看这么个标题你可能没明白啥意思,且听我慢慢道来. 公司的项目中新增了一个“心动” 的功能,用户初次使用时需要给一个引导页,就是下面图中的这个样子(这就是做完之后的效果了). 在上图 ...

  8. matlab练习程序(马尔可夫聚类MCL)

    本文主要参考: https://wenku.baidu.com/view/b7907665caaedd3383c4d31b.html https://blog.csdn.net/u010376788/ ...

  9. Orchard详解--第六篇 CacheManager 2

    接上一篇,关于ICacheContextAccessor先看一下默认实现,用于保存一个获取上下文,且这个上下文是线程静态的: public class DefaultCacheContextAcces ...

  10. 根据class判断

    一.生命不息,代码不止