2020-2021-1 20209302毕慧敏 《Linux内核原理与分析》第五周作业

第四章:系统调用的三层机制

一、实验楼实验四:

(一)使用库函数API和C代码中嵌入汇编代码触发同一系统调用

在/LinuxKernel/linux-3.18.6/arch/x86/syscalls目录下选取20号getpid进行调用,

编译并执行如下:

getpid20209302.c源代码如下:

(二)C代码中嵌入汇编代码进行系统调用

修改getpid20209302.c 嵌入汇编代码,编译并执行。

源代码如下:

分析__asm__ __volatile__函数中汇编语言的参数传递方式,首先将EBX置空,然后将系统调用号20传入EAX寄存器,在16进制中,0x14表示十进制的2,然后运行int $0x80指令,产生中断向量为128的编译异常,进入内核后开始执行中断向量128对应的中断服务程序system_call,根据EAX寄存器存储的系统调用号调用getpid(),将返回值传回用户态参数pid。

二、本周知识总结

1.系统调用3层机制:

第一步,系统调用的库函数就是读者使用的操作系统提供的API,调用软中断向内核发出中断请求;

第二步,CPU切换到内核态并开始执行一个system_call和系统调用内核函数,具体通过int $0x80触发系统调用的执行;

第三步,进入内核,通过系统调用号将API函数和系统调用内核函数关联起来进行调用。

参数传递:系统调用中,用户态切换到内核态,两种执行模式使用不同堆栈,参数传递通过特殊寄存器来进行。在x86-32中,EAX用于传递系统调用号,其余参数按顺序赋值给EBX,ECX,EDX,ESI,EDI和EBP,参数个数一般不超过6个。如果超过6个就把一个寄存器作为指针指向内存用于存储参数。

2.内核态和用户态的区别

  内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态,对所有的指令包括特权指令都可以执行。

  用户态:处于低的执行级别下,代码只能在级别允许的特定范围内活动。在日常操作下,执行系统调用的方式是通过库函数,库函数封装系统调用,为用户提供接口以便直接使用。

3.系统调用的意义是操作系统为用户态进程与硬件设备进行交互提供了一组接口。

4.一个API可能只对应一个系统调用,也可能内部由多个系统调用实现,一个系统调用也可能被多个API调用。

5.内核通过给每个系统调用一个编号来区分,即系统调用号,将API函数xyz()和系统调用内核函数sys_xyz()关联起来了。

6.传递参数时参数按顺序赋值给EBX、ECX、EDX、ESI、EDI、EBP。如果参数超过6个,就把某一个寄存器作为指针指向内存,这样可以通过内存来传递更多的参数

7.应用程序系统调用(API)和系统调用不同的API知识函数定义。系统调用是通过软中断向内核发出中断请求。

 

posted @ 2020-11-08 01:44  20209302毕慧敏  阅读(164)  评论(0编辑  收藏  举报