zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209312《Linux内核原理与分析》第五周作业

    1.使用库函数API触发一个系统调用

    编写tim.c函数,使用time()获得tt变量之后,通过localtime()把tt变成struct tm这种结构 输出为可读的格式

    #include<stdio.h>
    #include<time.h>
    int main()
    {
            time_t tt;
            struct tm *t;
            tt = time(NULL);
            t = localtime(&tt);
            printf("time:%d:%d:%d:%d:%d:%d:
    ",t->tm_year+1900,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
            return 0;
    }      

    2.C代码中嵌入汇编代码触发一个系统调用

    常用的内嵌汇编常用的修饰限定符

     对于下面的代码,有如下解释:

    "movl $0,%%ebx
    	"表示把EBX寄存器清零
    "movl $0xd,%%eax
    	"表示把0xd放到了EAX寄存器里面,EXA寄存器用于传递系统调用号,d在十六进制里面表示13,所以系统调用号是13
    "int $0x80
    	"表示触发器系统调用陷入内核执行13号系统调用的内核处理函数
    "movl %%eax,%0
    	"系统调用有一个返回值,通过EAX寄存器返回,将EAX寄存器的值放到变量tt里面
    #include<stdio.h>
    #include<time.h>
    int main(){
            time_t tt;
            struct tm *t;
            asm volatile(
                    "movl $0,%%ebx
    	"
                    "movl $0xd,%%eax
    	"
                    "int $0x80
    	"
                    "movl %%eax,%0
    	"
                    :"=m"(tt)
                    :
                    :"eax","ebx"
            );
            t=localtime(&tt);
            printf("time:%d:%d:%d:%d:%d:%d:
    ",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
            return 0;
    }

    3.C语言调用rename系统调用

    #include<stdio.h>
    int main()
    {
            int ret;
            char *oldname = "hello.c";
            char *newname = "newhello.c";
            ret = rename(oldname,newname);
            if(ret == 0)
            {
                    printf("Rnamed successfuly
    ");
            }
            else{
                    printf("Unable to rename the file
    ");
            }
            return 0;
    }      

    可以看到 改变后的文件夹里面已经没有hello.c 取代的则是newhello.c

     4.汇编语言调用rename系统调用

    #include<stdio.h>
    int main()
    {
            int ret;
            char *oldname = "hello.c";
            char *newname = "newhello_20209312.c";
            asm volatile(
                    "movl %2,%%ecx
    	"
                    "movl %1,%%ebx
    	"
                    "movl $0x26,%%eax
    	"
                    "int $0x80"
                    :"=a"(ret)
                    :"b"(oldname),"c"(newname)
            );
            if(ret == 0)
            {
                    printf("Rnamed successfuly
    ");
            }
            else{
                    printf("Unable to rename the file
    ");
            }
            return 0;
    }   

    #include <stdio.h>
    int main()
    {
        char* oldname="hello.c";
        char* newname="new1hello_9312.c";
        int ret;
        asm volatile(
            "movl %1,%%ebx
    	"
            "movl %2,%%ecx
    	"
            "movl $0x26,%%eax
    	"
            "int $0x80
    	"
            "movl %%eax,%0"
            :"=m"(ret)
            :"b"(oldname),"c"(newname)
            );
        if(ret==0)
            printf("Rename Successfully!
    ");
        else
            printf("Unable to rename the file!
    ");
        return 0;
    }

    上面的代码运行结果如下:

    关于出现的两个error 处理结果是用-m32编译就好了

    gcc rename_asm.c -o 20209312_test -m32

     5.总结

      在linux中,将程序的运行空间分为内核空间与用户空间(内核态和用户态),在逻辑上它们之间是相互隔离的,因此用户程序不能访问内核数据,也无法使用内核函数。当用户进程必须访问内核或使用某个内核函数时,就得使用系统调用(System Call)。在Linux中,系统调用是用户空间访问内核空间的唯一途径。

      系统调用就是一种特殊的接口。通过这个接口,用户可以访问内核空间。系统调用规定了用户进程进入内核的具体位置。

           系统调用是用户进程进入内核的接口层,它本身并非内核函数,但它是由内核函数实现,进入内核后,不同的系统调用会找到各自对应的内核函数,这些内核函数被称为系统调用的“服务例程”。比如系统调用getpid实际调用了服务例程为sys_getpid(),或者说系统调用getpid是服务例程sys_getpid()的“封装例程”。API和系统调用的区别

           具体步骤:用户进程-->系统调用-->内核-->返回用户空间。

    系统调用就是为了解决上述问题而引入的,是提供给用户的“特殊接口”。

         系统调用规定用户进程进入内核空间的具体位置。

        1.程序运行空间从用户空间进入内核空间。

        2.处理完后再返回用户空间。

      系统调用的三层皮:API(应用程序接口),中断向量system_call,中断服务程序sys_xyz,内核实现了很多不同的系统调用,进程必须指明需要用哪个系统调用,这需要传递一些参数。其中的系统调用号,是使用eax寄存器传递。系统调用也需要输入输出参数,例如:实际的值、用户态进程地址空间的变量的地址、包含指向用户态函数的指针的数据结构的地址system_call是Linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。
  • 相关阅读:
    安卓系统的文件管理神器Solid Explorer(v2.2)
    地月距离竟然如此遥远
    Android在争议中逃离Linux内核的GPL约束【转】
    gearman
    PHP基础学习
    函数式编程
    有向图的实现
    无向图的实现
    百度地图API获取数据
    python队列的实现
  • 原文地址:https://www.cnblogs.com/ZHANGwg11/p/13945162.html
Copyright © 2011-2022 走看看