当前位置: 首页 > news >正文

企业网站建设一条龙城乡建设工程信息网

企业网站建设一条龙,城乡建设工程信息网,网站建设市场供需分析,网站建设一般多少费用系统调用介绍 什么是系统调用 为了让应用程序有能力访问系统资源#xff0c;也为了让程序借助操作系统做一些由操作系统支持的行为#xff0c;每个操作系统都会提供一套接口#xff0c;以供应用程序使用。系统调用涵盖的功能很广#xff0c;有程序运行所必需的支持#xf…系统调用介绍 什么是系统调用 为了让应用程序有能力访问系统资源也为了让程序借助操作系统做一些由操作系统支持的行为每个操作系统都会提供一套接口以供应用程序使用。系统调用涵盖的功能很广有程序运行所必需的支持例如创建/退出进程和线程进程内存管理也有对系统资源的访问例如文件网络进程间通信硬件设备的访问也可能有对图形界面的操作支持。 Linux系统调用 下面让我们来看看Linux系统调用的定义有一个比较直观的概念。在x86下系统调用由0x80中断完成各个通用寄存器用于传递参数EAX寄存器用于表示系统调用的接口号比如EAX1表示退出进程(exit)EAX2表示创建进程(fork)EAX3表示读取文件或IO(read)EAX4表示写文件或IO(write)等每个系统调用都对应内核源代码中的一个函数它们都是以sys_开头比如exit调用对应内核中的sys_exit函数。当系统调用返回时EAX又作为调用结果的返回值。 EAX名字C语言定义含义参数1exitvoid _exit(int status)退出进程EBX表示退出码3readssize_t read(int fd, void* buf, size_t count)读文件EBX表示文件句柄ECX表示读取缓冲区地址EDX表示读取大小 系统调用的弊端 系统调用完成了应用程序和内核交流的工作因此理论上只需要系统调用就可以完成一些程序但是 理论上理论总是成立的。 事实上包括Linux大部分操作系统的系统调用都有两个特点 1、使用不便。操作系统提供的系统调用接口往往过于原始程序员需要了解很多与操作系统相关的细节。如果没有进行很好的包装使用起来不方便。 2、各个操作系统之间系统调用不兼容。 系统调用原理 特权级与中断 现在的CPU常常可以在多种截然不同的特权级别下执行指令在现代操作系统中通常也据此有两种特权级别分别为用户模式和内核模式也被称为用户态和内核态。由于有多种特权模式的存在操作系统就可以让不同的代码运行在不同的模式下以限制它们的权利提高稳定性和安全性。普通应用程序运行在用户态的模式下诸多操作将受到限制这些操作包括访问硬件设备开关中断改变特权模式等。 一般来说运行在高特权级的代码将自己降至低特权级是允许的但反过来低特权级的代码将自己提升至高特权级则不是轻易就能进行的。在将低特权级的环境转为高特权级时必须使用一种较为受控和安全的形式以防止低特权模式的代码破坏高特权模式代码的执行。 系统调用是运行在内核态的而应用程序基本都是运行在用户态的。用户态的程序如何运行内核态的代码呢操作系统一般是通过中断来从用户态切换到内核态。什么是中断呢中断是一个硬件或软件发出的请求要求CPU暂停当前的工作转手去处理更加重要的事情。 中断一般具有两个属性一个称为中断号(从0开始)一个称为中断处理程序。不同的中断具有不同的中断号而同时一个中断处理程序一一对应一个中断号。在内核中有一个数组称为中断向量表这个数组的第n项包含了第n号中断的中断处理程序的指针。当中断到来时CPU会暂停当前执行的代码根据中断号在中断向量表中找到对应的中断处理程序并调用它。中断处理程序执行完成之后CPU会继续执行之前的代码。一个简单的示意图如图1所示。 图1 CPU中断过程 通常意义上中断有两种类型一种称为硬件中断这种中断来自硬件的异常或其他事件的发生如电源掉电键盘被按下。另一种称为软件中断软件中断通常是一条指令带有一个参数记录中断号使用这条指令用户可以手动触发某个中断并执行其中断处理程序。例如在i386下int 0x80这条指令会调用第0x80号中断的处理程序。 由于中断号是很有限的操作系统不会舍得用一个中断号来对应一个系统调用而更倾向于一个或少数几个终端号来对应所有的系统调用。对于同一个中断号操作系统如何知道是哪一个系统调用被调用呢和中断一样系统调用都有一个系统调用号就像身份标识一样来表明是那个系统调用这个系统调用号通常就是系统调用在系统调用表中的位置例如Linux里的fork系统调用号是2。这个系统调用号在执行int指令前会被放置在某个固定的寄存器里对应的中断代码会取得这个系统调用号并且调用正确的函数。以Linux的int 0x80为例系统调用号是由eax来传入。用户将系统调用号放入eax然后使用int 0x80调用中断中断服务程序就可以从eax里取得系统调用号进而调用对应的函数。 基于int的Linux的经典系统调用实现 图2是以fork为例的Linux系统调用的执行流程。 图2 Linux系统中断流程  触发中断 首先当程序在代码里调用一个系统调用时是以一个函数的形式调用的例如程序调用fork int main(){ fork();} fork函数是一个对系统调用fork的封装可以用下列宏来定义它 _syscall0(pid_t, fork); _syscall0是一个宏函数用于定义一个没有参数的系统调用的封装。它的第一个参数为这个系统调用的返回值类型这里为pit_t是一个Linux自定义类型代表进程的id。_syscall0的第二个参数是系统调用的名称_syscall0展开之后会形成一个与系统调用名称同名的函数。下面的代码是i386版本的syscall0定义 #define _syscall0(type, name )                 type name(void)                                        {                                                                  long __res;                                           __asm__ volatile(int $0x80 a (__res)                           : 0 (__NR__##name));                 __syscall_return(type, __res);                 对应syscall0(pid_t, fork)上面的宏将展开为 pid_t fork(void) { long __res; __asm__ volatile(int $0x80 : a (__res) : 0 (__NR_fork)); __syscall_return(pid_t, __res); } 首先__asm__是一个gcc的关键字表示接下来要嵌入汇编代码。volatile 关键字告诉gcc对这段代码不进行任何优化。 __asm__的第一个参数是一个字符串代表汇代码的文本。这里的汇编代码只有一句: int $0x80这就要调用0x80号中断 a(__res)表示用eax(a表示eax)输出返回数据并存储在__res里。 0(__NR_#name)表示__NR_#name为输入0指示由编译器选择和输出相同的寄存器(eax)来传递参数。 更直观一点可以把这段汇编改写为更为可读的格式 main--fork pid_t fork(void) { long __res; $eax__NR_fork int $0x80 __res $eax __syscall_return(pid_t, __res); } 如果系统调用本身由参数要如何实现呢下面是x86Linux下的syscall1用于带1个参数的系统调用 #define _syscall2(type, name, type1, arg1) type name(type1, arg1) { long __res; __asm__ volatile(int $0x80 : a (__res) : 0 (__NR_##name), b((long)(arg1))); __syscall_return(type, __res);                   } 这段代码和_syscall0不同的是它多了一个b((long)(arg1))。这一句的意思是先把arg1强制转换为long然后存放在EBX(b代表EBX)里作为输入。编译器还会生产相应的代码来保护原理的EBX的值不被破坏。 可见如果系统调用由一个参数那么参数通过EBX来传入。x86下Linux支持的系统调用参数至多由6个分别使用6个寄存器来传递它们分别是EBXECXEDXESIEDI和EBP。 当用户调用某个系统调用的时候实际是执行了以上一段汇编代码。CPU执行到int $0x80时会保存现场以便恢复接着会将特权状态切换到内核态。然后CPU便会查找中断向量表中的第0x80号元素。 切换堆栈 在实际执行中断向量表中的第0x80号元素所对应的函数之前CPU首先还要进行栈的切换。在Linux中用户态和内核态使用的是不同的栈两者各自负责各自的函数调用互不干扰。但在应用程序调用0x80号中断时程序的执行流程从用户态切换到内核态这时程序的当前栈必须也相应的从用户栈切换到内核栈。从中断处理函数返回时程序的当前栈还要从内核栈切换回用户栈。 所谓的当前栈指的是ESP的值所在的栈空间。如果ESP的值位于用户栈的范围内那么程序的当前栈就是用户栈反之亦然。此外寄存器SS的值还应该指向当前栈所在的页。所以将当前栈由用户栈切换为内核栈的实际行为就是 1、保存当前的ESPSS的值。 2、将ESPSS的值设置为内核栈的相应值。 反过来将当前栈由内核栈切换为用户栈的实际行为则是 1、恢复原来ESPSS的值。 2、将用户态的ESPSS的值保存在内核栈上。 当0x80号中断发生的时候CPU除了切入内核态之外还会自动完成下列几件事 1、找到当前进程的内核栈(每一个进程都有自己的内核栈)。 2、在内核栈中依次压入用户态的寄存器SS,ESP,EFLAGS,CS,EIP。 而当内核从系统调用中返回的时候需要调用iret指令来回倒用户态iret指令则会从内核栈里弹出寄存器SSESPEFLAGSCSEIP的值使得栈恢复到用户态的状态。这个过程可以用图3来表示。 图3 中断时用户栈和内核栈切换
http://www.hkea.cn/news/14428249/

