原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
如果我写的不好或者有误的地方请留言
-
题目自拟,内容围绕系统调用的工作机制进行;
-
博客中需要使用实验截图
-
博客内容中需要仔细分析汇编代码调用系统调用的工作过程,特别是参数的传递的方式等。
-
总结部分需要阐明自己对“系统调用的工作机制”的理解。
实验报告:
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 ",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 " 11 "mov $0xd,%%eax " 12 "int $0x80 " 13 "mov %%eax,%0 " 14 :"=m"(tt) 15 ); 16 t = localtime(&tt); 17 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); 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! "); 11 } 12 else if(fpid == 0) 13 { 14 printf("i am child,process id :%d. ",getpid()); 15 } 16 else 17 { 18 printf("i am parent,process id :%d. ",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 " 9 "int $0x80 " 10 "mov %%eax,%0 " 11 :"=m"(fpid) 12 ); 13 14 if(fpid < 0) 15 { 16 printf("error in fork! "); 17 } 18 else if(fpid == 0) 19 { 20 printf("i am child,process id :%d. ",getpid()); 21 } 22 else 23 { 24 printf("i am parent,process id :%d. ",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.应用程序、封装例程、系统调用处理程序、系统调用服务例程 关系图
懒得画了 引用课件中的图