用asm内联汇编实现系统调用
来源:互联网 发布:双十一套路 知乎 编辑:程序博客网 时间:2024/05/22 09:42
原创内容(cxsmarkchan 陈晓爽)
转载请注明出处
《Linux内核分析》MOOC课程学习笔记
为保证系统的稳定运行,CPU运行状态被分为内核态和用户态。操作系统在内核态下运行,因此拥有所有计算机资源的操作权限。而一般的应用程序则在用户态下运行,它们不能直接操作底层的硬件设备,从而保证应用软件不会破坏系统的稳定。但是,应用程序在运行时常常需要和各种资源打交道,为此,操作系统提供了“系统调用”的功能,提供一组API,由用户态程序调用。本文通过asm内联汇编,分析系统调用的全过程。
1 系统调用的概念
下图是一个典型的系统调用图示:
从该函数可以看到,系统调用分成如下过程:
1. 用户态程序调用API函数xyz
2. 在xyz
接口函数内部,通过中断号0x80
进入系统调用,此时CPU进入内核态。
3. CPU开始执行中断处理程序,根据用户传入的信息(系统调用号和相关参数),执行相应的内核态函数,并返回结果。
这里有两个问题:
1. 内核态的切换是通过中断方式进入的,而产生中断时只能传入一个中断向量(即0x80
),而系统调用有大量的API函数,系统如何知道调用哪一个函数呢?
2. 有一些API函数带有参数,而系统调用并没有才有函数调用(call
)方式,那么参数如何传递到被调用函数?
答案是:在调用int 0x80
进入系统调用前,预先把系统调用号和相关参数存入指定的寄存器中。这样,系统调用函数只需要访问相应的寄存器,就可以获得所有的信息。
事实上,在进入系统调用前,首先需要将系统调用号传入eax
寄存器中,并将参数依次传入ebx
、ecx
、edx
、esi
、edi
、ebp
寄存器中。系统调用最多只能传入6个参数,如果参数多于6个,则需要将参数预存在内存中,然后将参数指针传入寄存器。系统调用结束后,eax
会被替换为系统调用返回值。
2 用asm实现系统调用的实例
本文运行平台为实验楼Linux内核分析的第4个实验,运行环境为linux系统。
为了验证系统调用的全过程,我们以exit函数为例,给出代码如下:
#include <stdio.h>#include <stdlib.h>int main(){ int id; scanf("%d", &id); switch(id){ case 0: //用C语言的方式调用exit函数 printf("C exit\n"); exit(0); break; case 1: //用内联汇编的方式调用exit函数 printf("asm exit\n"); asm volatile( "mov $0, %%ebx\n\t" "mov $0x1, %%eax\n\t" "int $0x80\n\t" : : ); break; default: printf("others\n"); break; } printf("before return\n"); return 0;}
该函数中,首先输入参数id。如果id为0,则调用C代码的exit函数。如果id为1,则调用汇编代码的exit函数。如果id为其他值,则顺序执行至main函数结尾。
事实上,上文的代码采用C代码和内联汇编实现了等价的功能,即exit(0)
功能。可以分析一下内联汇编的工作方式:
1. mov $0, %ebx
:exit函数的第1个参数(也是唯一一个参数)为0,按照寄存器顺序,应该放在ebx
中。
2. mov $0x1, %eax
:exit函数的系统调用号为0x1
,因此把系统调用号放入eax
中。
3. int 0x80
:产生中断,中断号0x80
表示系统调用。
执行了以上3步,即为执行了exit(0)函数。程序的运行结果如下:
可见,输入0或1时,都没有输出"before return"
,说明exit被成功调用,程序提前退出。
3 小结
系统调用既保证了操作系统的安全运行,也方便了用户态程序使用系统资源。用内联汇编的方式处理系统调用,可以很清晰地看出系统调用的过程,以及系统调用的参数传递方式。系统调用通过寄存器传递参数,因此在进行系统调用前,通常还需要备份相关寄存器中的信息。不过,在内联汇编中,这个工作会被编译器代劳。
- 用asm内联汇编实现系统调用
- 2.asm-asm内联汇编
- VC内联汇编实现跳转调用
- [汇编]内联汇编-扩展ASM
- C++ Inline ASM 内联汇编祥解
- VC内联ASM汇编学习笔记
- C++ Inline ASM 内联汇编祥解
- C++ Inline ASM 内联汇编详解
- GCC Inline ASM GCC内联汇编
- Visual C Inline ASM 内联汇编
- C++ Inline ASM 内联汇编祥解
- GCC Inline ASM GCC内联汇编
- C++ Inline ASM 内联汇编详解
- GCC Inline ASM GCC内联汇编
- [ASM]Linux平台内联汇编实例
- 内联汇编 实现 strlen
- sunwen:VC内联ASM汇编学习笔记【转】
- Visual C 中 Inline ASM 内联汇编的使用
- hraarchiacal baysian
- 新商业暗流下的迁徙与O2O行业的集体突围-2016年3月江西IDC排行榜与发展报告
- JAVA中Socket数据接收
- Debug和release版本区别
- 深入理解Java之内部类
- 用asm内联汇编实现系统调用
- 数据库 杂记
- CF_1A_TheatreSquare
- 我的c++第二次程序1
- Spring框架的IoC容器详解
- 问题 F: C语言习题 不等长字符串排序
- Java - 给编译器看的Annotation
- Numbers That Count
- C/C++中的函数指针