《Linux操作系统分析》之使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

本篇文章分析的是使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用,来说明在Linux系统中,系统调用的实现机制。

相关知识

首先关于这篇文章会介绍一些用到的知识。

一、什么是内核态,什么又是用户态。

内核态:在高执行级别下,代码可以执行特权指令,访问任意的物理地址。

用户态:在相应的低执行状态下,代码的掌控范围受到限制,只能在对应级别允许的范围内活动。



当一个程序在用户态下执行的时,它不能直接访问内核数据结构或者内核的程序。然而,当应用程序运行在内核态下的时候,这些限制不再有效。每中CPU模型都为从用户态到内核态的转换提供了特殊的指令,反之亦然。一个程序的执行大部分时间都处于用户态下,只有需要内核所提供的服务的时候才切换到内核态。当内核满足了用户程序的请求后,它让程序又回到用户态下。

二、C代码中嵌入汇编代码

嵌入式汇编的格式如下:


下面是一些常用的嵌入汇编的限定符:


汇编到底有什么好处呢?
 1.提高速度和效率。(不过这种情况很少了,现在C/C++编译器的优化很厉害了)
 2.实现某些C语言中不具备、但为不同的机器所特有的功能。(这是主要原因)
 3.利用通用的汇编语言例程。(也常会遇到)

三、中断机制

中断机制的一些概念可以参考我上篇博客《Linux操作系统分析》之分析精简的Linux的内核中断和时间片轮询

但是在这里我们需要在介绍一下,中断和系统调用之间的关系。

系统调用是只是一种特殊的中断,通过trap陷阱,进入到内核态。其中包括以下的步骤。


四、应用接口编程和系统调用

应用接口编程是一个函数的定义,说明了如何获得一个给定的服务。

系统调用是通过软中断向内核态发出了一个明确的请求。

系统调用的意义:操作系统为用户态进程与硬件设备进行交互提供的一组接口。可以把用户从底层的硬件变成中解放出来,极大的提高了系统的安全性,使用户程序具有可移植性。


上图是系统调用的三个层次依次是:xyz函数(API)、system_ call(中断向量)和 sys_ xyz(中断服务程序)。

分析过程

在这里我调用getpid函数。当然也可以去看看还有什么其他的系统调用点击

使用库函数的实现代码如下:

#include<stdio.h>
#include<unistd.h>
int main(){
pid_t num;
num = getpid();
printf("this is process id :%u\n",num);
return 0;
}
然后进行编译,并运行,结果如下图:


我们可以得到如上的结果。

我们修改代码,使用嵌入的汇编来调用20号系统调用。

#include <stdio.h>
#include<unistd.h>
int main()
{
    pid_t pid;
    asm volatile(
        "movl $0,%%ebx\n\t"//将ebx寄存器清零,系统调用传递第一个参数使用ebx,这里是null
        "movl $0x14,%%eax\n\t"//将0xd放入eax中,0x14为20,传递系统调用号20
        "int $0x80\n\t"
        "movl %%eax,$0\n\t"//通过eax这个寄存器返回系统调用值,和普通函数一样
        :"=m"(pid)
    );
    printf("this process's pid is : %u\n",pid);
    return 0;
}

编译后运行结果和第一种情况一样。

总结:

Linux中是通过寄存器%eax传递系统调用号,所以具体调用fork的过程是:将20存入%eax中,然后进行系统调用.对于参数传递,Linux是通过寄存器完成的。Linux最多允许向系统调用传递6个参数,分别依次由%ebx,%ecx,%edx,%esi,%edi和%ebp这个6个寄存器完成。进程运行在用户态和内核态时使用不同的栈,分别叫做用户栈和内核栈。两者各自负责相应特权级别状态下的函数调用。系统调用时,进程不仅是用户态到内核态的切换,同时也要切换栈,这样内核态的系统调用才能在内核栈上完成调用。系统调用返回时,还要切换回用户栈,继续完成用户态下的函数调用。

备注:

杨峻鹏 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值