相关文章:

  • 自己做的网站源码如何安装装修设计软件网页版
  • 设置个网站要多少钱wordpress本地访问速度慢
  • 扁平化设计网站建设公司做网站买服务器多少钱
  • 网站开发拒绝通知书民族建设集团有限公司官方网站
  • 网站建设与代运营介绍品牌创意设计公司
  • 浏览器禁止网站怎么做vps租用
  • 物流网站给做软件下载浏览器怎么取消2345网址导航
  • 网站建设上机考试题目网站开发语言排名
  • 科技设计网站有哪些怎样让自己做的网站被百度收录
  • 如何搭建asp网站网站上做旅游卖家要学什么软件
  • 高密专业网站建设价格网站没询盘怎么做推广
  • 校园招生网站建设的简报html网页制作总结
  • 企业服务类网站免费国内socks5代理
  • 做网站的好公司有哪些网站源码下载有什么用
  • 牡丹江seo网站推广蜘蛛屯优化排名网站常用的颜色
  • 做外贸现在一般都通过哪些网站重庆开发app的公司
  • 做设计的网站手机版企业网站php
  • 网站建设做什么会计科目在线药店网站建设
  • seo 网站两个ip做网站的技术路线
  • 关于药品网站建设策划书wordpress数据库用户导出
  • 优秀的图片设计网站苏州集团网站设计公司
  • 网站后台上传用户界面不显示泰安网红餐厅
  • 公司做公司网站广告自己做的网站如何制作后台
  • 做网站需要多少带宽统计站老站长推荐app视频
  • 门户网站为什么衰落网站建设个人主要事迹
  • 网站字体颜色大小中国网站开发排名
  • 域名注册成功后怎么使用网站石家庄网站服务
  • 成都企业网站设计制作营销型的网站
  • 网站没备案怎么做广告联盟东莞软件定制开发
  • 大田县建设局官方网站什么网站可以做ui兼职