程序人生-Hello’s P2P

金歌  论坛元老 | 2024-12-5 00:13:09 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1053|帖子 1053|积分 3159

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x



 

计算机系统


大作业



题     目  程序人生-Hellos P2P 
专       业           信息安全             
学     号                2021112136        
班   级     2103201                   
学       生       车振宁           
指 导 教 师      刘雄伟               






计算机科学与技能学院

2022年5月

摘  要

本论文具体叙述了hello.c在Linux系统下的整个生命周期:从原始程序的现在再到实行,再到末了的终止接纳。这一过程实现了了预处置惩罚、编译、汇编、链接、加载、运行、终止、存储、接纳等操作,对计算机系统有了更深的认识。

关键词:P2P;计算机系统;进程;程序;编译原理;变量生存期;                            









目  录


第1章 概述

1.1 Hello简介

1.2 情况与工具

1.3 中间结果

1.4 本章小结

第2章 预处置惩罚

2.1 预处置惩罚的概念与作用

2.2在Ubuntu下预处置惩罚的命令

2.3 Hello的预处置惩罚结果分析

2.4 本章小结

第3章 编译

3.1 编译的概念与作用

3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果分析

3.4 本章小结

第4章 汇编

4.1 汇编的概念与作用

4.2 在Ubuntu下汇编的命令

4.3 可重定位目标elf格式

4.4 Hello.o的结果分析

4.5 本章小结

第5章 链接

5.1 链接的概念与作用

5.2 在Ubuntu下链接的命令

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

5.4 hello的虚拟地点空间

5.5 链接的重定位过程分析

5.6 hello的实行流程

5.7 Hello的动态链接分析

5.8 本章小结

第6章 hello进程管理

6.1 进程的概念与作用

6.2 简述壳Shell-bash的作用与处置惩罚流程

6.3 Hello的fork进程创建过程

6.4 Hello的execve过程

6.5 Hello的进程实行

6.6 hello的异常与信号处置惩罚

6.7本章小结

第7章 hello的存储管理

7.1 hello的存储器地点空间

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

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

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

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

7.6 hello进程fork时的内存映射

7.7 hello进程execve时的内存映射

7.8 缺页故障与缺页中断处置惩罚

7.9动态存储分配管理

7.10本章小结

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

8.2 简述Unix IO接口及其函数

8.3 printf的实现分析

8.4 getchar的实现分析

8.5本章小结

结论

附件

参考文献



第1章 概述

1.1 Hello简介

根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。
1.1.1P2P(from program to process)
由.c文件经过预处置惩罚得到.i文件,在经过编译的到.s文件,然后经过汇编器汇编得到.s文件,末了毗连器链接得到可实行目标程序hello。

 

Linux系统中,在shell中上输入./hello运行hello,shell会调用fork函数为hello生成子进程,再调用加载器execve在子进程中加载hello程序,于是hello从程序转换为了进程。
1.1.2 020(from zero-0  to  zero-0)
zero-开始:程序原来在磁盘上生存,经过子进程调用execve加载后,内存创建了新的区域提供给hello的代码区、数据区以及运行时堆栈,映射虚拟内存,载入物理内存,然后进入程序入口处开始实行。
zero-竣事:hello实行完成后,操作系统接纳子进程,内核从系统中删除了hello的全部相关数据,hello所占的全部资源清零,hello以zero的形式竣事了它的一生。


1.2 情况与工具

硬件情况:X64 CPU;2GHz;16G RAM;256GHD Disk
软件情况:Windows 10、Vmware16.2.4、Ubuntu 22.04.2
开辟工具:gedit,vim,edb,vscode,readelf,HexEdit

1.3 中间结果

文件名
文件功能
hello.c
源程序
hello.i
预处置惩罚得到的文本文件
hello.s
编译得到的汇编文件
hello.o
汇编得到的可重定位目标文件
hello
链接得到的可实行目标文件
hello.elf
hello.o的ELF格式
hello1.elf
hello的ELF格式


1.4 本章小结

本章团体先容了hello的实现换个运行过程,扼要先容了hello.c的P2P与020,设置了所需实验情况和工具,得到了整个过程的中间文件和结果。


