API和系统调用实现同一方法

“平安的祝福 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

一、基本概念

1.1API和系统调用区别:

API只是一个函数定义;系统调用通过软中断向内核发出一个明确的请求。

Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用):一般每个系统调用对应一个封装例程;库再用这些封装例程定义出给用户的API

1.2大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用:

-1在多数情况下表示内核不能满足进程的请求;

Libc中定义的errno变量包含特定的出错码;

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

1.4当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。

在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常

1.5传参:

内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数,使用eax寄存器

1.6系统调用也需要输入输出参数,例如

实际的值,用户态进程地址空间的变量的地址,甚至是包含指向用户态函数的指针的数据结构的地址

1.7system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号

步骤:1.一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)。这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号。

2.进入sys_call之后,立即将eax的值压入内核堆栈。

二、具体例子

2.1系统调用函数getpid编写的程序:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
    printf("The current process ID is %d\n",getpid());
    return 0;
}

2.2使用嵌入式汇编实现的getpid程序:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
    int t;
    asm volatile(
                "mov $0,%%ebx\n\t"
                "mov $0x14,%%eax\n\t"  //其中getpid的系统调用数是20
                "int $0x80\n\t"
                "mov %%eax,%0"
                :"=m"(t)
                );
    printf("The current process ID is %d\n",t);
    return 0;
}

2.3分析汇编代码系统调用工作过程:

首先将ebx寄存器清空,将getpid的系统调用号传入寄存器eax,然后调用系统软中断。系统中断处理完成后,eax寄存器存储的是系统调用getpid的返回值,将eax寄存器的值赋值给用户空间的参数。

2.4程序的输出结果一样:

三、总结:

通过这次实验,大致了解用户程序如何执行系统调用的。流程:用户程序调用API——》封装例程——》中断向量实现系统程序的切换——》系统调用具体的汇编程序。

时间: 2024-08-06 03:24:20

API和系统调用实现同一方法的相关文章

Oracle官网JDK的API离线文档下载方法

最近在学习JAVA开发,使用频率最高的工具莫过于JAVA API,当我们身边没有可连接的网络,而又急需API文档时候,很明显我们需要在我们的电脑存储一份离线文档.下面是去Oracle官网下载API Documentation的步骤: 0.在地址栏输入http://www.oracle.com/index.html 进入Oracle官网,如下图: 1.把鼠标移到Downloads那里,不要点它哦!会看到展开一系列Oracle的产品下载,注意到第一列有个叫做“Popular Downloads” 红

快递api网接口快递调用方法

----------------实体类 [DataContract] public class SyncResponseEntity { public SyncResponseEntity() { } /// <summary> /// 需要查询的快递代号 /// </summary> [DataMember(Order = 0, Name = "id")] public string ID { get; set; } /// <summary> /

ValueError: The field authtoken.Token.user was declared with a lazy reference to &#39;api.user&#39;, but app &#39;api&#39; isn&#39;t installed解决方法

找到自己的python3.x,进入site-packages/django/contrib/admin/migrations文件目录下,除了__init__.py文件,其他的全部删除.(注意,切勿把__init__.py文件删了,也不要把contrib/contenttypes这个文件夹下的migrations删了,不然会导致migrate功能失效,就只能把django卸了重下). 转自:https://blog.csdn.net/cf313995/article/details/8434218

解决Gradle报错找不到org.gradle.api.internal.project.ProjectInternal.getPluginManager()方法问题

因为本地的AndroidStudio很久没用了,所以想要研究下github上的某个代码的时候,还得重新配下环境 打开了几个项目,都是提示如下错误 Error:Unable to find method 'org.gradle.api.internal.project.ProjectInternal.getPluginManager()Lorg/gradle/api/internal/plugins/PluginManagerInternal;'. Possible causes for this

学习ASP.NET Web API框架揭秘之“HTTP方法重写”

最近在看老A的<ASP.NET Web API 框架揭秘>,这本书对于本人现阶段来说还是比较合适的(对于调用已经较为熟悉,用其开发过项目,但未深入理解过很多内容为何可以这样“调用”).看到第四章了,有些内容看着虽能理解,但未遇到过具体的问题,看起来也就没有豁然开朗之感.同时,有些内容是一眼就觉得“这是干货”,可能是之前遇到过某些问题,当时用一些搓办法解决,但现在看到书中的示例就如获至宝.所以,就挑些单独能拎出来且马上就能在项目中应用的内容出来与大家分享交流下吧.其中会穿插一些框架中的知识点.不

百度地图API获得详细地名的方法

之前一直苦恼的一个问题就是当使用百度地图API进行反地理编码搜索的时候,最终得到的result只包含"枯燥"的省市区街道等信息,用于对客户的信息提示来说,这种"XX省XX市XX区XX路XX号"格式的信息往往不能给客户直观的概念,无法满足客户需求.反观百度地图.快的打车等LBS应用,它们可以为用户提供详细的地名等信息,让客户一目了然,它们是怎么做到的呢? 于是在查看了百度地图的文档的时候发现了ReverseGeoCoderResult类中的getPoiList方法,该

Android API 文档 离线秒开方法

也是近期才看Android开发,可是.它的API文档不管是在线还是离线的,实在是慢得不敢恭维.今天调试了一下.发现它自己请求了几个在线的文件,那几个文件由于谷歌被封的原因请求时间比較长.于是就查看了一下网页源代码将,这些请求的路径所有置空.发现打开速度立刻就上去了. 事实上替换的过程挺消耗电脑性能.大家就不用反复做了.直接在我的百度网盘下载就能够了. 使用方法和曾经一样.请到 reference/packages.html 開始你的Android 开发之旅. 下载地址 http://pan.ba

bootstrap Table API和一些简单使用方法

官网: http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/ 后端分页问题:后端返回"rows".""total,这样才能重新赋值 先初始化表格 $('#my-table').bootstrapTable({ method:'POST', dataType:'json', contentType: "application/x-www-form-urlencoded", cach

优秀的API接口设计原则及方法(转)

一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的打击就更大.如果API经常发生变化,用户就会失去对提供方失去信心,从而也会影响目前的业务. 但是我们为什么还要修改API呢?为了API看起来更加漂亮?为了提供更多功能?为了提供更好的性能?还是仅仅觉得到了改变了时候了?对于用户来说,他们更愿意使用一个稳定但是看起来不那么时髦的API,这并不意味着我们