Linux下的系统调用
张雨梅 原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-10000
1.linux的的用户态与内核态
Intel x86架构的CPU有0~3四种执行级别,0级最高,3级最低, linux只使用0级和3级,分别表示内核态和用户态。linux中,只有内核态能访问逻辑地址为0xc0000000以上的空间。执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态。程序由用户态进入内核态的方式是中断。
系统调用的核心是使用操作系统为用户特别开放的一个中断,例如linux的int 80h中断,系统中断是由用户态主动切换到内核态。
上图展示的是程序在用户态和内核态切换的大概过程。
(1)xyz()是API,就是一个函数定义。
(2)每个系统调用对应一个封装例程, libc库用这些封装例程定义出用户的API。执行到int 80h时,产生系统调用,是通过软中断向内核发出的明确请求。
(3)system_call是linux所有系统调用的入口点,此时进入内核态,执行系统调用处理程序,执行内核函数sys_xyz。
(4)执行完成后返回到系统调用处理程序中的ret_fromsys_call,通过iret返回到封装例程中,又回到用户态封装例程执行完回到发生系统调用的位置,继续执行下面的程序。
每个系统调用对应一个封装实例,从而产生可给用户使用的API。但是API与系统调用不是一一对应的,有的API可能提供的都是用户态的服务,有的API可能调用多个系统调用,可能多个API调用同一个系统调用。
2.c代码与汇编代码
可以通过c代码和汇编代码的对应关系,观察系统调用的发生过程,这里用geituid函数。
getuid.c
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
uid_t uid;
uid = getuid();
printf("User IDs: uid=%d\n", uid);
exit();
}
getuid-asm.c
int main()
{
uid_t uid;
asm volatile(
"mov $0,%%ebx\n\t"//ebx保存参数,置为null
"mov $0x18,%%eax\n\t"//getuid的系统调用号是24,传给eax
"int $0x80\n\t"//系统调用
"mov %%eax,%0\n\t"//返回值用eax保存
: "=m"(uid)
);
printf("User IDs: uid=%d\n", uid);
return ;
}
getuid-asm.c与getuid.c不同的是,把uid = getuid()变成了汇编语言。汇编语言的执行步骤是:
(1)把参数传递给ebx,这个函数没有参数,这一句去掉以后执行结果是一样的。
(2)把系统调用号传给eax,系统调用号标志具体的系统调用函数。
每个系统调用至少有一个参数,系统调用号,用eax传递。除了系统调用号,参数不能超过6个,分别存入ebx,ecx,edx,esi,edi,ebp。如果参数超过6个,会用一个单独的寄存器指向进程地址空间中这些参数所在的内存区。
(3)int 80h,进入system_call,在内核堆栈中保存现场
push cs
push eip
push EFLAGS
push ss
push esp
push eax
push es
push ds
push eax
push ebp
push edi
push esi
push edx
push ecx
push ebx
然后执行内核函数sys_getuid()。
(4)执行完sys_getuid后,返回到system_call,恢复现场。
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
pop eax
pop ds
pop es
add $,esp//相当于pop eax
iret//返回到用户堆栈
与一般中断一样,函数返回值传递给eax。
iret执行之后,弹出esp,ss,eflags,cs,eip,进入用户堆栈,程序回到用户态进程。
编译运行结果如图
可以看出c代码与汇编代码的执行结果一样。
Linux下的系统调用的更多相关文章
- 浅析基于ARM的Linux下的系统调用的实现
在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的. t8.c 1: #include <stdio.h> ...
- (转)linux下的系统调用函数到内核函数的追踪
转载网址:http://blog.csdn.net/maochengtao/article/details/23598433 使用的 glibc : glibc-2.17使用的 linux kerne ...
- linux下的系统调用函数到内核函数的追踪
http://blog.csdn.net/maochengtao/article/details/23598433
- Linux下缓冲区溢出攻击的原理及对策(转载)
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...
- LINUX下FD_SET介绍
刚刚了解了linux下select系统调用,函数原型是 #include <sys/select.h> #include <sys/time.h> int select(int ...
- Linux下端口复用(SO_REUSEADDR与SO_REUSEPORT)
freebsd与linux下bind系统调用小结: 只考虑AF_INET的情况(同一端口指ip地址与端口号都相同) freebsd支持SO_REUSEPORT和SO_REUSEADDR选项,而l ...
- Linux下函数调用堆栈帧的详细解释【转】
转自:http://blog.chinaunix.net/uid-30339363-id-5116170.html 原文地址:Linux下函数调用堆栈帧的详细解释 作者:cssjtuer http:/ ...
- Linux下缓冲区溢出攻击的原理及对策
前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈 帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实 ...
- linux下C++修改文件内容
C fwrite在任意位置写入文件,并可修改文件内容 想实现类似迅雷那样下载时可以从文件半中间写入的功能 #include<stdio.h> int main() { FILE *fp; ...
随机推荐
- windows下的host文件在哪里?做什么用的?
在Window系统中有个Hosts文件(没有后缀名),在Windows98系统下该文件在Windows目录,在Windows2000/XP系统中位于C:\Winnt\System32\Drivers\ ...
- nodejs require//////////z
背景 这篇文基本都是反对的,反对的很有道理,不是说我这篇文章的内容错误,因为这篇文章是我在健身房学习node的时候写的,这些知识都很粗糙,后来发现官方的稳定更详细:地址:http://nodejs.o ...
- paper 123: SVM如何避免过拟合
过拟合(Overfitting)表现为在训练数据上模型的预测很准,在未知数据上预测很差.过拟合主要是因为训练数据中的异常点,这些点严重偏离正常位置.我们知道,决定SVM最优分类超平面的恰恰是那些占少数 ...
- 索尼Sony ATI显卡驱动 Win7 Win8 Win8.1 视频黑屏 解决方法
索尼ATI显卡驱动 Win7 Win8 Win8.1 视频 黑屏 完美解决方法: 下载这个补丁 安装 即可 解决 ! baidu pan: http://pan.baidu.com/s/1gd ...
- asp .Net TreeView实现数据绑定和事件响应
最近做了一个图书馆管理系统,其中要实现中图法分类号查询,因为初学asp ,感觉还有点难度, 第一步:数据库文件 第二步 向界面中拖进TreeView控件 第三步添加事件 下面是cs文件代码 //Tre ...
- Android Monkey测试(转载)
Monkey是一款通过命令行来对我们APP进行测试的工具,可以运行在模拟器里或真机上.它向系统发送伪随机的用户事件流,实现对正应用程序进行压力测试. 官方介绍 :https://developer.a ...
- Linq对XML的简单操作
前两章介绍了关于Linq创建.解析SOAP格式的XML,在实际运用中,可能会对xml进行一些其它的操作,比如基础的增删该查,而操作对象首先需要获取对象,针对于DOM操作来说,Linq确实方便了不少,如 ...
- 有关docker的学习链接
本文是自己搜索的比较好的网上资源,便于有兴趣者查阅. 英文官网 https://docs.docker.com/engine/getstarted/ 中文入门手册 http://www.docker. ...
- 电脑装的是office2013,右键新建却是2007,或者右键新建菜单中没有excel2013问题解决办法。
我的office出现了两个问题,因为工作比较忙,也没有着急解决,今天实在受不了了,花费一下午才找到解决方法. 原来万恶之源都是可恶的wps,以后千万不安装kingsoft了. 第一个问题:excel打 ...
- nodejs学习笔记一:安装express框架并构建工程目录
偶遇node是在一个阳光明媚的上午,无意间打开博客看到一片关于nodejs的介绍,通读全篇后,心情跌宕起伏,哎呀,这么好的东西我竟然现在才知道,这是最气的,于是马上开始制定学习nodejs计划,好了, ...