一、知识点总结

(一)用户态、内核态和中断

1.内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态

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

3.在Linux下0级表示内核态,3级表示用户态。

4.内核态cs:eip的值是任意的,即可以访问所有的地址空间。用户态只能访问其中的一部分内存地址。

5.中断处理是从用户态进入内核态的主要方式,系统调用是一种特殊的中断。中断/int指令会在堆栈上保存用户态的寄存器上下文,其中包括用户态栈顶地址、当时的状态字、cs:eip的值,以及内核态的栈顶地址、当时的状态字、中断处理程序入口。中断处理结束前的最后一件事就是恢复现场,退出中断程序,恢复保存寄存器的数据。

例:

interrupt(ex:int 0X80)//发生系统调用 save

cs:eip/ss:esp/eflags(current)to kernel stack //保存cs:eip的值,保存当前堆栈段寄存器当前栈顶和标志位寄存器 load cs:eip(entry of a specific ISR)and ss:eip(point to kenerl stack) //把当前的中断信号或系统调用相关中断服务例程入口加载到cs:eip中,把当前的堆栈段和esp加载到CPU

SAVE_ALL//保存现场 ...//内核代码,完成中断服务,发生进程调度

RESTORE_ALL//恢复现场

iret - pop cs:eip/ss:esp/eflags from kernel stack//iret对应相反的中断指令

(二)系统调用概述

1.系统调用的意义

操作系统为用户态进程与硬件设备进行交互提供的一组接口——系统调用

  • 把用户从底层的硬件编程中解放出来

  • 极大的提高了系统的安全性

  • 使用户程序具有可移植性

2.API(应用程序编程接口)与系统调用的关系

  • API是一个系统调用封装成的一个函数定义

  • 系统调用通过软中断向内核发出一个明确的请求

  • Libc库定义的一些API引用了封装例程,目的是发布系统调用,让程序员写代码的时候可以通过函数调用而非汇编指令触发一个系统调用

  • 一般每个系统调用对应一个封装例程,库再用这些封装例程定义出给用户的API

3.返回值

  • 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用

  • -1在多数情况下表示内核不能满足进程的请求

  • Libc中定义的errno变量包含特定的出错码

  • 应用程序、封装例程、系统调用处理程序及系统调用服务例程之间的关系:

  • 系统调用的三层皮:xyz(API)、system_call(中断向量)、sys_xyz(中断服务程序)

4.传参

  • 内核实现了很多不同的系统调用。

  • 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数

  • 使用eax寄存器传递系统调用号。

超过6个的情况下,使用某一个寄存器作为指针,进入内核态之后可以访问所有的地址空间,通过某一片区域传递参数。

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

1.使用库函数API来获取系统当前时间

2.C代码中嵌入汇编代码的写法

__asm__(

汇编语句模板:

输入部分:

输出部分:

破坏描述部分:);

汇编代码分析:

#include <stdio.h>
#include <time.h>
int main()
{
time_t tt;//int型数值
struct tm *t;
asm volatile(
"mov $0,%%ebx\n\t"//将ebx寄存器清零,系统调用传递第一个参数使用ebx,这里是null
"mov $0xd,%%eax\n\t"//将0xd放入eax中,0xd为13,传递系统调用号13
"int $0x80\n\t"
"mov %%eax,$0\n\t"//通过eax这个寄存器返回系统调用值
:"=m"(tt)
);
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;
}

限定符对照表:

3.用汇编方式触发系统调用获取系统当前时间

(四)实验

1.选择20号系统调用,getpid来获取当前进程的pid

2.实验内容:

  • 使用库函数API方式:

  • 使用C代码中嵌入汇编代码方式:

王玥【原创作品转载请注明出处】 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

最新文章

  1. 关于Block的简单使用
  2. 使用JSSDK集成微信分享遇到的一些坑
  3. Jquery 基本知识(一)
  4. AppScan8.0简单扫描
  5. ASP.NET MVC Error
  6. 验证中文、英文、电话、手机、邮箱、数字、数字和字母、Url地址和Ip地址的正则表达式
  7. 了解discuz!
  8. curl post传递json数据
  9. Python操作MySQL -即pymysql/SQLAlchemy用法
  10. OC基础 代理和协议
  11. Spring学习之切入点表达式
  12. Java消息队列-Spring整合ActiveMq
  13. CentOS正确关机方法
  14. WebService中的WSDL详解 及jmeter测试
  15. android view事件分发机制
  16. JDBC事务控制
  17. 本人亲身讲解本科期间学习Linux系统过程
  18. 用 wait-notify 写一段代码来解决生产者-消费者问题
  19. java 多线程面试
  20. 认识程序的执行:从高级语言到二进制,以java为例

热门文章

  1. BZOJ2306:[CTSC2011]幸福路径(倍增Floyd)
  2. Guava 的EventBus示例代码(简单笔记,后期补充)
  3. 【转】 最新版chrome谷歌浏览器Ajax跨域调试问题
  4. 随手练——DFS小练
  5. 1、pyspider安装
  6. 【转】系统去掉 Android 4.4.2 的StatusBar和NavigationBar
  7. Failed to fetch URL https://dl-ssl.google.com/android/repository/addons_list-2.xml
  8. 在ASP.NET Core上实施每个租户策略的数据库
  9. overflow的使用
  10. XML 的4种解析方式