哈工大计算机系统大作业2023

计算机系统

大作业

题     目  程序人生-Hello’s P2P    

专       业                    

学     号                  

班     级                    

学       生                   

指 导 教 师                    

计算机科学与技术学院

2022年5月

摘  要

本文对hello.c程序进行了详细的“解剖”,从预处理,编译,汇编,链接开始。然后对其顺利运行背后的流程进行了具体的探索,包括进程与内存的使用,中断,异常,信号的处理。最终结束进程,hello进程被父程序回收,进程结束。

关键词:预处理,编译,汇编,链接,进程,异常                

(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分

目  录

第1章 概述................................................................................................................ - 4 -

1.1 Hello简介......................................................................................................... - 4 -

1.2 环境与工具........................................................................................................ - 4 -

1.3 中间结果............................................................................................................ - 4 -

1.4 本章小结............................................................................................................ - 4 -

第2章 预处理............................................................................................................ - 5 -

2.1 预处理的概念与作用........................................................................................ - 5 -

2.2在Ubuntu下预处理的命令............................................................................. - 5 -

2.3 Hello的预处理结果解析................................................................................. - 5 -

2.4 本章小结............................................................................................................ - 5 -

第3章 编译................................................................................................................ - 6 -

3.1 编译的概念与作用............................................................................................ - 6 -

3.2 在Ubuntu下编译的命令................................................................................ - 6 -

3.3 Hello的编译结果解析..................................................................................... - 6 -

3.4 本章小结............................................................................................................ - 6 -

第4章 汇编................................................................................................................ - 7 -

4.1 汇编的概念与作用............................................................................................ - 7 -

4.2 在Ubuntu下汇编的命令................................................................................ - 7 -

4.3 可重定位目标elf格式.................................................................................... - 7 -

4.4 Hello.o的结果解析......................................................................................... - 7 -

4.5 本章小结............................................................................................................ - 7 -

第5章 链接................................................................................................................ - 8 -

5.1 链接的概念与作用............................................................................................ - 8 -

5.2 在Ubuntu下链接的命令................................................................................ - 8 -

5.3 可执行目标文件hello的格式....................................................................... - 8 -

5.4 hello的虚拟地址空间..................................................................................... - 8 -

5.5 链接的重定位过程分析.................................................................................... - 8 -

5.6 hello的执行流程............................................................................................. - 8 -

5.7 Hello的动态链接分析..................................................................................... - 8 -

5.8 本章小结............................................................................................................ - 9 -

第6章 hello进程管理...................................................................................... - 10 -

6.1 进程的概念与作用.......................................................................................... - 10 -

6.2 简述壳Shell-bash的作用与处理流程........................................................ - 10 -

6.3 Hello的fork进程创建过程........................................................................ - 10 -

6.4 Hello的execve过程.................................................................................... - 10 -

6.5 Hello的进程执行........................................................................................... - 10 -

6.6 hello的异常与信号处理............................................................................... - 10 -

6.7本章小结.......................................................................................................... - 10 -

第7章 hello的存储管理................................................................................... - 11 -

7.1 hello的存储器地址空间............................................................................... - 11 -

7.2 Intel逻辑地址到线性地址的变换-段式管理............................................... - 11 -

7.3 Hello的线性地址到物理地址的变换-页式管理.......................................... - 11 -

7.4 TLB与四级页表支持下的VA到PA的变换................................................ - 11 -

7.5 三级Cache支持下的物理内存访问............................................................. - 11 -

7.6 hello进程fork时的内存映射..................................................................... - 11 -

7.7 hello进程execve时的内存映射................................................................. - 11 -

7.8 缺页故障与缺页中断处理.............................................................................. - 11 -

7.9动态存储分配管理.......................................................................................... - 11 -

7.10本章小结........................................................................................................ - 12 -

第8章 hello的IO管理.................................................................................... - 13 -

8.1 Linux的IO设备管理方法............................................................................. - 13 -

8.2 简述Unix IO接口及其函数.......................................................................... - 13 -

8.3 printf的实现分析........................................................................................... - 13 -

8.4 getchar的实现分析....................................................................................... - 13 -

8.5本章小结.......................................................................................................... - 13 -

结论............................................................................................................................ - 14 -

附件............................................................................................................................ - 15 -

参考文献.................................................................................................................... - 16 -

第1章 概述

1.1 Hello简介

1.首先使用vs,devc++,codeblocks等编辑器写Hello.c文件,获得hello.c的源程序。这是所有的根本。

2.形式上的第二步是,在上述编辑器中进行编译运行,然后我们就可以得到hello的可执行文件,然后就得到我们熟悉的“黑框”运行界面,但是实际上这是综合了许多步骤的结果

3.实际上的第二步是C预处理程序(cpp)工作,hello.c源文件被预处理生成hello.i文件,具体过程是:cpp根据字符#开头的命令读取系统头文件的内容,例如#include<stdio.h>就是读取头文件stdio.h的内容,将其直接接入源文件中,得到新的C程序,其后缀一般为i,也就是我们说的hello.i文件。

4.C编译器ccl工作,将文本文件hello.i翻译成hello.s文件,这时的hello.s文件是汇编文件,具体后面会详细介绍。

5.汇编器as将hello.s翻译成机器语言指令,把这些指令打包成可重定位目标程序,结果保存在hello.o文件中,这个文件是二进制文件。

6.链接器ld将hello.o文件和已定义好的其他函数文件组装起来,例如hello.o文件中调用了printf函数,但是我们并没有定义这个函数,这个函数是C标准库函数,所以我们把这些函数也打包成.o文件,并与我们的hello.o文件组装成一个可执行目标文件,称hello。这样我们的hello.c文件就可以被执行了。

7.执行阶段。我们在shell中执行hello,在shell中输入./hello回车,这条命令就意味着shell要加载可执行文件hello,shell调用fork函数创建子进程,同时进行虚拟内存空间的映射,mmap对hello进程调用虚拟内存空间。

8.程序运行结束,shell父进程回收hello子进程及hello创建的子进程。

1.2 环境与工具

硬件环境:CPU:Intel i5 12400f

                    16GB主存 500 固态硬盘

软件环境:Windows10 64位操作系统;Ubuntu 20.04;gcc编译器;gdb。

1.3 中间结果

源程序:hello.c

预处理文件:hello.i

汇编文件:hello.s

可重定位目标文件:hello.o

可执行目标文件:hello

ELF格式文件:hello.elf;helloe.elf

反汇编文件:hello.txt;hello1.txt;hello2.txt

1.4 本章小结

       本章大致介绍了hello程序从执行到结束的全过程以及本实验用到的硬件环境及软件和中间生成的文件等。

(第1章0.5分)

第2章 预处理

2.1 预处理的概念与作用

       概念:预处理器cpp根据以字符#开头的命令修改原始的C程序。

       作用:根据源代码中的如#include<stdio.h>的代码修改源代码,将头文件接入源文件,替换宏和常量标识符,生成.i文件

2.2在Ubuntu下预处理的命令

       命令:gcc -E hello.c -o hello.i

2.3 Hello的预处理结果解析

解析:由文件大小可知,被预处理后的hello.c文件变大。预处理后的hello,i文件对hello.c文件进行了对库的插入,可以看到<stdio.h>文件中的内容被插入到hello.i文件,且进行了大量的定义,包括结构体,变量等。

2.4 本章小结

本章详细介绍了预处理的概念及作用,还具体的查看了hello.i文件,详细了解了预处理的过程及结果。

(第2章0.5分)

第3章 编译

3.1 编译的概念与作用

       概念:编辑器ccl将文本文件hello.i翻译成文本文件hello.s,它包括一个汇编语言程序。

       作用:生成hello.s文件,将高级语言翻译成汇编语言,更加贴近机器级       

3.2 在Ubuntu下编译的命令

       命令:gcc -S hello.i -o hello.s

3.3 Hello的编译结果解析

3.3.1数据:

       字符串:hello.c中有两个字符串,通过关键字string定义

       局部变量:局部变量存储在程序栈中,通过栈顶指针访问,例如:通过寄存器rbp存储栈顶指针的值,将立即数0,存储到栈顶指针的下一个位置,因为栈是向下增长而且数据类型是int型整数的所以,是-4.

       全局变量:使用global关键字进行声明,是全局符号.

       静态符号:使用static修饰的变量

       宏:使用#define进行宏定义的量

       立即数:直接在汇编代码中以$数字表示的就是立即数.例如:32

3.3.2操作

       赋值=:赋值根据操作数的不同选取不同的mov指令,操作数位均为64位要用movq操作;均为32位用movl;16位用movw;8位用movb;源操作数和目的操作数位数不相同选择movabsq或者movslq.

       算数操作:

  • 加操作:使用add a,b指令,意思是将a+b的值赋给b,根据操作数类型的不同选择不同的操作后缀.
  • 减操作:sub a,b指令.将b-a付给b,其余同add
  • 乘法:imul a,b将a*b的值赋给b,其余同上.
  • 逻辑操作:

与:and a,b a&b的值赋给b

非:nor a a取非的值赋给a

或:or a,b a|b的值赋给b

异或:xor a^b的值赋给b

  • 移位:

逻辑移位SHR k,D将D逻辑右移k位;

        SHL k,D将D逻辑左移k位;

算数移位:SAR k,D将D算数右移k位;

             SAL k,D将D算数左移k位;

  • 关系操作

a==b:判断a-b结果是否为0;根据ZF标志位判断,若为0则ZF为1,否则为0

!=:和上面类似,使用!ZF判断,与相等正相反.

>:有符号数大于通过!(SF^OF)&!ZF;无符号数通过!CF&!ZF(其中CF为进位标志位,SF位结果为负标志位,OF为溢出标志位).

<:有符号数小于通过SF^OF;无符号数通过CF判断.

>=:有符号数通过!(SF^OF);无符号数通过!CF.

<=:有符号数通过(SF^OF)|ZF;无符号数通过CF|ZF.

hello.c中argc!=3;是条件判断语句,这条语句编译为:cmpl $3,-20(%rbp),比较之后设置条件码不改变结果,根据上述的规则进行判断; hello.c中i<8,作为判断循环条件指令被编译为cmpl $7,-4(%rbp),并设置条件码,下一步将根据条件码及对应规则跳转.

控制转移:先使用cmp指令按照关系操作的规则设置标志位,再根据标志位是否为1,进行跳转.

在hello.c中有如下跳转.第一个比较栈中数据与20的大小如果相等就跳转到L2处,不相等就向下执行.

此处是判断栈中数据与0的大小然后进行的无条件跳转,就是不管结果是多少,标志位怎么设置都直接进行跳转

.

此处是判断栈顶数据与8的大小大于则跳转到L4,此时栈顶数据应该是循环变量i

  • 函数操作:调用函数使用指令callq.参数传递使用程序计数器PC,实际上是寄存器rip设置函数的起始地址,返回时使用rip设为函数后第一条指令的地址;参数传递:参数使用寄存器rsi,rdi等六个寄存器进行传递,参数个数超过6个的使用堆栈进行传递;局部变量:函数定义的局部变量存在堆栈中;返回值使用寄存器rax进行传递.在hello.c程序中涉及到了main函数,参数是int argc,char *argv[];print函数,参数是argv[1]和argv[2];exit函数.参数是1或0;sleep函数,参数是argv[3];getchar函数,无参数.

  

3.4 本章小结

本章介绍了编译过程及各种数据类型和操作在汇编代码中的实现过程,对编译器对不同的数据的实现和不同操作的实现都有了详细的了解,对汇编语言也有了初步的认识,对循环,跳转的实现都有了一定的了解

(第32分)

第4章 汇编

4.1 汇编的概念与作用

概念:汇编器as将hello.c翻译成机器语言指令,把这些指令打包成可重定位目标程序的格式,并将结果保存在目标文件hello.o中,hello.o是二进制文件,这个过程叫汇编.

作用:将.s文件转换为机器语言指令,生成.o文件.

4.2 在Ubuntu下汇编的命令

命令:gcc -c hello.s -o hello.o

4.3 可重定位目标elf格式

一般的可重定位目标文件格式如下图所示:

使用readelf -a hello.o>hello.elf生成hello.o的elf格式文件.

分析:

ELF头:开始是一个16字节大小的序列.然后是此elf文件的类型及该文件的内容顺序.该文件的版本,生成该文件的系统版本及目标文件的类型,机器类型等.最后是一个节头部表,包括了不同类型的节的大小.

节头:记载不同节的名称,类型,地址,偏移量,大小,全体大小,旗标,链接,信息,对齐.

重定位节:. rodata节:存放只读数据,包括:switch跳转表等;本程序中的L1,L0保存在.rodata节中;其他可重定位的文件,包括printf,puts,exit函数等

符号表:symbol table,保存链接程序中的函数,全局变量等信息,这在链接会具体介绍.

4.4 Hello.o的结果解析

使用objdump -d -r hello.o>hello.txt命令将反汇编文件重定向输出到hello.txt中

对比

①控制转移:hello.s中使用的控制转移是跳转到目标的名称如L3,L4等;而反汇编文件中是直接跳转到目的地址,显然机器语言是更加贴近计算机底层.

②函数调用:反汇编中函数直接调用的是main+偏移量的地址,显然是重定位后的地址,而hello.s调用的是函数名.

4.5 本章小结

本章对hello.o进行了elf分析,详细介绍了hello.elf的构成,还对hello.o文件反汇编,比较了反汇编结果与hello.s文件的区别,介绍了汇编语言与机器语言的不同之处.

(第41分)

第5章 链接

5.1 链接的概念与作用

概念:合并文件中涉及到的所有内容到一个可执行文件的过程.

作用:使编译轻量化,不用再具体的编写常见的函数,只需要在引用包含这个函数的库即可,而且可以将程序分解为更小的模块,方便管理,在更改时不必更改所有的部分,只需要更改要更改的并且重新编译即可.

5.2 在Ubuntu下链接的命令

Ld-ohello-dynamic-linker/lib64/ld-linux-x86-64.so.2/usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o

5.3 可执行目标文件hello的格式

ELF头:

 

同hello.o的一样都列出了elf文件的相关信息,但是具体信息有所不同.

节头:包括各节的名称,类型,地址等.

重定位节:

符号表:

 

5.4 hello的虚拟地址空间

使用edb加载hello,查看本进程的虚拟地址空间各段信息,并与5.3对照分析说明。  

由edb可知,程序被加载到地址为0x203000-0x204000的内存空间,

结合5.3的节头部表可知

.text节:0x32f8

.data节:0x4000

.bss节:0x0000

.symtab节:0x36d0

.rodata节:0x34d9

5.5 链接的重定位过程分析

objdump -d -r hello 分析hello与hello.o的不同,说明链接的过程。

前者为hello的反汇编文件,后者为hello.o的反汇编文件,同hello.txt相比,hello2.txt文件大小变大,内容增多,节数增多,最主要的是库函数被链接到了文件中.

过程:

  1. 链接器先将不同文件中的相同的节合并到一起,形成一个文件中的不同的节,这个文件就是可执行目标文件,然后申请一块虚拟地址,将地址赋给可执行目标文件中的每个节,此时程序中的指令和全局变量有了虚拟地址.
  2. 符号引用,链接器修改代码节和数据节对每个符号的引用,使他们被映射到正确的虚拟地址.
  3. 重定位条目当编译器遇到对最终位置位置的目标引用时,就会生成一个可重定位条目,代码的重定位条目放在.rel.txt中

5.6 hello的执行流程

①开始执行:_start、_libc_start_main

②执行main:_main、_printf、_exit、_sleep、_getchar

③退出:exit

程序名及地址如下:

_start 0x1100

main 0x11e9

_printf 0x10b0

_exit 0x10e0

_sleep 0x10f0

_getchar 0x10c0

5.7 Hello的动态链接分析

分析hello程序的动态链接项目,通过edb调试,分析在dl_init前后,这些项目的内容变化。要截图标识说明。

动态链接是将程序拆分成独立的部分,在程序运行时将其链接到一起,与静态链接不同的是不会把所有模块都编译成可执行文件. 首先根据elf文件找到got.plt的地址,可以看到在调用之前,其内容均是0,在调用后内容发生了变化.

 

5.8 本章小结

本章介绍了链接的概念和作用,具体介绍了链接的过程及结果,详细说明了可执行文件的elf格式及反汇编了可执行文件,且与hell.o文件的反汇编进行了详细的比较.

(第51分)

第6章 hello进程管理

6.1 进程的概念与作用

概念:进程是一个执行中程序的实例.

作用:系统将每个程序都运行在进程的上下文中,进程的上下文由程序正确运行的所需的状态组成的.这个状态包括内存中的代码和数据,栈,寄存器,程序计数器等.

6.2 简述壳Shell-bash的作用与处理流程

作用:Linux中的shell从命令行接受命令,然后执行相关的操作.

处理流程:

  1. 从终端读入输入的命令.
  2. 根据命令,获得参数.
  3. 检查第一个命令行参数是不是一个内置的shell命令,如果是立即执行.
  4. 如果不是内置的命令,则调用fork函数创建新的进程,称为子进程.
  5. Shell监听键盘输入,如果是对应的有意义的信号则进行处理.

        

6.3 Hello的fork进程创建过程

在终端输入./Hello 2021111190 马鸿胜 1 ,shell接受我们的命令后开始解析,发现这不是一个内置命令,则调用fork创建子进程,子进程的虚拟空间内容是由父进程复制来的,但是策略是写时复制,所以在之后的过程中,两者的内容会开始不一致,子进程会返回0,父进程返回子进程的pid.

6.4 Hello的execve过程

在调用fork后,子进程会调用exceve进行子进程上下文的加载,它首先清空原本的用户区域中的内容,然后将可执行文件的内容映射到该空间.然后设置程序计数器PC,使其指向代码区域入口地址,值得注意的是execve函数调用成功不会返回.

6.5 Hello的进程执行

①逻辑控制流:计算机系统同时运行许多程序,但是计算机系统向每个运行的程序提供一个假象,就是这个进程在独占cpu, 如下图所示,每个进程在执行的时候都不是”连续”的,在被其他进程占用cpu时,进程会挂起.

②并发流与进程时间片:一个进程与别的进程在执行时有时间上的重叠成为并发,就像上图的进程A与B.一个进程执行它的控制流的一部分的每一时间段叫做时间片.

③用户与内核模式:在用户模式中,进程不允许执行特权指令,例如发起一个IO操作,更重要的是不允许直接引用地址空间中内核区的代码和数据,也就是用户模式下的地址空间是不完全的,或者说仅仅是进程自身的部分可以被使用,而涉及到内核的代码与数据无法被访问.内核模式:内核模式下进程可以执行指令集中的任何指令,访问任何数据,就像linux中的sudo,Android中的root.

④进程上下文:内核维持每一个进程的上下文,上下文是内核重新启动挂起进程的所需要的状态.其由通用目的寄存器,浮点寄存器,程序计数器,用户栈,状态寄存器,内核栈和各种内核数据结构组成.

⑤进程调度:在进程执行到某些时刻,内核决定挂起当前进程执行先前被挂起的进程或者新的进程,这种决策就是进程调度,由内核中的调度器处理.

⑥上下文切换:内核调度一个新的进程运行后,它就抢占了当前进程,并使用上下文切换的机制控制转移到新的进程.

⑦hello的执行:shell执行hello时先处于用户模式,在运行过程中由于和其他进程不断切换,故在内核模式与用户模式不断切换,如果收到信号就会直接切换到内核模式运行信号处理程序,再返回用户模式.

6.6 hello的异常与信号处理

首先,按照说明运行hello程序,结果如下:

然后在运行过程中按回车,这不是一个信号,所以程序继续运行.

按下Ctrl-Z,程序收到了SIGSTP信号,被挂起

期间使用ps,jobs命令可以查看当前进程及pid,使用pstree可以只管看到个进程关系

Fg命令重新执行被挂起的进程.

Kill -9 %1命令暂停进程

按下Ctrl-C,杀死进程.

6.7本章小结

本章介绍了hello进程如何执行,fork函数,execve函数执行过程,进程的概念与具体运行过程.对进程,异常,信号处理有了更深的认识.

(第61分)

第7章 hello的存储管理

7.1 hello的存储器地址空间

结合hello说明逻辑地址、线性地址、虚拟地址、物理地址的概念。

逻辑地址:程序经过编译后出现在汇编代码中的地址.

线性地址:逻辑地址经过分段机制转化为线性地址.

虚拟地址:线性地址的别称.其构造为VPN+VPO

物理地址:文件具体存储的地址,构造为PPN+PPO

7.2 Intel逻辑地址到线性地址的变换-段式管理

逻辑地址由两部分构成,段标识符:段内偏移量.段标识符为16位,其中前13位是所引,指向具体的段,后三位是硬件细节描述,多个索引组成的数组叫做段描述符表.

分段机制转换逻辑地址到线性地址过程如下:

  1. 使用索引的值在GDT表中找到段描述符
  2. 查看标志位,看是否可访问
  3. 将段描述符中对应的段的基地址加上偏移量,得到线性地址

7.3 Hello的线性地址到物理地址的变换-页式管理

虚拟内存技术认将内存与磁盘看为一个连续的字节数组,被分为大小固定的块,称为页块.页块根据不同的状态被分为三类:未分配,未缓存,已缓存.未分配是指虚拟内存中未对应物理页的页;未缓存是指已经分配但是没有被缓存到物理内存中的页;已缓存指的是已经缓存到物理页中的页.linux下虚拟页大小位4KB,物理页大小也为4KB,MMU负责将虚拟地址翻译为物理地址.

7.4 TLB与四级页表支持下的VA到PA的变换

许多个页表条目组成页表,其记载着虚拟页和物理页的对应.我们通过页表完成虚拟地址到物理地址的转换,大致的流程是cpu首先给出虚拟地址,然后去页表中查询对应的页表条目,得到物理地址PPN字段,再将PPN与VPO组合起来得到实际的物理地址.但是具体实现起来缺不是这样.

首先,页表存在主存中,每次查询页表都要访存,这就造成了时间上的浪费,根据局部性原理及cache的设计原理,我们可以拿出一部分经常访问的页表条码存在寄存器中,组成TLB,再查找PTE的时候,先去TLB中查看,如果有直接得到物理地址,如果没有再查找页表.而且页表的构造也不是单纯的PTE的集合,如果只有一页那页表会很大,intel采用多级页表的技术,高级页表控制低级页表中的存储内容,这样一级一级的查看,大大减小了页表的大小.所以具体的实现应该是cpu给出虚拟地址,先去TLB查看是否命中,如果命中,直接翻译出物理地址;没命中则去页表中逐级查询直到得到PTE,再得到物理地址.

7.5 三级Cache支持下的物理内存访问

物理地址组成为PPN+PPO的形式,然后cpu对物理地址进行分解,其包括CT,CI,CO分别是组标记,组索引,块内偏移.首先检查组索引,在第一级cache中查看是否命中,若没命中则逐级向下查找,若命中,则取出数据送cpu.

7.6 hello进程fork时的内存映射

当fork 函数被shell调用时,内核为hello进程创建各种数据结构,并分配给它一个唯一的PID。为了给hello进程创建虚拟内存,它创建了hello进程的各种结构,包括用户栈,堆和页表等的原样副本。它将两个进程中的每个页面都标记为只读,并将两个进程中的每个区域结构都标记为私有的写时复制。通过 fork 创建的子进程拥有父进程相同的区域结构、页表等的一份副本,同时子进程也可以访问任何父进程已经打开的文件。当 fork 在新进程中返回时,新进程现在的虚拟内存刚好和调用 fork 时存在的虚拟内存相同,当这两个进程中的任一个后来进行写操作时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地址空间。

7.7 hello进程execve时的内存映射

execve 函数调用驻留在内核区域的启动加载器代码,在当前进程中加载并运 行包含在可执行目标文件 hello 中的程序,用 hello 程序有效地替代了当前程序。 加载并运行 hello 需要以下几个步骤:

删除已存在的用户区域,删除当前进程虚拟地址的用户部分中的已存 在的区域结构。

映射,为新程序的代码、数据、bss 和栈区域创建新的区域结构,所有这些新的区域都是私有的、写时复制的。代码和数据区域被映射为 hello 文件中的.text 和.data 区,bss 区域是请求二进制零的,映射到匿名 文件,其大小包含在 hello 中,栈和堆地址也是请求二进制零的,初始长度为零。

映射共享区域,hello程序与lib.so文件链接,libc.so 是动态链接到这个程序中的,然后再映射到用户虚拟地址空间中的共享区域内。

设置程序计数器(PC),execve 做的最后一件事情就是设置当前进程 上下文的程序计数器,使之指向代码区域的入口点。

调用成功不会返回.

7.8 缺页故障与缺页中断处理

概念: 缺页故障就是虚拟内存中的字不在物理内存中,发生页不命中。

缺页中断处理: 进程暂停执行,内核会选择一个主存中的一个牺牲页面,如果该页面是其他进程或者这个进程本身页表项,则将这个页表对应的有效位改为0,同时把需要的页存入主存中的一个位置,并在该页表项储存相应的信息,将有效位置为1。然后进程重新执行这条语句,此时MMU就可以正常翻译这个虚拟地址了。如图:牺牲VP4,加入VP3并且返回引发缺页故障的指令.

7.9动态存储分配管理

程序的虚拟内存空间中有一部分被称为堆,它在未初始化的区域后(.bss),大小是动态变化的,但是只能向高地址增长.动态内存分配器负责分配堆.堆被分为大小不同的块,按块分配.

分配器分为:显式分配器和隐式分配器.显示分配器要求进程显示的释放所有的块,也就是必须表明释放,如malloc函数必须要free.隐式分配:java等语言中的分配器,不需要释放,便会自动释放.

7.10本章小结

本章介绍了Hello和操作系统之间的交流方式。介绍了计算机系统中非常重要的一个概念:虚拟内存,以及关于它的内容。介绍了Hello是如何经过地址翻译从而找到最终的物理地址。阐释了TLB加速地址翻译、多级缓存以及动态内存管理相关的要点。

(第7 2分)

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

以下格式自行编排,编辑时删除

设备的模型化:文件

设备管理:unix io接口

8.2 简述Unix IO接口及其函数

以下格式自行编排,编辑时删除

8.3 printf的实现分析

以下格式自行编排,编辑时删除

https://www.cnblogs.com/pianist/p/3315801.html

从vsprintf生成显示信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等.

字符显示驱动子程序:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。

显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。

8.4 getchar的实现分析

以下格式自行编排,编辑时删除

异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。

getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。

8.5本章小结

以下格式自行编排,编辑时删除

(第81分)

结论

用计算机系统的语言,逐条总结hello所经历的过程。

你对计算机系统的设计与实现的深切感悟,你的创新理念,如新的设计与实现方法。

(结论0分,缺失 -1分,根据内容酌情加分)

附件

列出所有的中间产物的文件名,并予以说明起作用。

(附件0分,缺失 -1分)

参考文献

为完成本次大作业你翻阅的书籍与网站等

[1]  林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42.

[2]  辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.

[3]  赵耀东. 新时代的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).

[4]  谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.

[5]  KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.

[6]  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.

(参考文献0分,缺失 -1分)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值