第一部分 课本学习

用户态、内核态和中断

  • 1.内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态,对所有的指令包括特权指令都可以执行。
  • 2.用户态:处于低的执行级别下,代码只能在级别允许的特定范围内活动。在日常操作下,执行系统调用的方式是通过库函数,库函数封装系统调用,为用户提供接口以便直接使用。
    -3.Intel x86 CPU有4种不同的执行级别0、1、2、3,Linux只使用了其中的0和 3两个级別分别表示内核态和用户态。用户态和内核态很显著的区别方法就是CS:EIP的指向范围,内核态cs:eip的值是任意的,即可以访问所有的地址空间。用户态只能访问其中的一部分内存地址(0x00000000-0xbbbbbbbf),0xc0000000以上的地址只能在内核态下访问。
  • 4.中断处理是从用户态进入内核态的主要方式,系统调用是一种特殊的中断。从用户态切换到内核态时,中断/int指令会在堆栈上保存用户态的寄存器上下文,其中包括用户态栈顶地址、当时的状态字、当时的cs:eip的值,还有内核态的栈顶地址、内核态的状态字、中断处理程序的入口。中断发生后的第一件事就是保存现场,保存一系列的寄存器的值;中断处理结束前的最后一件事就是恢复现场,退出中断程序,恢复保存寄存器的数据。

    系统调用

  • 1.系统调用的意义:把用户从底层的硬件编程中解放出来、极大地提高系统的安全性、使用户程序具有可移动性。
  • 2.系统调用的库函数就是读者使用的操作系统提供的API(应用程序编程接口),API只是函数定义。系统调用是通过软中断向内核发出了中断请求,int指令的执行就会触发一个中断请求。Libc库函数定义的一些API内部使用了系统调用的封装例程,其主要目的是发布系统调用,使程序员在写代码时不需要用汇编指令和寄存器 传递参数来触发系统调用。一般每个系统调用对应一个系统调用的封装例程,函数库再用这些封装例程定义出给程序员调用的API,这样把系统调用最终封装成方便程序员使用的库函数。
    如下图所示,User mode表示用户态,kernel mode表示内核态。Xyz()就是一个API函数,是系统调用对应的API,其中封装了一个系统调用,会触发int $0x80的中断,对应system_call内核代码的起点,即中断向量0X80对应的中断服务程序入口,内部会有sys_xyz()系统调用处理函数,执行完sys_xyz()后会ret_from_sys_call,这里是进程调度最常见的调度时机点。如果没有发生进程调度,就会执行iret再返回到用户态接着执行。系统调用的3层机制分别为xyz(),system_call和sys_xyz()。
  • 3.当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。在Linux中是通过执行int$0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常,Intel Pentium II 中引入了sysenter指令(快速系统调用),2.6已经支持。除了系统调用外,系统调用也可能需要传递参数。内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数,使用eax寄存器。系统调用也需要输入输出参数,例如:实际的值,用户态进程地址空间的变量的地址,甚至是包含指向用户态函数的指针的数据结构的地址。system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。一个应用程序调用fork()封装例程,那么在执行into$0x80之前就把eax寄存器的值置为2(即_NR_fork)。这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号,进入sys_call之后,立即将eax的值压入内核堆栈。寄存器传递参数具有如下限制: 1)每个参数的长度不能超过寄存器的长度,即32位 2)在系统调用号(eax)之外,参数的个数不能超过6个(ebx, ecx,edx,esi,edi,ebp) 3)超过6个怎么办?超过6个的话就把某一个寄存器作为一个指针,指向某一块内存。

    第二部分 使用库函数API和C代码中嵌入汇编代码触发同一个系统调用

  • 一、编写程序输出当前系统时间
    编写time.c程序,编译后结果如下:

    在C代码中嵌入汇编代码触发系统调用,然后编译程序,发现了问题,通过查阅资料,发现是版本问题:

    下载安装gcc-4.8后解决此问题,运行结果如下:
  • 二、实验楼实验
    我选用了系统调用处理函数是sys_rename(),系统调用号是38。
    代码如图所示:

    C代码嵌入汇编代码如图所示:

    movl %2,%%ecx\n\t
    将newname存入eax寄存器;
    movl %1,%%ebx/n/t
    将oldname存入ebx寄存器;
    movl $0x26,%%eax\n\t
    系统调用号38(16进制是0X26)存入EAX寄存器。
    两个程序的运行结果分别如下:


    System_call根据传入的系统调用号在系统调用列表中查找到对应的系统调用内核函数,然后根据EBX寄存器和ECX寄存器中保存的参数调用列表中查找到对应的系统调用内核函数,然后分局EBX寄存器和ECX寄存器中保存的参数调用内核函数sys_rename,执行完后将执行结果存放到EAX寄存器中,将EAX寄存器的值传给ret。

2018-2019-1 20189203《Linux内核原理与分析》第五周作业的更多相关文章

  1. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  3. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  4. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  5. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  6. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. Oracle 11gR2 RAC DBCA无法识别ASM磁盘组(ORA-19504,ORA-15045,ORA-17502,ORA-15081)

    ORA-19504: failed to create file "+DATA" ORA-15045: ASM file name '+DATA' is not in refere ...

  2. Apache与php快速部署web服务

    [本文出自天外归云的博客园] 在一台服务器上临时起个web服务,读取服务器上的cfs文件内容并显示在页面上,做一个简单的web请求处理. 首先找到apache,在conf文件夹下vi httpd.co ...

  3. jQuery雷达扫描切换幻灯片代码

    基于jQuery雷达扫描切换幻灯片代码.这是一款切换效果类似雷达扫描,支持鼠标滚轮滚动切换.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class=" ...

  4. 微信公众号平台上传文件返回错误代码:40005 invalid file type

    错误原因:文件类型(后缀名)不符合要求. 具体到笔者的情况是:在将 MultipartFile 类型转换为File 类型时,方法 File.createTempFile("filename& ...

  5. MPU6050带字符驱动的i2c从设备驱动2

    #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #inclu ...

  6. hdoj:2075

    A|B? Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  7. 第四百零五节,centos7下搭建sentry错误日志服务器,接收python以及Django错误,

    第四百零五节,centos7下搭建sentry错误日志服务器,接收python以及Django错误, 注意:版本,不然会报错 Docker >=1.11Compose >1.6.0 通过d ...

  8. 框架源码系列二:手写Spring-IOC和Spring-DI(IOC分析、IOC设计实现、DI分析、DI实现)

    一.IOC分析 1. IOC是什么? IOC:Inversion of Control控制反转,也称依赖倒置(反转) 问题:如何理解控制反转? 反转:依赖对象的获得被反转了.由自己创建,反转为从IOC ...

  9. 【OCP|OCM】Oracle培训考证系列

     [OCP|OCM]Oracle培训考证系列  我的个人信息 网名:小麦苗 QQ:646634621 QQ群:618766405 我的博客:http://blog.itpub.net/26736162 ...

  10. Unity编辑器中分割线拖拽的实现

    GUI splitter control How can I make a GUI splitter control, similar to the splitter the console has? ...