这次博客分为两部分,第一部分是实验,第二部分是教材。

第一部分:实验

这周实验的内容是使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用,教学案例给的是time()获取系统时间的函数,我用的是getpid()获取当前进程的pid的函数。前20个系统调用号如下图所示

20169210《Linux内核原理与分析》第六周作业-LMLPHP

我选择的是20号getpid(),获取的是当前进程的pid.

开始时Code中是没有函数的,我们来新建一个

20169210《Linux内核原理与分析》第六周作业-LMLPHP

创建好了之后我们首先使用库函数API来使用系统调用,代码如下。

20169210《Linux内核原理与分析》第六周作业-LMLPHP

其中sys/types.h是基本系统数据类型,是Unix/Linux系统的基本系统数据类型的头文件,含有size_t,time_t,pid_t等类型。

unistd.h是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数。

这些都是通过查资料得到的。

之后就是编译一下getpid.c然后运行得出结果。如图所示

20169210《Linux内核原理与分析》第六周作业-LMLPHP

我们可以看到执行结果是pid:3149

下一步就是使用C代码中嵌入汇编代码调用系统调用。创建getpid-asm.c并编写代码。

20169210《Linux内核原理与分析》第六周作业-LMLPHP

通过嵌入式汇编我们可以看到

mov $0, %%ebx\n\t
mov $0x14, %%eax\n\t
int $0x80\n\t
mov %%eax,%0\n\t
:"=m"(p)

第一句是指把ebx寄存器清零;第二句的14表示的是16进制的20,因为getpid的系统调用号是20,将20号放到eax寄存器中;第三句是早就设定好的,执行系统调用;第四句是将返回的结果在eax中放到%0中,%0指的就是p。至此系统调用完成,返回结果在p中。

接下来就是编译然后运行,如图所示

20169210《Linux内核原理与分析》第六周作业-LMLPHP

我们看到执行结果不是一样的,再执行一次

20169210《Linux内核原理与分析》第六周作业-LMLPHP

执行结果跟前两次的都不一样,因为每次调用进程都会改变,所以进程的pid也会不一样。

遇到的问题:

1.开始选系统调用是不知道每个系统调用的具体作用以及参数的个数及类型,经过查资料,看sys_call函数,清楚了一些系统调用的参数的类型以及个数,网址如下

http://lxr.free-electrons.com/source/include/linux/syscalls.h?v=3.18#L223

2.c语言的头函数开始时不知道写那个,后来上网查看别人写的系统调用,再加上对头函数的解释,这才明白sys/types.h和unistd.h的作用。

第二部分:教材

第7章中断和中断处理第8章下半部和推后执行工作。

又想中断处理程序运行的快,又想中断处理程序完成的工作量多,这两个目的显然有所抵触。鉴于两个目的之间存在此消彼长的矛盾关系,所以我们一般把中断处理切成两个部分或两半。中断处理程序是上半,收到一个中断就立即执行,但只做有严格时限的工作。这些工作都是在所有中断被禁止的情况下完成的,能够被允许稍后完成的工作会推迟到下半部去。

04-15 11:42