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

时间:2023-02-11 09:54:20

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

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

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

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

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

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

实验报告:

1.首先完成time系统调用

mytime.c是直接利用API函数

 #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+,t->tm_mon+,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
return ;
}

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

 #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"
"mov %%eax,%0\n\t"
:"=m"(tt)
);
t = localtime(&tt);
printf("time:%d-%d-%d %d:%d:%d\n",t->tm_year+,t->tm_mon+,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
return ;
}

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

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

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

myfork.c是直接利用API

 include <stdio.h>
#include <unistd.h> int main()
{
pid_t fpid;
fpid = fork();
if(fpid < )
{
printf("error in fork!\n");
}
else if(fpid == )
{
printf("i am child,process id :%d.\n",getpid());
}
else
{
printf("i am parent,process id :%d.\n",getpid());
}
return ;
}

myasmfork.c是通过嵌入式汇编

 nclude <unistd.h>

 int main()
{
pid_t fpid; asm volatile(
"mov $0x2,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
:"=m"(fpid)
); if(fpid < )
{
printf("error in fork!\n");
}
else if(fpid == )
{
printf("i am child,process id :%d.\n",getpid());
}
else
{
printf("i am parent,process id :%d.\n",getpid());
}
return ;
}

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

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

3.思路都是一样的:

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

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

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

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

4.需要记住的:

a.系统调用的意义:

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

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

使用户程序具有可移植性

b.API和系统调用

API只是一个函数定义

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

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

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

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

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

5.一个很重要的东西

系统调用号

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

懒得画了 引用课件中的图

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