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

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

如果我写的不好或者有误的地方请留言

  1. 题目自拟,内容围绕系统调用的工作机制进行;

  2. 博客中需要使用实验截图

  3. 博客内容中需要仔细分析汇编代码调用系统调用的工作过程,特别是参数的传递的方式等。

  4. 总结部分需要阐明自己对“系统调用的工作机制”的理解。

实验报告:

1.首先完成time系统调用

mytime.c是直接利用API函数

 1 #include <stdio.h>
 2 #include <time.h>
 3 
 4 int main()
 5 {
 6         time_t tt;
 7         tt = time(NULL);
 8         struct tm *t;
 9         t = localtime(&tt);
10         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);
11         return 0;
12 }

myasmtime.c是利用嵌入式汇编进行系统调用

 1 #include <stdio.h>
 2 #include <time.h>
 3 
 4 int main()
 5 {
 6         time_t tt;
 7         struct tm *t;
 8 
 9         asm volatile(
10         "mov $0,%%ebx\n\t"
11         "mov $0xd,%%eax\n\t"
12         "int $0x80\n\t"
13         "mov %%eax,%0\n\t"
14         :"=m"(tt)
15         );
16         t = localtime(&tt);
17         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);
18         return 0;
19 }

打印输出结果 都正确显示了当前的时间

2.接下来实现自己的系统调用

myfork.c是直接利用API

 1 include <stdio.h>
 2 #include <unistd.h>
 3 
 4 int main()
 5 {
 6         pid_t fpid;
 7         fpid = fork();
 8         if(fpid < 0)
 9         {
10                 printf("error in fork!\n");
11         }
12         else if(fpid == 0)
13         {
14                 printf("i am child,process id :%d.\n",getpid());
15         }
16         else
17         {
18                 printf("i am parent,process id :%d.\n",getpid());
19         }
20         return 0;
21 }

myasmfork.c是通过嵌入式汇编

 1 nclude <unistd.h>
 2 
 3 int main()
 4 {
 5         pid_t fpid;
 6 
 7         asm volatile(
 8         "mov $0x2,%%eax\n\t"
 9         "int $0x80\n\t"
10         "mov %%eax,%0\n\t"
11         :"=m"(fpid)
12         );
13 
14         if(fpid < 0)
15         {
16                 printf("error in fork!\n");
17         }
18         else if(fpid == 0)
19         {
20                 printf("i am child,process id :%d.\n",getpid());
21         }
22         else
23         {
24                 printf("i am parent,process id :%d.\n",getpid());
25         }
26         return 0;
27 }

实验结果都可以创建一个新的进程

3.思路都是一样的:

a.首先将中断号填入%eax

b.然后执行中断int $0x80

c.最后将结果返回到内存变量中

d.如果要传递参数 可以将参数存放在寄存器中做操作

4.需要记住的:

a.系统调用的意义:

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

极大的提高了系统的安全性

使用户程序具有可移植性

b.API和系统调用

API只是一个函数定义

系统调用通过软中断向内核发出一个明确的请求

LinbC库定义的一些API引用了封装例程

一般每个系统调用对应一个封装例程

库再用这些封装例程定义出给用户使用的API

不是每个API都对应一个特定的系统调用

5.一个很重要的东西

系统调用号

6.应用程序、封装例程、系统调用处理程序、系统调用服务例程 关系图

懒得画了 引用课件中的图

 

posted @ 2016-03-18 14:41  ailx10  阅读(443)  评论(0编辑  收藏  举报