• 2020-2021-1 20209309《Linux内核原理与分析》第五周作业


    实验过程

    查看系统调用号


    这里使用的是getpid函数与mkdir函数,对应的系统调用号为20与39.

    实现系统调用

    getpid函数
    #include<stdio.h>
    #include<unistd.h>
    int main()
    {       
          int pid;
          pid=getpid();
          printf("the pid is %d",pid);
          return 0;  
    }
    


    使用汇编代码实现:

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
          int pid;
          asm volatile(
                "mov $0x14,%%eax
    	"
                "int $0x80
    	"
                "mov %%eax,%0
    	"
                :"=m"(pid));
          printf("the pid is %d
    ",pid);
          return 0;
    }
    


    汇编代码细化了调用过程,getpid函数没有参数,首先将对应的系统调用号传入到ax寄存器中,int指令使系统内陷,执行相应的系统调用,最后返回值存入ax寄存器中,将ax中的返回值取出放入变量pid,打印输出。

    mkdir函数
    #include<stdio.h>
    #include<unistd.h>
    int main(){
          int ret;
          char *dir="dir";
          asm volatile(
                "movl %1,%%ebx
    	"
                "movl $0x27,%%eax
    	"
                "int $0x80"
                :"=a"(ret)
                :"b"(dir));
          printf("the ret is %d
    ",ret);
          return 0;
    }
    


    与上面的getpid函数相比,mkdir函数对应多了一个参数,其需要传入一个字符数组,这里以一个指针的形式传入到寄存器bx中,其他的操作与getpid函数无异。

    小结

    系统调用的三层皮:API、中断向量对应的system_call、中断服务程序sys_xyz
    API:应用程序接口是一个函数定义,系统调用通过软中断向内核发出一个明确的请求。
    系统调用:操作系统为用户态进程与硬件设备进行交互提供了一组接口。
    当API中包含系统调用时,通过系统调用号进入相应的系统调用,然后使用软中断进入内核态。中断发生后会保护现场,将用户的当前栈顶地址,当时的状态字和cs:eip的值进行压栈。之后进入由用户态切换到内核态,处理完中断程序后还原现场,返回用户态。
    xyz()函数,是系统调用对应的API,这个应用程序编程接口里面封装了一个系统调用,这个系统调用会触发一个int 0x80的中断,0x80这个中断向量对应着system_call这个内核代码的起点,这个内核代码里面会有SAVE_ALL,然后执行到sys_xyz()中断服务程序,进入程序里面处理,在中断服务程序执行完之后会ret_from_sys_call,在return的过程中可能会发生进程调度(这是一个进程调度的时机),如果没有进程调度,就会iret,回到用户态接着执行。

  • 相关阅读:
    requestAnimationFrame
    js来监控复制粘贴
    nodejs事件循环
    前端路由
    js基础查漏补缺(更新)
    http & https & http2.0
    进度条方案
    移动端适配方案
    性能优化之节流、防抖
    altium designer 里如何设置PCB默认字符默认大小(PCB丝印)
  • 原文地址:https://www.cnblogs.com/yanzs/p/13945080.html
Copyright © 2020-2023  润新知