您的位置:首页 > 运维架构 > Linux

MOOC《Linux内核分析》第四课

2016-03-17 21:54 525 查看

郑阳 原创作品转载请注明出处 《Linux内核分析》MOOC课程

当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。

在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常。

传参方面

内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数,使用eax寄存器

系统调用也需要输入输出参数

实际的值

用户态进程地址空间的变量的地址

甚至是包含指向用户态函数的指针的数据结的地址

寄存器 传递参数有如下的限制

每个参数的长度不能超过寄存器的长度

在系统调用号(eax)之外,参数的个数不能超过6过(ebx,ecx,edx,esi,edi,ebp),超过6个之后把每一个寄存器作为一个指针,指向一块内存

系统调用

system_call是linux中所有系统调用的[b]入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。[/b]

一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax的值置为2(即_NR_fork)。

这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心。

进入sys_call之后,立即将eax的值压入内核堆栈。

代码例程

time-asm.c 是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+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
return 0;
}


time.c 纯c语言进行中断调用

#include<stdio.h>
#include<time.h>
int main()
{
time_t tt;
struct tm *t;
tt = time(NULL);
t = localtime(&tt);

printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: