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\n",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\n\t"   //传递参数
        "mov $0xd,%%eax\n\t"//传递系统调用号
        "int $0x80\n\t"       //触发128号中断
        "mov %%eax,%0\n\t"    //将返回值保存到天天变量中
        :"=m"(tt)
        );
        t = localtime(&tt);
        printf("time:%d-%d-%d %d:%d:%d\n",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\n",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\n\t"//传递系统调用号
            "int $0x80\n\t"    //触发128号中断
            "mov %%eax,%0\n\t"//将结果保存到uid变量中
            :"=m"(uid)
        );
    printf("uid is %d\n",uid);
    return 0;
}

 

 

三.实验总结

系统调用的工作机制

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

(2)触发int 0x80中断

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

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

 

 

 

    

posted on 2016-03-20 20:42  crowpurple  阅读(263)  评论(0编辑  收藏  举报

导航