作业四:系统调用的工作机制

系统调用的工作机制

使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl

  

一、前情提要

系统调用操作系统为用户态进程与硬件设备进行交互提供了一组接口
API应用编程接口,是一个函数定义。
系统调用通过软中断向内核发出明确的请求。(eg:sysenter)

  

操作系统提供API和系统调用的关系
Libc库定义的一些API引用封装例程(wrapper routine).
一般每个系统调用对应一个封装例程。
库再用这些封装例程定义给用户的API.
    
不是每个API对应一个特定系统调用

返回值:1.大部分封装例程返回一个整数,值含义依赖于相应的系统调用;
2.-1,多数情况——内核不满足进程请求。
3.Libc定义errno变量包含特定出错码

  

  

二、两种方式调用系统调用的工作过程

 

用户态进程——(调用)——>系统调用
CPU——(切换)———内态核执行一个内核函数
linux中,通过执行int $0x80执行系统调用的,此汇编指令产生向量为128的编程异常。
中断向量0x80与system_call绑定起来
系统调用号将xyz和sys_xyz关联起来了。
系统调用三层皮 API XYZ,中断向量system_call,中断服务程序sys_xyz

  

system_call:Linux所有系统调用的入口点。

  

传参: 
1.内核实现不同系统调用
2.进程必须指明哪个系统调用,这需要传递一个名为系统调用号的参数。使用EAX寄存器传递 3.ebx,ecx,edx,esi,edi按照顺序存放前五个参数。
4.需要六个或六个以上参数时,应用一个单独的寄存器存放指向所有参数在用户空间地址的指针。 
5.返回值用eax

  

寄存器传递参数限制
 1.参数长度小于或等于寄存器长度(32位);
 2.除系统调用号(EAX),参数个数不超6个( EBX,ECX,EDX,ESI,EDI,EBP)

进入内核态后,可访问所有地址空间,通过用户块内存传递数据 下面使用的是getpid的系统调用,查表得  则系统调用号是20

  

1.库函数调用系统调用的工作过程

getpid()函数功能:取得进程识别码,返回值是进程的ID
这里直接使用getpid库函数进行系统调用。
传入的参数为NULL,通过EAX传入,再通过EAX将返回值传回。

  

2.汇编代码调用系统调用的工作过程

系统调用传递第一个参数ebx,这里是null
8行,将ebx清零;
9行,将20放入EAX
11行,返回值用EAX存储
总之,int 80触发中断,找到中断向量表,从表中寻找中断向量(或中断门),通过中断向量,找到系统调用表,
找到system_call JMP EAX*4+system_table

  

3.两种方式的编译运行结果分别是2999和3065.

(-14是实验出现了错误,使用了错误的系统调用号) 

4.总结部分

需要阐明自己对“系统调用的工作机制”的理解。

应用程序应该以某种方式(库函数或汇编代码)通知系统
告诉内核自己需要执行一个系统调用,希望系统切换到内核态。
内核就可以代表应用程序在内核空间执行系统调用。
通知内核的机制是靠软中断实现的:
通过引发异常将系统切换内核态执行异常处理程序(系统调用处理程序)。

  

注明“郑伟 + 参考书《内核分析与实现》 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

原文地址:https://www.cnblogs.com/zhengwei0712/p/5293565.html