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; ...
随机推荐
- jQuery CSS操作及jQuery的盒子模型
jQuery CSS-jQuery CSS方法 jQuery CSS-jQuery盒子模型
- .net post的参数如果出现乱码如何解决!
可以在webConfig里面添加 <system.web> <globalization requestEncoding="gb2312" responseEnc ...
- NSURLSessionTask使用dispatch_semaphore 完成同步机制
在NSURLSessionTask发起网路请求时,一般是异步操作,如果需要进行同步等待的话,可采用dispatch_semaphore_t信号量基于计数器的一种多线程同步机制.但是在多个线程访问共有资 ...
- WP 手机Lumia 820 锁屏密码的破解研究
Windows Phone lumia 手机锁屏密码的破解研究 大家好今天给大家分享一个最新研究案例, 近日笔者接Nokia Lumia 820, 由于客户密码失误太多,导致锁屏23000余分 ...
- java 编译期常量
今天在看书的时候遇到了一个不是很懂的名词,是在think in java 这本书的第七章讲final关键字时讲到的.然后自己在网上查了一下知道了一些. 编译器常量就是:它的值在编译期就可以确定的常量. ...
- HDU 3605:Escape(最大流+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...
- angular-笔记
ng-model 指令ng-model 指令 绑定 HTML 元素 到应用程序数据.ng-model 指令也可以:为应用程序数据提供类型验证(number.email.required).为应用程序数 ...
- Ajax开发中服务端Response的Content-Type
转自http://www.cnblogs.com/hyl8218/archive/2010/03/10/1681484.html ajax开发中在请求服务器端的响应时, 对于每一种返回类型 规范的做法 ...
- 华硕电脑u盘启动及原来win8现在安装win7后找不到硬盘解决方法
1.设置U盘启动 开机按F2进入BIOS,Security-Secure Boot Control设为Disabled , BOOT-Lunch CSM 设为Enabled 按F10保存. 重启按ES ...
- asp值mysql驱动
http://www.sufeinet.com/thread-10278-1-1.html%20http://tool.sufeinet.com/CodePreview/CodeView.aspx?a ...