博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系统调用
阅读量:5130 次
发布时间:2019-06-13

本文共 2683 字,大约阅读时间需要 8 分钟。

秦鼎涛 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

 

一、用户态、内核态和中断

 

 

 

二、系统调用概述

1、系统调用的意义

   操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用

·把用户从底层的硬件编程中解放出来
·极大的提高了系统的安全性
·使用户程序具有可移植性

 

2、API和系统调用

  ·应用编程接口(application program interface, API) 和系统调用是不同的

  API只是一个函数定义
  系统调用通过软中断向内核发出一个明确的请求
·Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用)
  一般每个系统调用对应一个封装例程
  库再用这些封装例程定义出给用户的API

   ·不是每个API都对应一个特定的系统调用。

  API可能直接提供用户态的服务
  如,一些数学函数
  一个单独的API可能调用几个系统调用
  不同的API可能调用了同一个系统调用
·返回值
  大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用
  -1在多数情况下表示内核不能满足进程的请求
  Libc中定义的errno变量包含特定的出错码

3、应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系

  

三、使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(源自网络)

选择sysinfo库函数116号系统调用

库函数API代码百度自网络:

 

#include

#include

intmain(void)

{

structsysinfo info;

if(sysinfo(&info) < 0) 

{

perror( sysinfofailed );

return-1;

}

printf( uptime   %ld , info.uptime  );

printf( loads %.2f, %.2f,%.2f ,

     (double)info.loads[0] / (1<< SI_LOAD_SHIFT),

 (double)info.loads / (1 <<SI_LOAD_SHIFT),

 (double)info.loads / (1 <<SI_LOAD_SHIFT));

printf( totalram %ld , info.totalram );

printf( freeram  %ld , info.freeram );

printf( sharedram %ld ,info.sharedram);

printf( bufferram %ld ,info.bufferram);

printf( totalswap %ld ,info.totalswap);

printf( freeswap %ld , info.freeswap );

printf( procs    %d , info.procs   );

printf( totalhigh %ld ,info.totalhigh);

printf( freehigh %ld , info.freehigh );

printf( mem_unit %d ,  info.mem_unit);

 

return0;

}

编译运行程序得到系统信息结果

给出了总的可用的内存大小,还未被使用的内存大小,共享的存储器的大小,缓冲区大小,交换区大小,还可用的交换区大小, 当前进程数目等数据

C代码中嵌入汇编代码

 

编写嵌入汇编的版本

asm volatile( mov $0,%%ebx mov $0x80,%%eax ...);

事实上在系统调用时,system_call是linux系统调用的入口点。每个系统调用至少有一个参数,那就是eax,它负责传递系统调用号,同时获取返回值。

除了eax外,还允许至多6个参数,分别是ebx,ecx,edx,esi,edi,ebp。

另一方面,容易观察到,实际上time()函数除了自身的传入系统调用号(同时接收返回值)外,还传入了一个参数NULL。

结合上面的叙述,应该可以猜到,其实代码 mov $0,%eax 是相当于向ebx传入了一个参数NULL,也就是0。

同理,对于sysinfo这个库函数API,它也有一个返回值,表示是否成功,并且传递进来一个参数sys_info来接收系统的相关信息。因此,我们可以编写下面的代码:

// syscall_asm.c#include #include .h>int main() { struct sysinfo sys_info; int error; //error = sysinfo(&sys_info); asm volatile( movl %1, %%ebx movl $0x74, %%eax // sysinfo 的系统调用号是 116 所以十六进制为 0x74 int $0x80 movl %�x, %0 : =m (error) // eax来负责传递返回值,我们同样用error来接收 : b (&sys_info) // sysinfo的地址作为参数,传递进ebx中作为参数被修改接收系统信息 ); printf( code error=%d ,error); printf( Uptime = %lds Load: 1 min%ld / 5 min %ld / 15 min %ld RAM: total %ld / free %ld / shared%ld Memory in buffers = %ld Swap: total%ld / free%ld Number of processes = %d , sys_info.uptime, sys_info.loads[0], sys_info.loads, sys_info.loads, sys_info.totalram, sys_info.freeram, sys_info.sharedram, sys_info.bufferram, sys_info.totalswap, sys_info.freeswap, sys_info.procs); return 0;}

所以,最后的执行结果是一样的

 

转载于:https://www.cnblogs.com/qindingtao/p/5295118.html

你可能感兴趣的文章
Java反射机制及其Class类浅析
查看>>
Postman-----如何导入和导出
查看>>
移动设备显示尺寸大全 CSS3媒体查询
查看>>
图片等比例缩放及图片上下剧中
查看>>
【转载】Linux screen 命令详解
查看>>
background-clip,background-origin
查看>>
Android 高级UI设计笔记12:ImageSwitcher图片切换器
查看>>
【Linux】ping命令详解
查看>>
对团队成员公开感谢博客
查看>>
java学习第三天
查看>>
python目录
查看>>
django+uwsgi+nginx+sqlite3部署+screen
查看>>
Andriod小型管理系统(Activity,SQLite库操作,ListView操作)(源代码下载)
查看>>
在Server上得到数据组装成HTML后导出到Excel。两种方法。
查看>>
浅谈项目需求变更管理
查看>>
经典算法系列一-快速排序
查看>>
设置java web工程中默认访问首页的几种方式
查看>>
ASP.NET MVC 拓展ViewResult实现word文档下载
查看>>
8、RDD持久化
查看>>
第二次团队冲刺--2
查看>>