linux系统调用实验,《Linux内核分析》之触发一个系统调用实验总结

前言 系统调用列表中可用的很多,可惜对用代码进行系统调用不太清楚,只好从网上窃取了一份,地址在最后放上。此处以fork()为例。

实验及代码 fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 [infobg class="notice" closebtn="" color="" bgcolor=""]

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值: 1)在父进程中,fork返回新创建子进程的进程ID; 2)在子进程中,fork返回0; 3)如果出现错误,fork返回一个负值; [/infobg]

使用库函数API调用 [toggle hide="yes" title="使用库函数API" color=""]

代码

#include

#include

#include

int main ()

{

pid_t fpid;

int count=0;

fpid=fork();

if (fpid < 0)

printf("error in fork!");

else if (fpid == 0)

{

printf("I am the child process, my process id is %dn",getpid());

count++;

}

else

{

printf("I am the parent process, my process id is %dn",getpid());

count++;

}

printf("Result is: %dn",count);

return 0;

}

效果图

da6d0519c334062041a2c631d253d782.png [/toggle]

使用C代码中嵌入汇编代码调用 [toggle hide="yes" title="使用C代码中嵌入汇编代码调用" color=""]

代码

#include

#include

#include

int main ()

{

pid_t fpid;

int count=0;

asm volatile(

"mov $0,%%ebxnt"

"mov $0x2,%%eaxnt"

"int $0x80nt"

"mov %%eax,%0nt"

:"=m"(fpid)

);

if (fpid < 0)

printf("error in fork!");

else if (fpid == 0)

{

printf("I am the child process, my process id is %dn",getpid());

count++;

}

else

{

printf("I am the parent process, my process id is %dn",getpid());

count++;

}

printf("Result is: %dn",count);

return 0;

}

效果图

e1083189dbe3a0bc661d1fa89eb8f7a7.png [/toggle]

使用C代码中嵌入汇编代码实验测试 [toggle hide="yes" title="使用C代码中嵌入汇编代码实验测试" color=""]

代码

#include

#include

#include

int main ()

{

pid_t fpid;

int count=0;

asm volatile(

"mov $0,%%ebxnt"

"mov $0xd,%%eaxnt"

"int $0x80nt"

"mov %%eax,%0nt"

:"=m"(fpid)

);

if (fpid < 0)

printf("error in fork!");

else if (fpid == 0)

{

printf("I am the child process, my process id is %dn",getpid());

count++;

}

else

{

printf("I am the parent process, my process id is %dn",getpid());

count++;

}

printf("Result is: %dn",count);

return 0;

}

效果图

430b030cf19589737123cd5afe1a4ac5.png [/toggle]

分析 此处依旧以分析汇编为例(主要api没可分析的)。 首先将ebx清零,使用eax传递系统调用号,此处设为2,之后fork()函数(其系统调用对应的api)运行,期间触发int 0x80的中断完成由用户态进入内核态的转变过程,在执行完系统调用后,其系统调用的返回值使用eax存储。 int 0x80的中断向量对应着system_call()内核代码的入口,中间执行到对应的system_fork()中断服务程序,之后ret_from_sys_call,过程中可能发生进程调度,若没发生则返回到用户态继续进行其他的。

4176ca2e195f68e7ca5f68639bc55761.png 当初由于没仔细看视频于是有了上面最后的代码实验测试,在eax处设了个13,调成time的系统调用号了,故最后一张图中打印出来的仅有一个主程序。

总结 系统通过中断的方式完成用户态到内核态的转换过程,同时调用系统函数实现系统功能。当进入系统中断时,先保护现场,即保存需要用到的寄存器的数据,中断完成后恢复现场,即退出中断程序,恢复保存寄存器的数据。 windCoder原创作品转载请注明出处

参考资料 《Linux内核分析》MOOC课程

http://mooc.study.163.com/course/USTC-1000029000 实验代码参考地址:http://blog.csdn.net/myfather103/article/details/44496605

本文同步分享在 博客“蜜汁炒酸奶”(other)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值