网易云课堂 Linux内核分析(四)

来源:互联网 发布:数控编程指令大全 编辑:程序博客网 时间:2024/04/28 08:49

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

实验内容

使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

  • 选择一个系统调用(13号系统调用time除外),系统调用列表参见系统调用
  • 参考视频中的方式使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

实验过程及结果

参见实验报告

实验分析

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

    • 应用编程接口(Application program interface,API)和系统调用是不同的
      • API只是一个函数定义
      • 系统调用通过软中断向内核发出一个明确的请求
    • Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用)
      • 一般每个系统调用对应一个封装例程
      • 库再用这些封装例程定义出给用户的API
    • 不是每个API都对应一个特定的系统调用
      • API可能直接提供用户态的服务
        • 如,一些数学函数
      • 一个单独的API可能调用了几个系用调用
      • 不同的API可能调用同一个系统调用
    • 返回值
      • 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用
      • -1在多数情况下表示内核不能满足进程的请求
      • Libc中定义的errno变量包含特定的出错码
  • 用调用程序及服务例程

    • 当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数
      • 在Linux中使用过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的变成异常
    • 传参
      内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数
      • 使用eax寄存器来接收系统调用号
      • 系统调用所需的参数可以用寄存器传参,但有如下限制:
        • 每个参数的长度不能超过寄存器的长度
        • 在系统调用号(eax)之外,参数的个数不能超过6个(ebx,ecx,edx,esi,edi,ebp)
        • 超过6个则寄存器中可存入指针,相应的内存地址中存放参数

具体实践

使用8号系统调用(creat)来演示说明。
- 使用库函数API创建文件

#include<stdio.h>#include<fcntl.h>int main(){    int ret =0;    char* filename = "createfile1";    mode_t mode = 0755;    ret = creat(filename,mode);    printf("file %d create success\n",ret);    return 0;}

库函数int creat(const char *filename, mode_t mode)有两个参数,第一个为要创建文件名,第二个为创建文件的模式/访问权限,0755表示文件所有者可读可写可执行,文件所有者所在组他行,其用户可读可执行。

  • 使用C语言内嵌汇编带码实现
#include<stdio.h>#include<fcntl.h>int main(){    int ret =0;    char *filename = "createfile2";    mode_t mode = 0755;    asm volatile(            "movl $8,%%eax\n\t"            "int $0x80\n\t"            "movl %%eax,%0\n\t"            :"=m"(ret)            :"b"(filename),"c"(mode)            );    printf("file %d create success\n",ret);    return 0;}

在上面代码中,首先将系统调用号8传给寄存器eax,然后执行指令int $0x80执行数调用;creat函数的两个参数分别存入寄存器ebx和ecx中。

实验总结 

系统调用不但把用户从底层的硬件编程中解放出来,提高了编程的效率,也极大的提高了系统的安全性。                         

0 0
原创粉丝点击