《操作系统》OS学习(三):系统调用

例子

首先看一个标准C库的例子:当我们程序中使用了C库中的printf()函数,实际在底层是在内核态中调用了write()函数。图中右侧则是将程序代码与C库都算到应用程序中,内核提供了一个系统调用接口。

从这个例子我们可以得到以下几点:

1. 系统调用是操作系统服务的编程接口;

2. 系统调用通常由高级语言编写(C或者C++);

3. 程序访问通常是通过高层次的API接口(比如C库)而不是直接进行系统调用。最常见的三种:1. Windows下的Win32 API;2. POSIX-based系统(包括UNIX、LINUX、Mac OS等)下的 POSIX API;3. JAVA虚拟机中的Java API。

实现:

每个系统调用对应一个系统调用编号。当使用系统调用时,系统调用首先通过软中断的方式进入到内核的中断向量表产生中断,发现是系统调用软中断后转移到系统调用表,系统调用表中记录系统调用编号与具体实现之间的映射关系,根据系统调用编号选取不同的系统调用实现,得到结果之后返回。通过这种方式,用户不需要知道系统调用内部是如何实现的,而只需要设置调用参数和湖区返回结果即可,并且系统调用接口的细节大部分都隐藏函数库后面,通过调用库函数实现。

函数调用与系统调用的不同:

使用的指令不同。系统调用使用INT和IRET,函数调用使用CALL和RET,他们的指令级是完全不同的。具体还有哪些不同呢?我们知道在调用一个函数的时候需要把参数压到堆栈中去,然后转到相应函数去执行,执行的时候从堆栈获取我的参数信息执行,然后返回结果。而对于系统调用来讲,内核是受保护的,为了保护内核,内核与应用程序之间使用不同的堆栈,因此系统调用时会有一个堆栈和特权级的切换,首先切换到内核态,此时可以使用特权指令,并拥有自己的堆栈,执行完后再切换回用户态。而常规调用是没有堆栈切换的。

开销不同。系统调用比函数调用更安全,但是开销更大。主要原因就是有一个用户态的切换。具体有以下操作导致开销更大:1. 引导机制,需要引导用户态到内核态的切换;2. 建立内核堆栈,第一次调用时需要创建新的内核堆栈;3. 验证参数,需要对传入的参数的有效性合法性进行验证;4. 在内核态中需要使用到用户态中的一些信息,此时需要建立内核态到用户态地址空间的映射关系;5. 建立用户态内核态地址空间映射时会导致缓存的变化,TLB中有些内容会失效。

示例:文件复制

一个文件复制过程可以拆分如下图所示,我们可以先看下整个过程中哪些过程会使用到系统调用:1.键盘输入;2. 屏幕显示;3. 读取文件;4. 创建文件 5. 写入文件。而在操作系统内部,键盘、屏幕与文件都视为文件系统里的,只是键盘、屏幕作为特殊文件来使用。因此用到了右图中标红的系统调用(还有一个creat)。

   

首先是一个read()函数如下图,我们要知道参数意义和返回值。int fd是要读的文件句柄,void *buf是缓冲区头指针, int length是缓冲区的最大长度,返回值为读出的数据长度int return_value。

那么内部是如何实现的呢?首先准备参数,如下图中上面的汇编代码,前6行都是压栈,压栈完最后一行是一个函数调用,这个函数调用还不是系统调用。因为所有系统调用都是通过一个宏展开成相应的函数。函数内的int就是进入内核态的指令,i就是系统调用的中断向量编号,T_SYSCALL代表该软中断是系统调用,a(num)是系统调用编号,后面是相应的参数。

进入到内核态之后的过程如下图:系统调用进入内核态实际是一个软中断,所有这些软中断会到最开始的一段汇编程序叫做alltraps(),在这里面获取中断的相关信息组成的数据结构,也就是TF数据结构。接下来来到trap(),判断tf中有一个成员trapno(中断向量)表明了该软中断是系统调用,则进入syscall(),发现系统调用编号代表的是sys_read()函数,接下来执行sys_read()函数,该函数读取堆栈中的参数信息,之后进入sysfile_read()函数,该函数则是直接操作底层的驱动程序进行读取,最后返回时调用trapret()函数返回给用户态


补充:

大多数计算机系统将CPU执行状态分为管态和目态。管态又称为特权状态、系统态或核心态。通常,操作系统在管态下运行。目态又叫做常态或用户态,用户程序只能在目态下运行,如果用户程序在目态下执行特权指令,硬件将发生中断,由操作系统获得控制,特权指令执行被禁止,这样可以防止用户程序有意或无意的破坏系统。从目态转换为管态的唯一途径是中断。

系统调用与库函数的区别

  • 系统调用:运行在用户空间的应用程序向操作系统内核请求某些服务的调用过程。是内核提供给应用程序的接口函数,属于系统的一部分。是为了方便应用使用操作系统的接口
  • 函数库调用是语言或应用程序的一部分。是为了方便人们编写应用程序而引出的,比如你自己编写一个函数其实也可以说就是一个库函数。
  • write/read就是系统调用,而printf/fread就是C标准库函数.
     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454174.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript服务器端开发技术(对象属性的枚举与查询)

既然对象是属性的集合,那么检测与枚举集合中的属性就是一项重要任务。对此,我们来分别看一下ES3和ES5提供的解决方案。 1) ES3枚举方案 示例代码: var contacts{ ID:[0,1,2,3,4,5], names:["Zero","One","Two&q…

treelistview 所有节点失去焦点_垃圾询盘过滤,焦点科技的 Milvus 实践

文章作者:黎阳,焦点科技软件开发工程师李成龙,Zilliz 数据工程师Milvus (https://milvus.io/) 向量搜索引擎开源半年以来,全球已经有数百家企业或组织用户。焦点科技是一家以 B2B 外贸交易为主营业务的科技公司,也是 M…

《操作系统》OS学习(四):计算机体系结构、内存层次和地址生成

计算机除了计算能力之外还有存储能力,存储能力即计算机拥有一系列的存储介质,我们可以在存储介质上存储我们的代码和数据。计算机体系结构中约定了哪些地方可以用来存储数据:CPU内的寄存器、内存和外存。不同的存储介质,容量、速度…

GCC中SIMD指令的应用方法

X86架构上的多媒体应用开发,如果能够使用SIMD指令进行优化, 性能将大大提高。目前,IA-32的SIMD指令包括MMX,SSE,SSE2等几级。 在GCC的开发环境中,有几种使用SIMD指令的方式,本文逐一介绍。X86的…

使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular

上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from angular/core; import { Http, Headers } from angular/http; import { Observable } from rxjs/Observable; import { ErrorHandler } from angular/core; import rxj…

leelen可视对讲怎么接线_楼宇对讲系统怎么布线 楼宇对讲系统布线方式【介绍】...

随着智能小区规模不断增加,楼宇可视对讲系统应用越来越广泛,因而视频信号的传输方式与布线设计显得越来越重要。视频信号与数据和音频信号不同,可行的一种传输方式为视频信号基带传输,下面小编就简要介绍一下这种传输方式和布线方…

路由汇总实例

5.2.2.2 路由汇总策略 之前提到过,在网络管理员计划好子网选择并进行预期地路由汇总时,手动路由汇总工作能取得最佳效果。例如,之前的例子设定好了一个考虑周全的计划,管理员只使用远离Yosemite路由器并以10.2开头的子网。这个规定…

《操作系统》OS学习(五):连续内存分配 内存碎片、动态分配、碎片整理、伙伴系统

内存碎片 在没有其他方式辅助的情况下,我们分配给一个进程的内存是连续的。在分配时候我们需要有动态分配与碎片处理。如何理解呢?就是每个进程需要一块内存,我们要选取合适的位置的内存分配给它。当有的进程先结束了内存还给操作系统&#…

世界之窗浏览器删除文本框信息_文本框——Excel里的便利贴

工作表里面的单元格应该是足够我们来记录数据和信息了。但是文本框这个功能在工作表中还是存在,可以理解为便利贴功能。插入文本框1.点击“插入”选项卡。2.然后点击“文本框”。3.在下拉菜单里面,有两种可供选择:横排文本框和垂直文本框。在…

RHEL 5服务篇—常用网络配置命令

常用网络配置命令 在“Linux系统管理”的文章中,大家已经学习了Linux系统的基本管理命令和技巧,为了进一步学习Linux网络服务打下了良好的基础。所以我作者以后将陆续推出Linux网络服务的相关文章。希望大家能给与我大大的支持。 今天我们就来学习一下…

清华大学《操作系统》(六):非连续内存分配 段式、页式、段页式存储管理

背景 连续内存分配给内存分配带来了很多不便,可能所有空闲片区大小都无法满足需求大小,这个分配就会失败。基于这种现状,就有了非连续内存分配的需求。非连续分配成功的几率更高,但也面对更多的问题,比如分配时是不是…

C语言第三次博客作业---单层循环结构

一、PTA实验作业。 题目1 1.实验代码 int n,i; double height1,height2;//1为输入身高&#xff0c;2为输出身高。 char sex; //1<height1<3; //N<1; scanf("%d",&n); while(n--){getchar();scanf("%c%lf",&sex,&height1);switch(sex)…

清华大学《操作系统》(七):虚拟存储、覆盖、交换

接下来几节都是对虚拟存储的讲解。虚拟存储是非连续存储管理的扩展。通过将内存中的数据暂存到外存的方式&#xff0c;为进程提供更大的内存空间。虚拟存储出现的主要原因是因为程序规模的增长速度远远大于存储器容量的增长速度&#xff0c;导致内存空间不够用。其实针对内存空…

遵义大数据中心项目工程概况_市委书记张新文到曹州云都大数据中心等项目现场调研建设情况...

4月25日&#xff0c;市委书记张新文到曹县调研重点项目建设情况&#xff0c;研究推进措施。市委常委、秘书长任仲义参加活动。张新文首先来到曹州云都大数据中心项目建设现场&#xff0c;查看项目推进情况。曹州云都大数据中心&#xff0c;是涵盖云计算区、研发办公区、公寓生活…

linux 可执行文件的分析(gcc GUN BUILEIN)

1、GCC The History of GCC 1984年&#xff0c;Richard Stallman发起了自由软件运动&#xff0c;GNU (Gnus Not Unix)项目应运而生&#xff0c;3年后&#xff0c;最初版的GCC横空出世&#xff0c;成为第一款可移植、可优化、支持ANSI C的开源C编译器。GCC最初的全名是GNU C Com…

Cassandra 的数据存储结构——本质是SortedMapRowKey, SortedMapColumnKey, ColumnValue

Cassandra 的数据存储结构 Cassandra 的数据模型是基于列族&#xff08;Column Family&#xff09;的四维或五维模型。它借鉴了 Amazon 的 Dynamo 和 Googles BigTable 的数据结构和功能特点&#xff0c;采用 Memtable 和 SSTable 的方式进行存储。在 Cassandra 写入数据之前&a…

清华大学《操作系统》(八):置换算法

功能&#xff1a;置换算法是指当出现缺页异常时&#xff0c;需要调入新页面而内存已满时&#xff0c;置换算法选择被置换的物理页面。 设计目标&#xff1a; 尽可能减少页面的调入调出次数&#xff1b;把未来不再访问或短期内不访问的页面调出。 页面锁定&#xff1a; 了解具…

烂泥:通过vsphere给esxi添加本地硬盘

公司ESXi服务器的硬盘空间不够使用&#xff0c;现在新加了一块硬盘在ESxi服务器上。在服务器上添加完硬盘后&#xff0c;在Vsphere上是看不到新加硬盘的。 下面我们来通过虚拟机模拟该情况&#xff0c;先添加一块硬盘。如下图&#xff1a; 在Esxi添加完硬盘后&#xff0c;现在通…

清华大学《操作系统》(九):进程和线程

进程 定义&#xff1a; 进程是指一个具有一定独立功能的程序在一个数据集合上的一次动态执行的过程。 组成&#xff1a; 代码数据状态寄存器&#xff08;正在运行的一个程序的所有状态信息&#xff09;&#xff1a;CPU状态CP0、指令指针IP通用寄存器&#xff1a;AX、BX、CX…

开始Flask项目

1.新建Flask项目。2.设置调试模式。3.理解Flask项目主程序。4.使用装饰器&#xff0c;设置路径与函数之间的关系。5.使用Flask中render_template&#xff0c;用不同的路径&#xff0c;返回首页、登录员、注册页。6.用视图函数反转得到URL&#xff0c;{{url_for(‘login’)}}&am…