第2章 预处置惩罚

2.1 预处置惩罚的概念与作用

2.1.1预处置惩罚的概念:C语言预处置惩罚是指在编译阶段之前,对源代码进行的一系列处置惩罚操作。预处置惩罚器会根据预处置惩罚指令(以#开头的语句)对源代码进行处置惩罚,生成一份新的代码文件,供编译器使用。
2.1.2预处置惩罚的作用:
宏界说:使用#define指令界说宏,可以将一些常用的代码片断或常量界说为宏,在代码中使用时可以直接使用宏名,进步代码的可读性和重用性。
文件包含:使用#include指令可以将其他文件中的代码包含到当前文件中,方便代码的组织和管理。
条件编译:使用#if和#ifdef指令可以根据条件来选择编译哪些代码,可以根据差别的平台或编译选项来选择差别的代码。
其他:预处置惩罚器还可以进行一些其他的操作,比如#error指令可以在编译时输出错误信息,#pragma指令可以控制编译器的行为等。

2.2在Ubuntu下预处置惩罚的命令



 

2.3 Hello的预处置惩罚结果分析

通过linux下的gedit工具打开hello.i文件,我们可以看到代码中包含了#include文件中的函数代码


 
Main函数代码位于文件末端
 

 

由预处置惩罚结果我们可以看到,预处置惩罚器(cpp)按照#的顺序进行预处置惩罚内容展开
(在hello.c中为stdio.h,unistd.h,stdlib.h),终极的hello.i文件中没有#开头的预处置惩罚命令,其包含了#include指示的文件的全部源代码以及重定位,符号引用等等,形成了hello.i文件。文件大小远远超过hello.c。

2.4 本章小结

通过本章具体的hello.c生成hello.i实例,深刻明白了预处置惩罚过程的步骤的生成文件。并对生成文件做出了具体的分析。


第3章 编译


3.1 编译的概念与作用

3.1.1编译的概念:编译的过程是进行词法分析、语法分析、语义分析以及优化后产生相应的汇编代码文件的过程。
3.1.2编译的作用;
编译的作用是将高级计算机语言所写作的源代码程序翻译为汇编语言程序,在这个过程中,会进行以词法分析、语法分析、语义分析来生成汇编语言程序,且编译器大概在这个过程中根据编译选项对程序进行一些适当的优化。

编译可以将高级程序设计语言翻译成较为底层的汇编语言,在这个过程中产生的汇编程序里的指令更加贴近于机器指令也更为贴近机器真正实行程序的过程,可以让程序员更好明白程序在机器层面上的底层实现。
词法分析:编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单元,方法分为两种:自上而下分析法和自下而上分析法。
优化代码:将C语言源代码转换为汇编语言可以更直观地了解程序的实行过程,帮助开辟者更好地优化代码。

调试程序语义分析:汇编语言中的指令和C语言源代码是一一对应的,可以帮助开辟者更深入地明白计算机底层的运行机制,通过汇编语言代码来定位和调试程序中的错误。
留意:这儿的编译是指从 .i 到 .s 即预处置惩罚后的文件到生成汇编语言程序
3.2 在Ubuntu下编译的命令




 
 

3.3 Hello的编译结果分析

此部分是重点,说明编译器是怎么处置惩罚C语言的各个数据范例以及各类操作的。应分3.3.1~ 3.3.x等按照范例和操作进行分析,只要hello.s中出现的属于大作业PPT中P4给出的参考C数据与操作,都应分析
3.3.1:数据

 

main的局部变量i,生存在栈中。
(2)常量字符串:

 

位于只读数据段(.rodata)中,作为printf函数的参数。
(3)立即数
以$开头的数字,直接出现于汇编代码中。
(4)函数参数argc、数组函数参数*argv[]
作为传给main函数的参数,均被放入栈中,前者指示参数个数,后者每个元素存放一个指向字符的指针。

 

3.3.2:赋值
在hello.s中,赋值操作由mov指令实现,使用了movq指令。

 

movb:一个字节,movw:“字”,movl:“双字”,movq:“四字”3.3.3 范例转换
hello.c中atoi(argv[3])将字符串范例转换为整型。int、float、double、short、char可以进行相互转化。
3.3.4 算数操作

 

.c中的自加操作。

 

对应完成上述自加操作的汇编代码。下面是跳转判断指令。

其他汇编代码算术操作如下:

 

3.3.5关系操作

 

判断argc是否为4,若不为4则打印用法后退出,若为4则继续。

 

为循环截至条件。
3.3.6 控制转移

 

       .c 文件中的跳转代码。

在hello.s中通过cmp指令设置条件码,依据条件码进行控制转移。

 




 

此中,je用于判断cmpl产生的条件码,若两个操作数的值不相等则跳转到指定地点,jle用于判断cmpl产生的条件码,若后一个操作数的值小于等于前一个则跳转到指定地点。
3.3.7函数操作
调用函数时有以下操作:(P调用函数Q)
传递控制:调用过程Q的时间,程序计数器(%rip)必须设置为函数Q代码的起始地点,将P程序的下一条指令压入栈中。然后在返回时,要把程序计数器(%rip)设置为压入栈中的指令
传递数据:函数P必须可以大概向函数Q提供一个或多个参数Q必须可以大概向P中返回一个值。
分配和释放内存:在开始时,Q大概必要为局部变量分配空间,而在返回前,又必须释放这些空间。
hello.c中的函数操作:
main函数:参数是int argc,char *argv[]
printf函数:参数是argv[1],argv[2],作用为打印所选内容。
exit函数:参数是1,功能为退出程序。
sleep函数:参数是atoi(argv[3]),功能为进程休眠atoi(argv[3])秒。
getchar函数:无参数,功能为从stdin流中截取一个字符。
atoi函数:参数是argv[3],功能为将所选字符串转化为整型变量。


3.4 本章小结

本章展示了hello.i通过编译得到hello.s文件,并对该文件的汇编指令进行分析,分析了其汇编代码中的数据和操作,加深了对汇编的明白。


第4章 汇编


4.1 汇编的概念与作用


汇编的概念:将汇编语言转换为机器语言的过程。结果生存在.o文件中,是一个二进制文件。
汇编的作用:完成汇编指令文件向可重定位目标文件的转化。把汇编语言翻译成计算机可以大概直接实行的0、1机器语言,把文本文件转化成二进制文件。


留意:这儿的汇编是指从 .s 到 .o 即编译后的文件到生成机器语言二进制程序的过程。
4.2 在Ubuntu下汇编的命令





 
应截图,展示汇编过程!
 
4.3 可重定位目标elf格式

分析hello.o的ELF格式,用readelf等列出其各节的基本信息,特别是重定位项目分析。
4.3.1

 

Elf头:

 



ELF头以一个16字节的序列(Magic)开始,它形貌了系统的字的大小和字节顺序(大端序大概小端序)。ELF头剩下部分的信息包含帮助毗连器语法分析和解释目标文件的信息。此中包括ELF头的种别,数据,版本,范例程序入口地点和起始地点等信息。
4.3.2
节头部表

 

在ELF头与节头部表之间的都为节。其形貌了.o文件中出现的各个节的信息,包括节的名称、范例、地点、偏移量、所占空间大小等信息。

名称
内容
.text
已编译程序的机器代码
.rodata
只读数据
.data
已初始化的全局和静态C变量
.bss
未初始化的全局和静态C变量,以及全部被初始化为0的全局或静态变量
.symtab
一个符号表,存放一些在程序中界说和引用的函数和全局变量的信息
.rel.text
一个.tex节中位置的列表
.rel.data
被模块引用或界说的全部全局变量的重定位信息
.debug
一个调试符号表
.line
原始C源程序中的行号和.text节中机器指令之间的映射
.strtab
一个字符串表(包括.symtab和.debug节中的符号表)
4.3.3重定位

 

文件中有两个重定位节,分别是.rela.text和.rela.eh_frame节。差别的重定位节对应差别节的重定位信息。毗连器在处置惩罚目标是要对目标文件进行重定位,这时必要重定位节中的信息才气知道如何进行重定位。.rela.text中生存了.text节中必要被修正的信息,注明白偏移量、寻址方式等信息。
.rela.eh_frame中生存了.eh_frame节重定位信息。
4.3.4符号表

 

 符号表:符号表中为程序界说的函数以及全局变量信息,值得留意的是局部变量是存储在内存的栈中的。
4.4 Hello.o的结果分析

以下格式自行编排,编辑时删除
objdump -d -r hello.o  分析hello.o的反汇编,并请与第3章的 hello.s进行对照分析。
说明机器语言的构成,与汇编语言的映射关系。特别是机器语言中的操作数与汇编语言不一致,特别是分支转移函数调用等。

 

机器语言是二进制的指令,每一串01数字就是一个机器指令,对应着一句汇编指令。二者以一种映射关系对应。

汇编文件中操作数为十进制,反汇编为十六进制
汇编文件中call和jump使用.L表现段名称,而反汇编中使用pc相对寻址。地点是有实际的数字出现的。同时我们也可以发现,反汇编中的文件前有机器代码,每一段机器指令都对应一条汇编语言指令。可以以为这两种指令为双射关系。
差别之处:hello.s中跳转的目标地点直接记为段名称(L2,L3等),

 

而hello.o中跳转需确定目标地点

 

hello.s中函数调用是call+函数名称,但hello.o中call后跟的是所调用的函数相对调用之的函数的起始位置的相对地点。
4.5 本章小结

本章先容了hello.s变为hello.o的过程,对可重定位ELF格式进行雷昂系的分析。深入明白了汇编代码和机器指令的关系。

5链接


5.1 链接的概念与作用

留意:这儿的链接是指从 hello.o 到hello生成过程。
5.1.1链接的概念
链接是指通过链接器,将各种代码与数据片断收集并合成为一个完全链接的单一文件的过程,可被加载到内存中并实行。其可以实行于编译时,可以实行于加载时(加载器加载到内存实行),大概实行与运行时,由应用程序加载实行。
5.1.2 链接的作用
链接器在软件开辟过程中扮演着一个关键的角色,因为它们使得分离编译成为大概。我们不消将一个大型的应用程序组织为一个巨大的源文件,而是可以把它分解为更小、更好管理的模块,可以独立地修改和编译这些模块。当我们改变这些模块中的一个时,只需简单地重新编译它,并重新链接应用,而不必重新编译其它文件。
5.2 在Ubuntu下链接的命令

使用ld的链接命令,应截图,展示汇编过程! 留意不只毗连hello.o文件

 

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

分析hello的ELF格式,用readelf等列出其各段的基本信息,包括各段的起始地点,大小等信息。
在终端shell中输入readelf -a hello > hello1.elf生成hello程序的ELF格式文件,并生存为hello1.elf(与第四章中的elf文件区分)

 

5.3.1ELF头


 
与hello.o的头文件差别,hello中Type为EXEC(Executable file) ,即hello为一个可实行目标文件,根据Number of section headers可知有25个节。
5.3.2节头

 

形貌了各个节的大小、偏移量和其他属性。链接器链接时,会将各个文件的雷同段合并成一个大段,而且根据这个大段的大小以及偏移量重新设置各个符号的地点。
5.3.3程序头

 

包含实行程序系统所需的段的信息。
5.4 hello的虚拟地点空间

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

根据节头部表,通过edb可以找到各节的信息。

 

在edb中的虚拟地点和在elf文件中看到的虚拟地点是对应雷同的,在edb中我们可以选择打开symbol viewer进行loaded symbls,也会加载出节头的虚拟地点信息。
5.5 链接的重定位过程分析

objdump -d -r hello 分析hello与hello.o的差别,说明链接的过程。
联合hello.o的重定位项目,分析hello中对其怎么重定位的。

 

与hello.o的区别:
Hello.o没有经过链接,main的地点从0开始。hello将hello.o必要重定位的部分重定位后将其地点变化成了虚拟空间中绝对地点。

 


Hello.o中不存在调用库函数代码,hello中将库函数添加到了文件,并添加了节

 


在helllo.o的反汇编程序中,图中选中的函数调用指令由于还没有分配虚拟地点,以是只能用偏移量跳转,而右侧链接后已经分配好了虚拟地点,可以直接用call虚拟地点进行跳转.
跳转指令

 

函数调用中,链接后可以采用虚拟地点跳转
5.6 hello的实行流程

使用edb实行hello,说明从加载hello到_start,到call main,以及程序终止的全部过程。请列出其调用与跳转的各个子程序名或程序地点。
各个函数名和对应的地点如下:

<_init>:401000

<.plt>:401020

<puts@plt> :401090

<printf@plt>:4010a0

<getchar@plt>:4010b0

<atoi@plt>:4010c0

<exit@plt>:4010d0

<sleep@plt>:4010e0

<_start>:4010f0

<_dl_relocate_static_pie>:401120

<main> :401125

<_libc_scu_init>:4011c0

<_libc_csu_fini>:401230

<_fini>: 401238
5.7 Hello的动态链接分析

  当程序调用共享链接库时,我们无法预测这个函数的地点,因为界说他的模块可以再运行时加载到任何位置。以是我们要为每一个重定位生成一个分析然后再毗连他们。采用延迟绑定的计谋,把过程地点的加载推迟到第一次调用该进程。动态链接器使用GOT(全局偏移量表)和PLT(过程链接表)实现函数的动态链接。此中GOT 中存放函数目标地点,PLT使用 GOT中地点跳转到目标函数。
链接器采用延迟绑定的计谋来避免运行时修改调用模块的代码段。动态链接器使用过程链接表PLT+全局偏移量表GOT实现函数的动态链接,GOT中存放函数目标地点,PLT使用GOT中地点跳转到目标函数。
dl_init前:

 

got起始位置位于0x404000处
查看edb相关信息

 

GOT表位置在调用dl_init之前0x404008后的16个字节均为0:
dl_init后:

 

16字节的内容已经改变,即.got.plt的条目已经发生变化



5.8 本章小结

本章围绕链接展开,分析了ubuntu下ELF文件的各部分信息,而且使用edb加载hello。通过将反汇编hello文件和hello.o反汇编文件进行对比,比力两个反汇编文件的差别。具体的解释了重定位过程中对文件进行的操作。并对动态链接的过程也进行了深入的了解。



6hello进程管理


6.1 进程的概念与作用

狭义界说:进程就是一段程序的实行过程。
 广义界说:进程是一个具有肯定独立功能的程序关于某个数据集合的一次运行运动。它是操作系统动态实行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的实行单元。
进程的作用
进程提供给应用程序两个关键抽象:一个独立的逻辑控制流,程序貌似独占处置惩罚器;一个私有的地点空间,如同程序独占内存地点。

6.2 简述壳Shell-bash的作用与处置惩罚流程

shell是一个交互型的应用级程序,它代表用户运行其他程序,解释命令

shell处置惩罚中包括了:

读入命令:读取用户输入的命令
语法分析:对用户的指令进分析
内部指令实行:判断是否为内部指令,如果则在内部进行操作,实行后跳回1
外部程序调用:使用fork与exec家属函数进行系统调用,把实行程序调入内存。
接受signal:通过signal决定对程序实行的操作,如放到前台 杀死进程(同样通过signal实现)
使用wait家属函数等候程序实行竣事
6.3 Hello的fork进程创建过程

输入命令实行hello后,父进程判断是不是内部指令。如果不是,则fork函数创建子进程。子进程获取了与父进程的上下文,包括栈、通用寄存器、程序计数器,情况变量和打开的文件雷同的一份副本。Fork函数调用一次,返回两次,在父进程中,fork返回子进程的PID,在子进程中,fork返回0。子进程可以读取父进程打开的任何文件。当子进程运行竣事时,父进程如果仍旧存在,则实行对子进程的接纳,否则就由init进程接纳子进程。

6.4 Hello的execve过程

实行exexve时将会加载并运行程序。加载器将删除子进程现有的虚拟内存段,创建一组新的段(栈与堆初始化为0)通过将虚拟地点空间中的页映射到可实行文件的页大小的片, execve 调用驻留在内存中的、被称为启动加载器的操作系统代码,并创建一组新的代码、数据、堆和栈段。 新的代码和数据段被初始化为可实行文件中的内容。末了加载器(execve)设置PC指向_start 地点,_start 终极调用 hello中的 main 函数。
当出现错误时,execve才会返回-1到调用程序,execve调用成功则不会产生返回。

6.5 Hello的进程实行

联合进程上下文信息、进程时间片,阐述进程调度的过程,用户态与核心态转换等等。
(1)上下文信息:上下文信息是操作系统内核重新启动一个挂起的进程所必要恢复的原来的状态。它由通用寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构等对象的信息构成。
(2)时间片;一个进程实行它的控制流的一部分的每一时间段叫做时间片。
6.5.3进程调度过程
在进程实行的某些时刻,内核可以决定抢占当进步程,并重新开始一个先前被抢占了的进程,这种决策就叫做调度,是由内核中称为调度器的代码处置惩罚的。当内核选择一个新的进程运行,我们说内核调度了这个进程。在内核调度了一个新的进程运行了之后,它就抢占了当进步程,并使用上下文切换机制来将控制转移到新的进程。
以实行sleep函数为例,sleep函数哀求调用休眠进程,sleep将内核抢占,运行其他程序所挂载的进程,进入sleep倒计时,当倒计时竣事后,hello程序重新抢占内核,返回hello所在的进程继续实行。


 

6.6 hello的异常与信号处置惩罚

 hello实行过程中会出现哪几类异常,会产生哪些信号,又怎么处置惩罚的。
 程序运行过程中可以按键盘,如不停乱按,包括回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps  jobs  pstree  fg  kill 等命令,请分别给出各命令及运行结截屏,说明异常与信号的处置惩罚。
 大概出现的异常:
中断:来自I/O设备的信号,异步发生,中断处置惩罚程序对其进行处置惩罚,返回后继续实行调用前待实行的下一条代码
陷阱:故意的异常,是实行一条指令的结果,调用后也会返回到下一条指令,用来调用内核的服务进行操作。帮助程序从用户模式切换到内核模式。
故障:由错误情况引起的,它大概可以大概被故障处置惩罚程序修正。如果修正成功,则将控制返回到引起故障的指令,否则将终止程序。
终止:不可恢复的致命错误造成的结果,通常是一些硬件的错误,处置惩罚程序会将控制返回给一个abort例程,该例程会终止这个应用程序。
大概产生的信号
①不停乱按:

 

除了ctrl+c或ctrl+z,对进程不会造成影响
②ctrl+z:SIGTSTP
进程被临时挂起

 

输入ps,该程序只是挂起而不是终止

 

ctrl+c:SIGINT

 

进程被SIGINT信号中断。
fg命令:使后台挂起的进程继续运行。

 

被SIGTSTP挂起的进程hello可以用fg指令继续运行。
jobs:表现目前运行的关键作业

 

pstree:以树状图的形式显现全部运行的进程

 

kill命令:向指定的进程或进程组传递指定的信息

 



6.7本章小结

本章先容了进程的概念与作用,以及Shell-bash的基本概念。在这一章中根据hello可实行文件研究了fork, execve函数的原理与实行过程。先容了hello异常与信号处置惩罚,分析并测试了在hello实行过程中外部键盘输入时的处置惩罚结果。

             第7章 hello的存储管理
7.1 hello的存储器地点空间

联合hello说明逻辑地点、线性地点、虚拟地点、物理地点的概念。
1.逻辑地点:程序经过编译后出现在汇编代码中的地点。
2.线性地点:逻辑地点向物理地点转换时的中间环节,hello中的偏移地点加上相应段的基地点就是线性地点。
3.虚拟地点:就是线性地点
4.物理地点:实际出现在CPU外部地点总线上的地点信号,表现实的物理内存所对应的地点。

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

在段式管理下,逻辑地点由两部分组成:段选择器和偏移量。段选择器指示了要访问的段,偏移量指示了在该段内的偏移量。
将段选择器和偏移量组合起来,就可以得到一个逻辑地点。然后,通过查找段形貌符表,可以找到对应的段形貌符,从而得到该段的基地点和限长。基地点加上偏移量就得到了线性地点。
如果线性地点超出了段的限长,则会触发异常。如果线性地点没有超出段的限长,则可以将其转换为物理地点,然后进行访问。
7.3 Hello的线性地点到物理地点的变换-页式管理

在页式管理下,线性地点由两部分组成:页目录项和页表项的偏移量。页目录项指示了要访问的页表,页表项的偏移量指示了在该页表内的偏移量。

将页目录项和页表项偏移量组合起来,就可以得到一个线性地点。然后,通过查找页目录表和页表,可以得到对应的物理页框号。将物理页框号和线性地点的偏移量组合起来,就可以得到物理地点。

在页式管理下,每个进程有自己的页目录表和页表,因此差别进程之间的线性地点大概对应差别的物理地点。此外,如果线性地点没有对应的物理页框号,则会触发缺页中断,必要将相应的页面从磁盘中加载到内存中。

 

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

TLB(Translation Lookaside Buffer)是一个高速缓存,用于存储最近访问过的页表项。当CPU必要访问一个虚拟地点时,首先会在TLB中查找相应的页表项,如果找到了,就可以直接得到物理地点;如果没有找到,就必要通过四级页表来进行变换。
在四级页表支持下,虚拟地点由四部分组成:页目录项、页表项、页内偏移和进程号。首先,CPU会使用页目录项和页表项偏移量来查找页表项,如果TLB中没有缓存,就必要在四级页表中进行查找。如果找到了页表项,就可以得到物理页框号。然后,将物理页框号和页内偏移组合起来,就可以得到物理地点。
如果TLB中没有缓存,而且四级页表中也没有找到相应的页表项,则会触发缺页中断。操作系统会将相应的页面从磁盘中加载到内存中,并更新页表项和TLB,然后再次实行地点变换。

 


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

在三级Cache支持下,物理内存访问的过程可以分为三个阶段:L1 Cache、L2 Cache和L3 Cache。
首先,当CPU必要访问一个物理地点时,会首先在L1 Cache中查找是否有相应的缓存。如果有,就可以直接得到数据;如果没有,则必要到L2 Cache中查找。如果没有,则必要到L3 Cache中查找。如果L3也没有,则必要到主存中查找。
如果查找到,则将数据复制到上级的全部Cache中,返回cpu。
如果在主存中也没有找到相应的数据块,则会触发缺页中断,操作系统会将相应的页面从磁盘中加载到内存中,并更新相应的缓存和页表,然后再次实行物理内存访问。
7.6 hello进程fork时的内存映射

在fork()系统调用实行时,操作系统会为新进程创建一个与原进程雷同的内存映射,包括代码段、数据段、堆、栈等。具体来说,内存映射会包括以下内容:

代码段:新进程的代码段与原进程雷同,都指向雷同的物理页面。
数据段:新进程的数据段与原进程雷同,都指向雷同的物理页面。
堆:新进程的堆与原进程雷同,但是它们各自拥有独立的虚拟地点空间和物理地点空间,因此它们不会相互影响。
栈:新进程的栈与原进程雷同,但是它们各自拥有独立的虚拟地点空间和物理地点空间,因此它们不会相互影响。

7.7 hello进程execve时的内存映射

当一个进程实行execve()系统调用时,它会加载一个新的程序到内存中,替换当进步程的代码段、数据段、堆、栈等。因此,execve()系统调用实行后,进程的内存映射会发生变化,具体包括以下几个方面:

代码段:当进步程的代码段会被新程序的代码段所替换,即原来的代码段会被卸载,新程序的代码段会被加载到雷同的虚拟地点空间中。
数据段:当进步程的数据段会被新程序的数据段所替换,即原来的数据段会被卸载,新程序的数据段会被加载到雷同的虚拟地点空间中。
堆:当进步程的堆会被清空,新程序必要重新分配堆空间。
栈:当进步程的栈会被清空,新程序必要重新分配栈空间。
7.8 缺页故障与缺页中断处置惩罚

CPU发生缺页故障,进入内核态。
操作系统根据虚拟地点的页号,查找页表,判断必要加载的页面是否在磁盘中。
如果必要加载的页面在磁盘中,则操作系统会将相应的页面从磁盘中读取到内存中,并更新页表,将虚拟地点与物理地点进行映射。
如果必要加载的页面不在磁盘中,则会触发页面置换算法,将某些页面从内存中换出到磁盘中,以腾出空间来加载新的页面。
页面加载完成后,操作系统将控制权返回给用户程序,程序重新实行缺页故障引起的指令。

 


7.9动态存储分配管理

动态存储分配,即指在目标程序或操作系统运行阶段动态地为源程序中的量分配存储空间,动态存储分配包括栈式或堆两种分配方式。动态存储分配方式是不一次性将整个程序装入到主存中。可根据实行的必要,部分地震态装入。同时,在装入主存的程序不实行时,系统可以收回该程序所占据的主存空间。再者,用户程序装入主存后的位置,在运行期间可根据系统必要而发生改变。此外,用户程序在运行期间也可动态地申请存储空间以满足程序需求。
7.10本章小结

本章先容了存储管理和虚拟页表的相关内容。先容了hello进程中,段式管理,也先容了存储映射和虚拟页表和hello进程的fork和execve的存储映射,和动态存储分配

8hello的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本章小结

以下格式自行编排,编辑时删除
(第8章1分)

结论

用计算机系统的语言,逐条总结hello所经历的过程。
你对计算机系统的设计与实现的深切感悟,你的创新理念,如新的设计与实现方法。


  • hello经历的过程:
(1)编写:程序员编写高级语言程序代码。
(2)预处置惩罚(cpp):对hello.c进行预处置惩罚,将文件包含、宏界说、条件编译的代码直接插入hello.c中
(3)编译(ccl):将hello.i文件转为汇编语言程序hello.s
(4)汇编(as):将hello.s文件转为可重定位目标文件hello.o
(5)链接(ld):将hello.o文件与各种链接库,目标文件毗连成为可实行目标文件。
(6)运行:在shell中输入指令运行,和发送信号。
(7)创建子进程:在shell调用fork()函数创建子进程。
(8)加载(execve):shell调用execve函数映射虚拟内存,进入程序入口后程序开始载入物理内存,末了进入main函数实行
(9)实行指令:CPU为进程分配时间片,在一个时间片中,hello享有CPU资源, 顺序实行自己的控制逻辑流。
(10)访问内存:在主存中创建虚拟页表mmu通过页表将程序中使用的虚拟内存地点映射成物理地点。
(11)动态申请内存:函数调用malloc动态申请内存
(12)信号:在程序运行的时间发送信号,产生中断。
(13)终止:当子进程实行完成时退出,内核使用waitpid函数调用父进程接纳子进程,并将子进程的退出状态传递给父进程,终极内核完全删除子进程的全部数据结构以及系统资源。是谓ZERO TO ZERO.
经过本次实验我对计算机系统有了更加深入的了解,对进程的产生和运行,再到中止有了更深刻的明白。把握了深入明白计算机底层运行的能力和解决问题的能力。对后与课程的学习奠定了理论和能力底子。

附件


列出全部的中间产物的文件名,并予以说明起作用。
文件名
文件功能
hello.c
源程序
hello.i
预处置惩罚得到的文本文件
hello.s
编译得到的汇编文件
hello.o
汇编得到的可重定位目标文件
hello
链接得到的可实行目标文件
hello.elf
hello.o的ELF格式
hello1.elf
hello的ELF格式

参考文献




  • C语言编译概念明白_c语言编译是什么意思_大大大大大板牙的博客-CSDN博客 C语言编译概念明白
  • 通过readelf工具分析ELF可重定位目标文件_readelf magic_BUFANG_XF的博客-CSDN博客 通过readelf工具分析ELF可重定位目标文件
  • 进程(一段程序的实行过程)_百度百科 进程
文献:
[1] Randal E.Bryant, David O'Hallaron. 深入明白计算机系统[M]. 机械工业出书社.2018.4 



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表