zoukankan      html  css  js  c++  java
  • 2019-2020-1 20199318《Linux内核原理与分析》第三周作业

    第2章 操作系统是如何工作的

    一、学习笔记

    1. 计算机的三大法宝:存储程序计算、函数调用机制、中断。
    2. 堆栈的具体作用有:记录函数调用框架、传递函数参数、保存返回值的地址、提供函数内部局部变量的存储空间等。
    3. 堆栈相关的寄存器:
       ESP:堆栈指针(stack pointer)
       EBP:基址指针(base pointer),在C语言中用作记录当前函数调用基址。
    4. 对于X86体系结构来讲,堆栈空间是从高地址向低地址增长的,如图所示:
    

    5. 堆栈操作:
       push:栈顶地址减少4个字节(32位),并将操作数放入栈顶存储单元。
       pop:栈顶地址增加4个字节(32位),并将栈顶存储单元的内容放入操作数。
    6. 其它一些指令:
       顺序执行:总是指向地址连续的下一条指令。
       跳转/分支:执行这样的指令时,CS:EIP的值会根据程序需要被修改。
       call:将当前CS:EIP 的值压入栈顶,CS:EIP指向被调用函数的入口地址。
       ret:从栈顶弹出原来保存在这样的CS:EIP的值,放入CS:EIP中。
    

    二、试验记录

    1.进程初始化代码

    asm volatile(
        "movl %1,%%esp
    	"   //将进程原堆栈栈顶的地址(这里是初始化的值)存入ESP寄存器。
        "pushl %1
    	"        //将当前EBP寄存器值入栈。
        "pushl %0
    	"        //将当前进程的EIP(这里是初始化的值)入栈。
        "ret
    	"             //ret命令正好可以让入栈的进程EIP保存到EIP寄存器中。
        "popl %%ebp
    	"      //与前面push指令结对出现。
    

    2.进程0启动,开始执行my_process(void)函数的代码。

    if(next->state==0)//next->state==0对应进程next对应进程曾经执行过。
    {
        //进行进程调度关键代码。
        asm volatile(
            "pushl %%ebp
    	"   //保存当前EBP到堆栈中。
            "movl %%esp,%0
    	" //保存当前ESP到当前PCB中。
            "movl %2,%%esp
    	" //将next进程的堆栈栈顶的值存到ESP寄存器。
            "movl $1f,%1
    	"   //保存当前进程的EIP值,下次恢复进程后将在标号1开始执行。
            "pushl %3
    	"      //将next进程继续执行的代码位置(标号1)压栈。
            "ret
    	"           //出栈标号1到EIP寄存器。
            "1:	"              //标号1,即next进程开始执行的位置。
            "pop1 %%ebp
    	"    //恢复EBP寄存器的值。
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        );
        my_current_task=next;
        printk(KERN_NOTICE ">>>switch %d to %d<<<
    ",prev->pid,next->pid);
    }
    else
    {
        next-state=0;
        my_current_task=next;
        printk(KERN_NOTICE ">>>switch %d to %d<<<
    ",prev->pid,next->pid);
    //转换到新的进程中
        asm volatile(
          "pushl %%ebp
    	"   //保存当前EBP到堆栈中。
          "movl %%esp,%0
    	" //保存当前ESP到当前PCB中。
          "movl %2,%%esp
    	" //载入next进程的栈顶地址到ESP寄存器。
          "movl %2,%%ebp
    	" //载入next进程的堆栈基地址到EBP寄存器
          "movl $1f,%1
    	"   //保存当前EIP寄存器值到PCB,这里$1f是指上面的标号1。
          "push %3
    	"       //把即将执行的进程的代码入口地址入栈。
          "ret
    	"           //出栈进程的代码入口地址到EIP寄存器。
          : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
          : "m" (next->thread.sp),"m" (next->thread.ip)
        );
    }
    

    3.对上述代码的堆栈调用过程进行分析。

    为了分析简单,假设系统只有两个进程,分别是进程0和进程1.进程0由内核启动时初始化执行,然后需要进程调度,开始执行进程1。下面从进程1被调度开始分析堆栈变化,因为进程1从来没有被执行过,是第一次被调度执行,此时执行else中的代码。
    

    到这里开始执行进程1,如果进程1执行的过程中发生了进程调度,进程0重新被调度执行了,应该执行前述if中的代码,具体的堆栈变化与上图所示过程相似。
    

    总结

    本章内容最重要的是进程的切换,进程在执行过程中,当时间片用完需要进程切换时,需要先保存当前的进程执行的上下文环境,下次进程被调度时,需要恢复进程的上下文环境。这样实现多道程序的并发执行。
    

  • 相关阅读:
    一个简单的进程察看器
    查找素数的程序
    两种动态创建对象的方法
    我对企业管理信息系统的看法
    下定决心,准备买dopod535,做基于M$ smartphone 2003(ce.net 4.2)的开发了
    工作流中对于事务处理的思考
    第二次安装.net2005地感受
    贴一个Microsoft Business Framework的图片上来,可能有些兄弟还不知道。
    SizeOf与Structure与Managed Code
    校园招聘技术面试方面的小题目
  • 原文地址:https://www.cnblogs.com/SunMaolin/p/11604074.html
Copyright © 2011-2022 走看看