操作系统——用户编程接口

用户编程接口

库函数调用与系统调用

库函数是语言或应用程序的一部分,它是高层的、完全运行在用户空间、为程序员提供调用真正的在幕后完成实际事务的系统调用接口。而系统函数是内核提供给应用程序的接口,属于系统的一部分。简单说,函数库调用是语言或应用程序的一部分,而系统调用是操作系统的一部分

库函数调用与系统调用的区别:

  1. 在所有的ANSI C编译器版本中,C语言库函数是相同的;各个操作系统的系统调用是不同的

  2. 库函数调用函数库中的一段程序(或函数);系统调用系统内核的服务

  3. 库函数调用与用户程序相联系;系统调用是操作系统的一个入口点

  4. 库函数调用在用户地址空间执行;系统调用在内核地址空间执行

  5. 库函数调用的运行时间属于“用户时间”;系统调用的运行属于“系统时间”

  6. 库函数调用属于过程调用,调用开销较小;系统调用需要在用户空间和内核上下文环境间切换,开销较大

  7. 在C函数库libc中有大约300个函数;在UNIX中有大约90个系统调用

  8. 典型的C函数库调用:system、fprintf和malloc等;典型的系统调用:chdir、fork、write和brk等

静态链接与动态链接

静态链接

静态链接是指把要调用的函数或者过程直接链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的.exe文件中,该文件包含了运行时所需的全部代码。

静态链接的缺点是:当多个程序都调用相同的函数时,内存中就会存在这个函数的多个复制,这样就浪费了内存资源

动态链接

动态链接调用的函数代码并没有被复制到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定向信息)。仅当应用程序被装入内存开始运行时,在操作系统的管理下,才在应用程序与相应的动态链接库(dynamic link library, dll)之间建立链接关系。当要执行调用.dll文件中的函数时,根据链接产生的重定位信息,操作系统才转去执行.dll文件中相应的函数代码

静态链接的执行程序能够在其他同类操作系统的机器上直接运行。而动态链接的执行程序则不可以,除非把该.exe文件所需的dll文件都一并复制过去,或者对方机器上也有所需的相同版本的.dll文件,否则是不能保证正常运行的

静态链接库与动态链接库

静态链接库

静态链接库就是使用的.lib文件,库中的代码最后需要链接到可执行文件中去,所以静态链接的可执行文件一般比较大一些

动态链接库

动态链接库是一个包含可由多个程序同时使用的代码和数据的库,它包含函数和数据的模块的集合。程序文件(如.exe文件或.dll文件)在运行时加载这些模块(即所需的模块映射到调用进程的地址空间)

静态链接库和动态链接库的相同点是它们都实现了代码的共享,不同点是静态链接库.lib文件中的代码被包含在调用的.exe文件中,该.lib文件中不能再包含其他动态链接库或静态链接库了。而动态链接库.dll文件可以被调用的.exe动态地“引用”和“卸载”,该.dll文件中可以包含其他动态链接库或者静态链接库

用户态和核心态

核心态与用户态是操作系统的两种运行级别,它用于区分不同程序的不同权利。核心态就是拥有资源多的状态,或者说访问资源多的状态,也称为特权态。相对来说,用户态就是非特权态,在此种状态下访问的资源将受到限制。如果一个程序运行在特权态,则该程序就可以访问计算机的任何资源,即它的资源访问权限不受限制。如果一个程序运行在用户态,则其资源需求将受到各种限制

Intel CPU提供Ring0~Ring3共4中级别的运行模式。Ring0级别最高,Ring3级别最低

用户态:Ring3运行于用户态的代码则要受到处理器的诸多检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段(TTS)中I/O许可位图(I/O Permission Bitmap)中规定的可访问端口进行直接访问

核心态:Ring0在处理器的存储保护中,核心态是操作系统内核所运行的模式。运行在该模式的代码,可以无限制地对系统存储、外部设备进行访问

当一个任务(进程)执行系统调用而陷入内核代码中执行时,就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(或简称为用户态)。即此时处理器在特权级最低的(3级)用户代码中运行

在核心态下CPU可执行任何指令;在用户态下CPU只能执行非特权指令。当CPU处于核心态时,可以随意进入用户态;而当CPU处于用户态时,用户从用户态切换到核心态只有在系统调用和中断两种情况下发生。一般程序一开始都是运行于用户态,当程序需要使用系统资源时,就必须通过调用软中断进入核心态

核心态和用户态各有优势:运行在核心态的程序可以访问的资源多,但可靠性、安全性要求高,维护管理都比较复杂;用户态程序访问的资源受限,但可靠性、安全性要求低,自然编写维护起来都较简单。一个程序到底应该运行在核心态还是用户态取决于其对资源和效率的需求

CPU管理和内存管理都应该在核心态实现。这些功能可以在用户态下实现,但是不太安全

诊断和测试程序也需要在核心态下实现,因为诊断和测试需要访问计算机的所有资源。输入输出管理也一样,因为要访问各种设备和底层数据结构,也必须在核心态实现

对于文件系统,则可以一部分放在用户态,一部分放在核心态。文件系统本身的管理,即文件系统的宏数据部分的管理,必须放在核心态,不然任何人都可能破坏文件系统的结构;而用户数据的管理,则可以放在用户态。编译器、网络管理的部分功能、编辑器用户程序,都可以放在用户态下执行

用户栈与内核栈

内核在创建进程的时候,在创建task_struct的同时,会为进程创建相应的堆栈。每个进程会有两个栈:一个用户栈,存在于用户空间;一个内核栈,存在于内核空间。当进程在用户空间运行时,CPU堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间,CPU堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈

当进程因为中断或者系统调用而从用户态转为内核态时,进程所使用的堆栈也要从用户栈转到内核栈。进程陷入内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态,把内核栈中保存的用户态的堆栈的地址恢复到堆栈指针寄存器即可。这样就实现了内核栈和用户栈的互转

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值