zoukankan      html  css  js  c++  java
  • lab4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

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

    一.实验原理

    1.1系统调用的意义

    (1)把用户从底层的硬件编程中解放出来

    (2)极大的提高了系统的安全性

    (3)使用户程序具有可移植性

    1.2系统调用过程

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

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

    (3)Intel Pentium II中引入了sysenter指令。

    1.3参数传递

    (1)进程必须指明需要哪个系统调用,这需要传递一个名为 系统调用号的参数,使用eax寄存器传递系统调用号。

    (2)每个参数的长度不能超过寄存器的长度,即32位。

    (3)在系统调用号(eax)之外,参数的个数不能超过6个(ebx,ecx,edx,esi,edi,ebp)。

    (4)如果参数超过6个,就将一个寄存器变成指针指向一块内存区域,区域中连续保存着参数。

    1.4内嵌汇编语法

    __asm__(

        汇编语句模版:

        输出部分:

        输入部分:

        破环描述部分);

    二.实验过程

    2.1调试课件上的例子程序,调用系统调用time(),"纯"C程序如下:

    #include <stdio.h>
    #include <time.h>
    
    int main()
    {
            time_t tt;
            tt = time(NULL);
            struct tm *t;
            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;
    }

    2.2使用嵌入式汇编调用time系统函数,程序如下:

    #include <stdio.h>
    #include <time.h>
    
    int main()
    {
            time_t tt;
            struct tm *t;
    
            asm volatile(
            "mov $0,%%ebx
    	"   //传递参数
            "mov $0xd,%%eax
    	"//传递系统调用号
            "int $0x80
    	"       //触发128号中断
            "mov %%eax,%0
    	"    //将返回值保存到天天变量中
            :"=m"(tt)
            );
            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;
    }

    2.3 自己选择系统调用,编程调用,我选择的是getuid,该函数返回用户的ID值,c语言程序如下:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main()
    {
        
        int uid;
        uid =getuid();
        printf("uid is %d
    ",uid);
        return 0;
    }

    结果如下所示:

    2.4使用嵌入式汇编调用getuid,代码如下所示:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main()
    {
        int uid;
        //uid =getuid();
        asm volatile(
                "mov $0x18,%%eax
    	"//传递系统调用号
                "int $0x80
    	"    //触发128号中断
                "mov %%eax,%0
    	"//将结果保存到uid变量中
                :"=m"(uid)
            );
        printf("uid is %d
    ",uid);
        return 0;
    }

    三.实验总结

    系统调用的工作机制

    (1)传递参数包括函数参数和系统调用号

    (2)触发int 0x80中断

    (3)cpu切换到内核态执行系统函数

    本次应该是第一次自己写程序,而不是照抄老师的,虽然还有些不太熟练,但也有了很大的进步,希望自己能坚持到底。加油!!!!!!!!!

        

  • 相关阅读:
    HDU5269 字典树
    HDU1664 BFS + 数论 + 剪枝
    HDU1429 BFS + 状态压缩
    HDU1075 字典树 + 字符串映射
    HDU1247 字典树
    UVa 10256(凸包、线段交、点在多边形内)
    UVa 10652(旋转、凸包、多边形面积)
    牛客练习赛43D(贪心)
    牛客练习赛43F(推式子)
    Codeforces 1161B(判断旋转对称)
  • 原文地址:https://www.cnblogs.com/crowpurple/p/5299539.html
Copyright © 2011-2022 走看看