科技颠覆者 发表于 2024-6-21 13:23:32

步伐人生-Hello‘s P2P




https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps14.png&pos_id=EAUjwBMR

计算机体系

大作业


题     目  步伐人生-Hello’s P2P 
专       业  信息安全                
学     号  2022111772              
班   级  2203201                 
学       生  徐勤玉            
指 导 教 师  史先俊               






计算机科学与技术学院
2024年5月
摘  要
本文通太过析hello步伐的一生,表明白C语言步伐如何从源代码转换为可实行文件,从而将本学期计算机体系这门课程的知识贯通。计算机通过hello.c步伐天生hello可实行文件的生命周期包罗预处置惩罚、编译、汇编、链接、进程管理等整过程。这是一个P2P的过程,有助于我们对计算机体系的工作与原理与体系结构有更深的相识。

关键词:计算机体系;生命周期;P2P                       

(择要0分,缺失-1分,根据内容出色称都酌情加分0-1分)








目  录

第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简介

P2P:即From Program to Process,指从hello.c(Program)变为运行时进程(Process)。首先,hello以一段储存在磁盘上的步伐文本(Program)开始,要使hello.c步伐运行,必要将其变为可实行文件,这个过程包罗预处置惩罚、编译、汇编、链接四个阶段(如图1-1)。具体为用预处置惩罚器处置惩罚 hello.c 文件,天生一个 hello.i 文件,然后,hello.i 输入编译器,编译器将天生一个 hello.s 文件,天生的 hello.s 文件将输入汇编器,产生一个 hello.o,这是一个可重定位文件,可重定位文件颠末链接器的链接将天生可实行目标步伐 hello,最后,在shell中实行它,shell会给它分配进程空间。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps15.jpg&pos_id=W5UnW9ig
图1-1 hello.c的编译过程
020:即From Zero-0 to Zero-0。最初内存并无hello文件的相干内容,在 shell 中输入相干命令后,shell 将调用 fork 函数为这一步伐创建进程,之后将通过 exceve 在进程的上下文中加载并运行 hello,将进程映射到虚拟内存空间,并加载必要的物理内存,从步伐入口开始加载和运行,进入main函数实行目标代码,步伐竣过后,shell父进程回收hello进程,内核删除hello文件相干的数据结构,进程竣事。
1.2 环境与工具

硬件环境:
处置惩罚器:12th Gen Intel(R) Core(TM)i5-12500H   2.50 GHz
机带RAM:16.0GB
体系范例:64位操纵体系,基于x64的处置惩罚器
软件环境:Windows11 64位,VMware,Ubuntu 20.04 LTS
开辟与调试工具:Visual Studio 2021 64位;vim objump edb gcc readelf等工具
1.3 中心效果

列出你为编写本论文,天生的中心效果文件的名字,文件的作用等。
中心效果文件名称
文件作用
hello.i
预处置惩罚后得到的文本文件
hello.s
编译后得到的汇编语言文件
hello.o
汇编后得到的可重定位目标文件
hello
可实行目标步伐
elf.txt
hello.o 的 ELF 格式
hello.asm
反汇编hello.o得到的反汇编文件
hello1.asm
反汇编hello可实行文件得到的反汇编文件

1.4 本章小结

本章首先简要概述了了hello步伐的P2P与020总体流程,然后,说明白本实验所需的硬件设置、软件平台、开辟工具以及本实验天生的各个中心效果文件的名称和功能。
(第1章0.5分)


第2章 预处置惩罚

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

2.2.1预处置惩罚的概念
预处置惩罚是源文件编译前必要做的预备工作,预处置惩罚器在步伐运行前,必要对源文件举行简单加工。该过程主要举行代码文本的更换,用于处置惩罚以#开头的指令,还会删除步伐中的注释和多余的空白字符。
2.2.2预处置惩罚的作用
处置惩罚头文件:将所包含头文件的指令替代。
处置惩罚宏定义:将宏定义更换为实际代码中的内容。
条件编译:根据条件判断是否编译某段代码,伪指令使得步伐员可以通过定义不同的宏来决定编译步伐对哪些代码举行处置惩罚。预编译步伐将根据有关的文件,将那些不必要的代码过滤掉。
2.2在Ubuntu下预处置惩罚的命令

预处置惩罚的命令:gcc -E hello.c -o hello.i(如图2-1)
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps16.jpg&pos_id=ahUbV8CC
图2-1 Ubuntu下的预处置惩罚命令
2.3 Hello的预处置惩罚效果解析

在Linux下打开hello.i文件,将源步伐和预处置惩罚后的步伐举行对比,发现文件被扩展成了三千多行(如图2-2),说明.c文件被修改。插入的部分包罗各种头文件的睁开,如<stdio.h>  <unistd.h>  <stdlib.h> 。预处置惩罚器不会对头文件中的内容做任何计算或转换,只是简单地复制和更换。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps17.jpg&pos_id=ekEj27a3
图2-2 hello.i文件
观察还可以发现,在源代码头部出现的注释在预处置惩罚之后的源代码部分已经不可见(如图2-3),说明在预处置惩罚过程中预处置惩罚器将删除源代码中的注释部分。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps18.jpg&pos_id=7bXM46D1
图2-3 预处置惩罚后的源代码
2.4 本章小结

本章报告了在Linux环境下如何对C语言步伐举行预处置惩罚,以及预处置惩罚的含义和作用。以hello步伐从hello.c到hello.i的过程为例介绍了预处置惩罚器的工作(头文件睁开,宏更换,删除注释,条件更换等)。
(第2章0.5分)

第3章 编译

3.1 编译的概念与作用

编译的概念:计算机步伐的编译是指将用高级步伐设计语言誊写的源步伐,翻译成等价的汇编语言格式步伐的翻译过程,编译器(ccl)将文本文件 hello.i 翻译成文本文件 hello.i。
编译的作用:编译步伐的根本功能是把源步伐(高级语言)翻译成汇编语言。编译的根本流程包罗词法分析、语法分析、语义分析、中心代码天生、代码优化和目标代码天生等阶段。此中各阶段具体作用如下:

[*]词法分析:将源代码步伐输入扫描器,将源代码中的字符序列分割为一系列 C语言中的符合语法要求的字符单元,这一部分可以分为自上而下的分析和自下而上的分析两种方式。
[*]语法分析:基于词法分析得到的字符单元天生语法分析树。
[*]语义分析:在语法分析完成之后由语义分析妻举行语义分析,主要就是为判断指令是否是正当的C语言指令,这一部分也可以叫做静态语义分析,并不判断一些在实行时大概出现的错误,例如如果不存在IDE优化,这一步对于1/0这种只有在动态范例查抄的时候才会发现的错误,代码将不会报错。
[*]中心代码天生:中心代码的作用是可使使得编译步伐的逻辑更加明确,主要是为了下一步代码优化的时候优化的效果更好。
[*]代码优化:根据用户指定的不同优化等级对代码举行安全的、等价的优化,这一举动的目的主要是为了提升代码在实行时的性能。
[*]目标代码天生:天生是编译的最后一个阶段。在颠末上面的全部过程后,在这一过程中将会天生一个汇编语言代码文件,也就是我们最后得到的hello.s文件,这一文件中的源代码将以汇编语言的格式呈现。
3.2 在Ubuntu下编译的命令

编译的命令:gcc -S hello.i -o hello.s
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps19.jpg&pos_id=kDkqAp2o
图3-1 Ubuntu下编译的命令
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps20.jpg&pos_id=1LgOIp5H
图3-2 天生的文件
3.3 Hello的编译效果解析

3.3.1文件初始行
在main函数前的字段展示了节名称(如图3-3)
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps21.jpg&pos_id=CQKdNZZL
图3-3 编译效果初始部分
3.3.2数据

[*]数字常量
通过观察可以发现在源代码中利用的数字常量都是储存在.text段的,无论是比较时利用的数字变量还是在循环时利用的循环比较变量,都储存在.text段中(如图3-4)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps22.jpg&pos_id=nhG8Sw2O
图3-4 数字变量存储位置

[*]字符串常量
通过观察可以发现在 printf 等函数中利用的字符串常量是储存在.rotate段中的(如图3-5)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps23.jpg&pos_id=U0J35qvD
图3-5 字符串常量存储位置

[*]全局变量
在代码中存在一个全局变量,是在sleep中必要利用的sleepsecs变量,通过观察编译后的效果我们可以发现这一个全局变量放在了.data 段,且大小被设置为 4 个字节,这一变量在刚开始的时候就初始化好了(如图3-6)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps24.jpg&pos_id=lgfxRyS5
图3-6 全局变量存储位置

[*]局部变量
局部变量储存在栈中的某一个位置的或是直接储存在寄存器中,分析源代码,局部变量共有三个,分别是循环变量 i、argc 、argv,对于i,通过观察发现它储存在栈中地点为-4(%rbp)的位置(如图3-7)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps25.jpg&pos_id=hgVviwwX
图3-7 局部变量i的存储位置
对于局部变量argc,其作用是标志在步伐运行的时候输入的变量的个数,通过观察可以发现它储存在栈中地点为-20(%rbp)的位置,对于它的操纵主要是与5比较之后确定有一部分代码是否实行(如图3-8)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps26.jpg&pos_id=PypcUx27
图3-8 局部变量argc的存储位置
对于局部变量 argv,其作用是保存输入变量,范例为数组,通过观察可以发现它储存在栈中(如图3-9)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps27.jpg&pos_id=WgDN0pMi
图3-9 局部变量argv的存储位置
3.3.3全局函数
hello.c中只声明白一个全局函数int main(int arge,.char*argv[])(如图3-10)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps28.jpg&pos_id=89k357C4
图3-10 全局函数声明环境
3.3.4赋值操纵
对于变量的赋值在代码中出现了两次,一次是对于全局变量sleepsecs的赋值,一次是对于循环变量 i 的在循环中的赋值.对于全局变量的赋值在编译完成的时候就已经完成,因此不必要其他的赋值语句。对于局部变量i,每次循环竣事的时候都对其举行+1 操纵(如图3-11)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps29.jpg&pos_id=8mLGFEVI
图3-11 对循环变量i的赋值操纵
3.3.5范例转换
对于全局变量sleepsecs存在一个隐式范例转换,对于int型的全局变量赋值为 2.5,最后sleepsecs的值将会是2,在这里发生了由float向int转换的隐式范例转换(如图3-12)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps30.jpg&pos_id=7jeQtLr1
图3-12 对sleepsecs的隐式范例转换
3.3.6sizeof
sizeof在编译时确定其值, 计算出x在内存中所占字节数。以是, 括号内的赋值和函数, 不会被实行。
3.3.7算术操纵
hello.c中的算术操纵为for循环的每次循环竣过后i++,该操纵体现在汇编代码中如图3-13。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps31.jpg&pos_id=ecDIj7gu
图3-13 对局部变量i的算术操纵
3.3.8逻辑/位操纵
通过观察未发现逻辑操纵,但在hello.i文件中可以发现存在异或(如图3-14),将%ebx举行异或。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps32.jpg&pos_id=qmrZ23Jf
图3-14 逻辑操纵
3.3.9关系操纵
hello.c中存在两个关系操纵,分别是:

[*]对于argc的判断,当即是5的时候将举行条件跳转,对应的汇编代码如图3-15。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps33.jpg&pos_id=1IFHn16b
图3-15 关系操纵1

[*]在for循环中对于循环变量i的判断,当循环变量 i 大于即是 9 的时候将举行条件跳转,汇编代码如图3-16。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps34.jpg&pos_id=E5fTK2un
图3-16 关系操纵2
3.3.10数组/指针/结构操纵
通过观察可以发现数组操纵只有一个,是对于argv数组的操纵,观察汇编代码可以发现argv储存的两个值都存放在栈中,储存地点分别是-24(%rbp)与-16(%rbp)(如图3-17)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps35.jpg&pos_id=wgTSfbUY
图3-17 数组操纵
3.3.11控制转移
通过观察可以发现hello.c步伐中的if(argc!=5)将-20(%rbp)的值与5比较,相称就会跳转到L2处继承实行代码(如图3-18)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps36.jpg&pos_id=nGqxxmtX
图3-18 跳转
3.3.12函数操纵
在X86体系中函数参数储存的规则是第1~6 个参数依次储存在%rdi、%rsi、%rdx、%rcx、%r8、%r9 这六个寄存器中,其余的参数保存在栈中的某些位置。
main函数:
参数:传入参数 argc 和 argv,此中 argv 储存在栈中,argc 储存在%rdi 中。
返回:源代码中返回return 0,在汇编代码中是将%eax设置为0并返回这一寄存器(如图3-19)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps37.jpg&pos_id=IaEzfP3o
图3-19 main函数汇编代码
printf函数:
参数:第一次调用的时候只传入了字符串参数首地点,for 循环中调用的时候传入了 argv和 argc的地点。
函数调用:该函数调用了两次。第一次将寄存器%rdi设置为待传递字符串"用法:Hello学号姓名 秒数!\n"的起始地点;第二次将其设置为“Hello %s  %s\n”的起始地点。具体已在前面讲过。利用寄存器%rsi完成对argv的传递,用%rdx完成对argv的传递(如图3-20)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps38.jpg&pos_id=ycNChCbQ
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps39.jpg&pos_id=dsiXb62V
图3-20 printf函数调用
sleep函数:sleep函数以全局变量sleepsecs为参数,参数储存在%edi中,该函数在 for 循环的条件下被调用(如图3-21)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps40.jpg&pos_id=8vGdWKbJ
图3-21 sleep函数调用
exit函数:
参数:1。
调用:当if条件满意时(如图3-22)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps41.jpg&pos_id=DzCFM3Gs
图3-22 exit函数调用
atoi函数:如图3-23。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps42.jpg&pos_id=4ujivNpd
图3-23 atoi函数调用
3.4 本章小结

本章报告了C编译器如何把hello.i文件转换成hello.s文件的过程,介绍了编译的概念与作用,并对Hello的编译效果举行了具体的说明,包罗伪指令,rodata节,赋值,算术运算,数组运算,函数调用,跳转等内容。
(第3章2分)

第4章 汇编

4.1 汇编的概念与作用

概念:汇编是指汇编器(as)将包含汇编语言的.s文件翻译为机器语言指令,并把这些指令打包成为一个可重定位目标文件的格式,天生目标文件.o文件。.o文件是一个二进制文件。
作用:汇编就是将高级语言转化为机器可直接识别实行的代码文件的过程,汇编器将.s 汇编步伐翻译成机器语言指令,把这些指令打包成可重定位目标步伐的格式。通过汇编和天生目标文件的过程,C语言源代码被转换为机器语言的二进制表现。这个目标文件可以作为链接器的输入,与其他目标文件一起天生可实行文件或动态库文件,以便在计算机上运行和实行。
4.2 在Ubuntu下汇编的命令

命令:gcc -m64 -no-pie -fno-PIC -c hello.s -o hello.o
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps43.jpg&pos_id=MaGZBDRm
图4-1 Ubuntu下汇编命令
4.3 可重定位目标elf格式

4.3.1命令
在shell中输入readelf -a hello.o > hello.elf指令获得hello.o文件的ELF 格式 。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps44.jpg&pos_id=rgYuz8XC
图4-2 天生可重定位目标elf格式
4.3.2ELF头
ELF头(ELF header)以一个l6字节的序列开始,这个序列描述了天生该文件的体系的字的大小和字节顺序。ELF头剩下的部分包含了资助链接器语法分析和表明目标文件的信息,此中包罗ELF头的大小、目标文件的范例(如可重定位、可实行或者共享的)、机器范例(如x86-64)、节头部表(section header table)的文件偏移,以及节头部表中条目的大小和数量。不同节的位置和大小是有节头部表描述的,此中目标文件中每个节都有一个固定大小的条目(entry)(如图4-3)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps45.jpg&pos_id=tLLVmcaM
图4-3 ELF头
4.3.3节头
记载各节名称、范例、地点、偏移量、大小、全体大小、旗标、链接、信息、对齐(如图4-4)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps46.jpg&pos_id=vd40OgaX
图4-4 节头表
4.3.4重定位节
重定位节中包含了在代码中利用的一些外部变量等信息,在链接的时候必要根据重定位节的信息对这些变量符号举行修改。链接的时候链接器会根据重定位节的信息对外部变量符号决定选择何种方法计算精确的地点,通过偏移量等信息计算出精确的地点。.rel.text节是一个.text节中位置的列表,当链接器把这个目标文件和其他文件组合时,必要修改这些位置。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps47.jpg&pos_id=AynFuxNt
图4-5 重定位节信息
4.3.5符号表
.symtab节中包含ELF符号表,这张符号表包含一个条目的数组,存放一个步伐定义和引用的全局变量和函数的信息。该符号表不包含局部变量的信息。本步伐中的getchar、puts、exit等函数名都必要在这一部分体现。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps48.jpg&pos_id=QmbKyrmA
图4-6 符号表内容
4.4 Hello.o的效果解析

命令:objdump -d -r hello.o > Disas_hello.s
分析hello.o的反汇编,并与第3章的 hello.s举行对照分析发现有以下不同:

[*]操纵数进制不同
反汇编文件中的全部操纵数都改为十六进制(如图4-7),而hello.s中为十进制。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps49.jpg&pos_id=zX1PqmHq
图4-7 反汇编代码

[*]增加机器语言
每一条指令增加了一个十六进制的表现,即该指令的机器语言,(如图4-7),13:83 7d ec 05。

[*]分支转移
反汇编的跳转指令中,全部跳转的位置被表现为主函数+段内偏移量这样确定的地点,而不再是段名称(如图4-8)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps50.jpg&pos_id=3RbT2VJz
图4-8跳转指令位置

[*]函数调用
反汇编文件中对函数的调用与重定位条目相对应,hello.s中call指令后跟的是必要调用的函数的名称,而hello.o反汇编代码中 call 指令利用的是 main 函数的相对偏移地点(如图4-9)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps51.jpg&pos_id=j43U9bIs
图4-9 函数调用指令
4.5 本章小结


本章介绍了汇编的含义和功能。以Ubuntu体系下的hello.s文件为例,说明白如何把它汇编成hello.o文件,并天生ELF格式的可实行文件hello.elf。将可重定位目标文件改为ELF格式观察文件内容,对文件中的每个节举行简单解析。通过与 hello.s 的反汇编代码的比较相识在汇编过程中发生的变化。
(第4章1分)

第5章 链接

5.1 链接的概念与作用

概念:链接(linkng)是将各种代码和数据片段网络并组合为一个单一文件的过程,这个文件可被加载(复制)到内存并实行。链接可以实行与编译时(compile time),也可以实行与加载时(load time),甚至实行于运行时。
作用:链接是由叫做链接器(1iker)的步伐自动实行的,这使得分离编译成为大概。我们可以把一个大型的应用步伐分解为更小、更好管理的模块,可以独立地修改和编译这些模块。当我们改变这些模块中的一个时,只需简单地重新编译它,并重新链策应用。
5.2 在Ubuntu下链接的命令

命令:
ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linuxgnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so
/usr/lib/x86_64-linux-gnu/crtn.o
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps52.jpg&pos_id=Bd2BOtmO
图5-1 Ubuntu下链接命令
5.3 可实行目标文件hello的格式

命令:readelf -a hello > hello1.elf
5.3.1ELF头
   hello1.elf中的ELF头与hello.elf中的ELF头包含的信息种类根本相同,以描述了天生该文件的体系的字的大小和字节顺序的16字节序列Magic开始,剩下的部分包含资助链接器语法分析和表明目标文件的信息。与hello.elf相比较,hello1.elf中的根本信息未发生改变(如Magic,种别等),而范例发生改变,步伐头大小和节头数量增加,而且获得了入口地点。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps53.jpg&pos_id=RtfUdpIk
图5-2 ELF头
5.3.2节头

描述了各个节的大小、偏移量和其他属性。链接器链接时,会将各个文件的相同段归并成一个大段,而且根据这个大段的大小以及偏移量重新设置各个符号的地点。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps54.jpg&pos_id=CRcDTROX
图5-3 节头
5.3.3步伐头
步伐头部分是一个结构数组,描述了体系预备步伐实行所需的段或其他信息。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps55.jpg&pos_id=ti0Hbgx9
图5-4 步伐头
5.3.4Dynamic section
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps56.jpg&pos_id=4l2w0ejg
图5-5 Dynamic section
5.3.5Symbol table
符号表中保存着定位、重定位步伐中符号定义和引用的信息,全部重定位必要引用的符号都在此中声明。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps57.jpg&pos_id=GrbrHI7U
图5-6 符号表
5.4 hello的虚拟地点空间

利用edb打开hello从Data Dump窗口观察hello加载到虚拟地点的环境,查
看各段信息,如图5-7。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps58.jpg&pos_id=mgkECRyY
图5-7 edb中的data dump试图
步伐从地点0x400000开始到0x401000被载入,虚拟地点从0x4000000x400f0竣事,根据5.3中的节头部表,可以通过edb找到各段的信息。此中PHDR保存的是步伐头表;INTERP保存了步伐实行前必要调用的表明器;LOAD记载步伐目标代码和常量信息;DYNAMIC 储存了动态链接器所利用的信息;NOTE记载的是一些辅助信息;GNU_EH_FRAME保存非常信息;GNU_STACK利用体系栈所必要的权限信息;GNU_RELRO保存在重定位之后只读信息的位置。如.interp节,在hello.elf文件中能看到开始的虚拟地点,在edb中找到对应的信息(如图5-8)。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps59.jpg&pos_id=apEFueaY
图5-8 .interp节
5.5 链接的重定位过程分析

在Shell中利用命令objdump -d -r hello > hello1.asm天生反汇编文件hello1.asm
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps60.jpg&pos_id=dUY023Ws
图5-9 hello反汇编代码
hello与hello.o区别:

[*]链接后hello中函数数量增加,加入了代码中调用的一些库函数,如.plt,puts@plt,printf@plt,getchar@plt,exit@plt,sleep@plt等,同时每一个函数都有了相应的虚拟地点,这是由于动态链接器将共享库中hello.c用到的函数加入可实行文件中。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps61.jpg&pos_id=AC7tYyly
图5-10 链接后的反汇编文件中增加的函数

[*]函数调用指令call的参数发生变化,在链接过程中,链接器解析了重定位条目,call之后的字节代码被链接器直接修改为目标地点与下一条指令的地点之差,指向相应的代码段,从而得到完整的反汇编代码。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps62.jpg&pos_id=OvP83aQc
图5-11 调用指令

[*]跳转指令参数发生变化,在链接过程中,链接器解析了重定位条目,并计算相对距离,修改了对应位置的字节代码为PLT 中相应函数与下条指令的相对地点,从而得到完整的反汇编代码。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps63.jpg&pos_id=oeM0xf4s
图5-12 跳转指令

[*]hello中无hello.o中的重定位条目,而且跳转和函数调用的地点在 hello 中都变成了虚拟内存地点。这是由于hello.o中对于函数还未举行定位,只是在.rel.text 中添加了重定位条目,而hello举行定位之后不必要重定位条目。
重定位过程:重定位由两步组成,分别是重定位节和符号定义、重定位节中的符号引用。编译器和汇编器天生从 0 开始的代码和数据节。链接器通过把每个符号定义与一个内存位置关联起来,从而重定位这些节,然后修改全部对这些符号的引用,使得它们指向这个内存位置。链接器利用汇编器产生的重定位条目的具体指令,不加甄别地实行这样的重定位。
5.6 hello的实行流程

https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps64.jpg&pos_id=SawYTya7
图5-13edb检察步伐过程
如图5-13,通过利用edb实行hello,可以观察到hello步伐主要三步:

[*]开始实行:_start、_libe_start_main
[*]实行main:_main、printf、_exit、_sleep、getchar
[*]退出:exit
子步伐名或地点:
步伐名
步伐地点
_start
0x4010f0
_libc_start_main
0x2f12271d
main
0x401125
_printf
0x4010a0
_sleep
0x4010e0
_getchar
0x4010b0
_exit
0x4010d0

5.7 Hello的动态链接分析

动态链接是把步伐按照模块拆分成各个相对独立部分,在步伐运行时才将它们链接在一起形成一个完整的步伐,在调用共享库函数时,编译器没有办法猜测这个函数的运行时地点,由于定义它的共享模块在运行时可以加载到任意位置。正常的方法是为该引用天生一条重定位记载,然后动态链接器在步伐加载的时候再解析它。延迟绑定是通过GOT和PLT实现的,根据hello.elf文件可知,GOT起始表位置为0x404000。通过观察edb,可发现dl_init后.got.plt 节发生的变化。
plt初始存的是一批代码,它们跳转到got所指示的位置,然后调用链接器。初始时got内里存的都是plt的第二条指令,随后链接器修改got,下一次再调用plt时,指向的就是精确的内存地点。接下来实行步伐的过程中,就可以利用过程链接表plt和全局偏移量表got举行动态链接。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps65.jpg&pos_id=ndHwpAeR
图5-14 实行init前地点
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps66.jpg&pos_id=pDpEV8X6
图5-15 实行init后地点
5.8 本章小结

本章首先阐述了链接的根本概念和作用,展示了利用命令链接天生hello可实行文件,观察了hello文件ELF格式下的内容,利用edb观察了hello文件的虚拟地点空间利用环境,最后以hello步伐为例对重定位过程、实行过程和动态链接举行分析。
在链接过程中,各种代码和数据片段网络并组合为一个单一文件。利用链接器,分离编译称为大概,我们不消将应用步伐组织为巨大的源文件,只是把它们分解为更小的管理模块,并在应用时将它们链接就可以完成一个完整的任务。
(第5章1分)


第6章 hello进程管理

6.1 进程的概念与作用

概念:进程(Process)是计算机中的步伐关于某数据聚集上的一次运行活动,是体系举行资源分配和调度的根本单元,是操纵体系结构的基础。在早期面向进程设计的计算机结构中,进程是步伐的根本实行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。步伐是指令、数据及其组织情势描述,进程是步伐的实体。
作用:在现代体系上运行一个步伐时,我们会得到一个假象,好像我们的步伐是体系中唯一运行的步伐一样。我们的步伐好像独占处置惩罚器和内存。处置惩罚器好像无间断地一条接一条实行我们步伐中的指令,我们步伐中的代码和数据好像是体系内存中唯一的对象。这些假象是通过进程的概念提供的。
6.2 简述壳Shell-bash的作用与处置惩罚流程

作用:Shell是一个交互型应用级步伐,也被称为命令解析器,它为用户提供一个操纵界面,接受用户输入的命令,并调度相应的应用步伐。
处置惩罚流程:
(1)从终端读入输入的命令。
(2)将输入字符串切分获得全部的参数
(3)如果是内置命令则立即实行
(4)否则调用相应的步伐实行
(5)shell 应该接受键盘输入信号,并对这些信号举行相应处置惩罚
6.3 Hello的fork进程创建过程

用户在shell界面输入指令后,Shell判断该指令不是内置命令,于是父进程调用fork函数创建一个新的子进程,该子进程得到与父进程用户级虚拟地点空间相同的一份副本,包罗代码和数据段、堆、共享库以及用户栈。子进程与父进程最大的区别就是具有不同的PID。在父进程中,fork返回子进程的PID,而在子进程中fork返回0,返回值提供一个明确的方法来分辨步伐是父进程还是在子进程中实行。
6.4 Hello的execve过程

execve函数声明为int execve(const char *filename, const char *argv[], const char *envp[]);exceve 函数在当前进程的上下文中加载并运行一个新步伐。exceve 函数加载并运行可实行目标文件filename,并带参数列表和环境变量列表。只有当出现错误时,exceve才会返回到调用步伐。以是,与 fork 一次调用返回两次不同,在 exceve 调用一次并从不返回。当加载可实行目标文件后,exceve 调用启动代码,启动代码设置栈,将可实行目标文件中的代码和数据从磁盘复制到内存中,然后通过跳转到步伐的第一条指令或入口点来运行该步伐,由此将控制传递给新步伐的主函数。
6.5 Hello的进程实行

(1)上下文切换:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps67.jpg&pos_id=bLjqKTZ5
图6-1 上下文切换
图6-1为上下文切换示例,操纵体系内核利用一种称为上下文切换的叫高层情势的非常控制流来实现多任务。内核为每一个进程维持一个上下文。上下文就是内核重新启动一个被抢占的进程所需状态。
(2)时间片:一个进程实行它的控制流的一部分的每一时间段叫做时间片。因此,多任务也叫做时间分片。
(3)用户模式和内核模式。处置惩罚器通常利用某个控制寄存器中的一个模式位来提供这种功能。当设置了模式位时,进程就运行在内核模式里。一个运行在内核模式的进程可以实行指令会合的全部指令且可以访问体系中的任何内存位置。没有设置模式位时,进程就运行在用户模式中。用户模式中的进程不答应实行特权指令,也不能直接引用地点空间中内核区内的代码和数据。
(4)进程调度:即使在体系中通常有很多其他步伐在运行,进程也可以向每个步伐提供一种假象,好像它在独占地利用处置惩罚器。如果想用调试器单步实行步伐,我们会看到一系列的步伐计数器(PC)的值,这些值唯一的对应于包含在运行时动态链接到步伐的共享对象中的指令。这个 PC 的序列叫做逻辑控制流,或者简称逻辑流。
进程是轮流适用处置惩罚器的,每个进程实行它的流的一部分,然后被抢占,然后轮到其他进程。在进程实行的某些时刻,内核可以决定抢占当前进程,并重新开始一个先前被抢占了的进程,这种决定就叫做调度,是由内核中称为调度器的代码处置惩罚的。当内核选择一个新的进程运行,我们说内核调度了这个进程。在内核调度了一个新的进程运行了之后,它就抢占了当前进程,并利用上下文切换机制来将控制转移到新的进程。
6.6 hello的非常与信号处置惩罚

非常范例:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps68.jpg&pos_id=K2QPHfsD
非常处置惩罚方式:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps69.jpg&pos_id=x7INnkgQ
图6-2 制止处置惩罚
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps70.jpg&pos_id=ECvD4z50
图6-3 陷阱处置惩罚
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps71.jpg&pos_id=tAytJ9Gh
图6-4 故障处置惩罚
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps72.jpg&pos_id=e56ZDdE8
图6-5 制止处置惩罚

不绝乱按:不影响步伐实行
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps73.jpg&pos_id=cxExZD8p
按下 Ctrl-Z:步伐运行时按 Ctrl-Z,这时,产生制止非常,它的父进程会接收到信号 SIGSTP 并运行信号处置惩罚步伐,然后便发现步伐在这时被挂起了,并打印了相干挂起信息。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps74.jpg&pos_id=tZikOO7j
按下Ctrl + C:Shell进程收到SIGINT信号,Shell竣事并回收hello进程。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps75.jpg&pos_id=QNCyflRH
按下Ctrl-z后运行ps  jobs  pstree  fg  kill 等命令:输入pstree命令,可以将全部进程以树状图表现;输入kill命令,则可以杀死指定(进程组的)进程。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps76.jpg&pos_id=rxYZHA8l
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps77.jpg&pos_id=wKe8PiGA

6.7本章小结

本章介绍了进程的概念与作用,简述了壳Shell-bash的作用与处置惩罚流程,说明白Hello的进程创建、启动和实行过程,最后,对hello步伐大概出现的非常环境,以及运行效果中的各种输入举行了表明和说明。
(第6章1分)

第7章 hello的存储管理

7.1 hello的存储器地点空间

逻辑地点:编译器举行编译时,产生汇编汇编代码,每局代码以及每条数据都会有本身的逻辑地点。逻辑地点用来指定一个操纵数或者是一条指令的地点。是由一个段标识符加上一个指定段内相对地点的偏移量。
线性地点:CPU加载步伐后,会为步伐分配内存,分配的内存分为代码段数据和数据段数据。线性地点是逻辑地点到物理地点变更之间的一步,步伐hello的代码会产生逻辑地点,在分段部件中逻辑地点是段中的偏移地点,加上基地点就是线性地点。
虚拟地点:线性地点的别称。虚拟地点颠末地点翻译得到物理地点。
物理地点:出现在CPU外部地点总线上的寻址物理内存的地点,在存储器里以字节为单元存储信息,每一个字节单元给一个唯一的存储器地点。
7.2 Intel逻辑地点到线性地点的变更-段式管理

在Intel x86处置惩罚器中,段式内存管理是一种常用的方法,用于将逻辑地点转换为线性地点。段式管理是通过将内存分别为不同的段(例如代码段、数据段、堆栈段等)来实现的。每个段都有本身的基地点和界限,逻辑地点由段号和段内偏移量组成。段标识符是由一个16位长的字段组成的,称为段选择符。此中前13位是一个索引号,后3位为一些硬件细节。索引号即是“段描述符”的索引,段描述符具体地点描述了一个段,很多个段描述符就组成了段描述符表。通过段标识符的前13位直接在段描述符表中找到一个具体的段描述符。
段式管理的主要步骤如下:
(1)将逻辑地点分解为段号和段内偏移量。
(2)找到对应的段描述符。段描述符存储了段的基地点、界限等信息。
(3)查抄段内偏移量是否凌驾段的界限,如果凌驾则产生非常。
(4)将段基地点加上段内偏移量,得到线性地点。
7.3 Hello的线性地点到物理地点的变更-页式管理

在页式内存管理中,线性地点通过页表映射到物理地点。页表将虚拟地点(线性地点)分别为固定大小的页(通常为4KB),并为每个页分配一个物理帧号。页表存储在主存中,每个进程都有一个页表。页表就是一个页表条目(PTE)的数组,每个PTE由一个有用位和一个位地点字段组成,有用位表明白该虚拟页当前是否被缓存在DRAM中,如果设置了有用位,那么地点字段就表现DRAM中相应的物理页的起始位置,如果发生缺页,则从磁盘读取。MMU利用页表来实现从虚拟地点到物理地点的翻译。图7-1为页表管理图示。
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps78.jpg&pos_id=sdp3oLHO
图7-1 页表管理

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

当举行TLB与四级页表支持下的VA到PA变更时,主要经历以下过程(如图7-2):
(1)TLB查询:CPU会首先查抄TLB,检察是否缓存了与此虚拟地点相对应的物理地点。如果命中,则直接返回物理地点。否则,实行下一步。
(2)四级页表查询:
   a. 获取虚拟地点的最高12位(例如)作为PGD(Page Global Directory)索引,在PGD表中查找相应的表项。
   b. 利用虚拟地点的中心12位(例如)作为PMD(Page Middle Directory)索引,在PMD表中查找相应的表项。
   c. 利用虚拟地点的中下12位(例如)作为PTE(Page Table Entry)索引,在PTE表中查找相应的表项。
   d. 利用虚拟地点的最低12位(例如)作为PPE(Page Page Directory)索引,在PPE表中查找相应的表项。
在上述过程中,每一步都会查抄对应的表项是否存在或正当。如果某一步未命中,则产生页错误非常。如果全部步骤均命中,将得到终极的物理帧号。
(3)物理地点天生:将物理帧号与虚拟地点的页内偏移量归并,天生终极的物理地点。

https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Casus%5CAppData%5CLocal%5CTemp%5Cksohtml9380%5Cwps79.jpg&pos_id=FfzqVjF7
图7-2 四级页表工作原理
7.5 三级Cache支持下的物理内存访问

在三级缓存(三级Cache)支持下的物理内存访问过程中,CPU通常利用缓存来进步内存访问的速度。三级缓存的结构和原理如下:
(1)L1 Cache(一级缓存):位于CPU焦点内部,速度最快,容量最小。每个CPU焦点都有本身的L1缓存,只缓存当前焦点利用的数据。
(2)L2 Cache(二级缓存):位于CPU焦点外部,速度中等,容量较大。L2缓存通常为多个CPU焦点共享,用于缓存频繁访问的数据。
(3)L3 Cache(三级缓存):位于CPU外部,速度较慢,容量最大。L3缓存通常为整个CPU共享,用于缓存大量数据。
当CPU必要访问物理内存时,会首先查询所需的数据是否在缓存中。如果缓存命中,则直接从缓存中读取数据;否则,会从物理内存中读取数据,并将数据缓存到相应的缓存级别中。
三级缓存支持下的物理内存访问过程:
(1)CPU天生物理地点:CPU将虚拟地点颠末页表和TLB转换得到物理地点。
(2)L1 Cache查询:CPU首先查询L1 Cache,检察所需的数据是否在L1缓存中。如果命中,则直接读取数据。
(3)L2 Cache查询:如果L1 Cache未命中,则CPU查询L2 Cache。如果命中,则直接读取数据,并更新。
(4)L3 Cache查询:如果L2 Cache未命中,则CPU查询L3 Cache。如果命中,则直接读取数据,并更新。
(5)物理内存访问:如果L3 Cache未命中,则CPU直接访问物理内存,获取所需的数据,并将数据缓存到L3 Cache、L2 Cache和L1 Cache中。
7.6 hello进程fork时的内存映射

进程fork时的内存映射指的是在UNIX操纵体系(如Linux)中,当一个进程fork创建出新的子进程时,子进程和父进程之间的内存映射关系。这种内存映射有助于节流内存资源,并进步子进程启动速度。
当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新进程创建虚拟内存,它创建了当前进程的mm_ struct、.区域结构和页表的原样副本。当fork在新进程中返回时,新进程现在的虚拟内存刚好和调用fork时存在的虚拟内存相同。当这两个进程中的任何一个。后来举行写操纵时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地点空间的抽象概念。
7.7 hello进程execve时的内存映射

execve函数调用驻留在内核区域的启动加载器代码,在当前进程中加载并运行包含在可实行目标文件hello中的步伐,主要包罗以下过程:
(1)删除已存在的用户区域
(2)映射私有区域:全部这些新的区域都是私有的、写时复制的。代码和数据被映射至.text区和.data区。bss区域,堆是请求二进制零的区域。
(3)映射共享区域:hello步伐与共享对象链接,这些对象动态链接到hello步伐,然后映射到用户虚拟地点空间。
(4)设置步伐计数器:设置当前进程上下文的步伐计数器,使之指向代码区域的入口点。
7.8 缺页故障与缺页制止处置惩罚

缺页故障:当进程访问的页面不在物理内存时,就会发生缺页故障。这大概是由于页面从未被加载到物理内存,或者由于它已经被置换到磁盘上以腾出物理内存空间。缺页故障会导致处置惩罚器产生一个非常,称为缺页制止。
缺页制止处置惩罚:
当操纵体系接收到缺页制止时,它会实行以下步骤来处置惩罚故障:
(1)确定必要访问的虚拟页面。这通常是由处置惩罚器提供的信息来识别的。
(2)查抄虚拟页面是否属于当前进程。如果不是,操纵体系大概会触发一个段错误,由于它大概意味着进程试图访问不属于它的内存。
(3)如果虚拟页面属于当前进程,操纵体系会在物理内存中查找一个空闲的页面帧。如果找不到空闲的页面帧,操纵体系大概会将内存中的一个或多个页面置换到磁盘上,以便为所需的页面腾出空间。这大概会导致其他进程的缺页制止。

(4)一旦找到了空闲的页面帧,操纵体系会将所需的虚拟页面加载到该页面帧中。这大概必要从磁盘上的页面交换文件读取页面,或者从进程的工作会合加载页面,如果它在工作会合已被置换到磁盘上。
(5)更新页表,将虚拟页面映射到新的物理地点。
(6)操纵体系会返回到发生缺页制止的指令,处置惩罚器将继承实行该指令。
(7)如果在物理内存中找不到空闲的页面帧,操纵体系大概会选择牺牲一些体系资源,如缓存或缓冲区,以便为所需的页面腾出空间。
缺页制止处置惩罚是操纵体系内存管理的关键部分,由于它有助于确保进程能够有用地访问其虚拟地点空间,并在物理内存不足的环境下仍然可以运行。
7.9动态存储分配管理

动态内存管理是计算机内存管理中的一种手段,用于在运行时动态分配和释放内存,以顺应步伐的内存需求。动态内存管理的根本方法和策略包罗:
(1)堆和栈:动态内存管理通常利用堆和栈来实现。栈用于存储局部变量、函数参数和返回值,由编译器自动管理。堆用于动态分配内存,答应步伐在运行时请求和释放内存。步伐可以利用malloc、calloc、realloc等函数在堆上申请内存,利用free函数释放内存。
(2)内存分配策略:动态内存管理的一个重要策略是确定何时分配和释放内存。常见的策略包罗:
  a.首次适配:在堆中搜刮第一个能满意请求大小的空闲块,并将其分配。
  b.下次适配:从上一次分配的位置开始搜刮,找到第一个能满意请求大小的空闲块。
  c.最佳适配:在堆中搜刮一个满意请求大小且大小最小的空闲块。
  d.最差适配:在堆中搜刮一个能满意请求大小且大小最大的空闲块。
(3)内存碎片:动态内存管理大概导致内存碎片,这是由于频繁地分配和释放不连续的内存块导致的。内存碎片有两种范例:内部碎片和外部碎片。内部碎片是指已分配内存块之间的未利用空间,外部碎片是指未分配的、不连续的内存空间。
(4)内存紧凑:这是一种用于减少内存碎片的技术。通过将存活的对象移动到一起,紧凑算法可以减少内部碎片。
(5)垃圾回收:这是一种用于自动释放不再利用的内存的技术。垃圾回收器会跟踪内存的利用环境,识别不再利用的内存并释放它们。垃圾回收算法有多种,如标志-清除、复制、标志-整理等。
(6)内存池:这是一种用于优化动态内存管理的技术。内存池在步伐启动时预先分配一大块内存,然后根据需求将其分割为更小的内存块。内存池可以通过重用已分配的内存块来减少内存分配和释放的开销。
7.10本章小结

本章介绍了hello的存储器地点空间,Intel逻辑地点到线性地点的变更-段式管理,Hello的线性地点到物理地点的变更-页式管理,TLB与四级页表支持下的VA到PA的变更,三级Cache支持下的物理内存访问,hello进程fork时的内存映射,hello进程execve时的内存映射,缺页故障与缺页制止处置惩罚以及动态存储分配管理。
(第7章 2分)

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

在linux中全部的I/O设备都被模子化为文件,全部的输入和输出都被当做对相应文件的读和写来实行。
设备的模子化:文件
设备管理:unix io接口
8.2 简述Unix IO接口及其函数

UNIX操纵体系提供了一套IO接口,用于实现对各种设备的访问和控制。这些接口被称为UNIX IO接口,通常通过一组函数来实现。这些函数可以用于文件、设备等资源的打开、关闭、读写等操纵。以下是一些常见的UNIX IO接口及其函数:
(1)文件打开和关闭:
  int open(const char *path, int flags, mode_t mode);
  int close(int fd);
 这些函数用于打开和关闭文件。open函数返回一个文件描述符,用于后续对该文件的操纵。close函数用于关闭一个打开的文件。
(2)读和写:
ssize_t read(int fd, void *buf, size_t count);
  ssize_t write(int fd, const void *buf, size_t count);
 这些函数用于从文件中读取数据和向文件中写入数据。read函数从文件中读取最多count个字节到缓冲区buf中,返回实际读取的字节数。write函数将缓冲区buf中的count个字节写入文件,返回实际写入的字节数。
8.3 printf的实现分析

printf函数实现:
int printf(const char *fmt, ...)
{
int i;
char buf;
va_list arg = (va_list)((char*)(&fmt) + 4);
i = vsprintf(buf, fmt, arg);
write(buf, i);
return i;
}
此中vsprintf(buf, fmt, arg)函数能够返追念要打印的字符串的长度并对格式化字符串举行解析。当获取到字符串的长度后,便能打印出字符串。
从vsprintf天生表现信息,到write体系函数,到陷阱-体系调用 int 0x80或syscall等.
字符表现驱动子步伐:从ASCII到字模库到表现vram(存储每一个点的RGB颜色信息)。
表现芯片按照革新频率逐行读取vram,并通过信号线向液晶表现器传输每一个点(RGB分量)。
8.4 getchar的实现分析

getchar能够读取stdin,然后获取输入的字符。
异步非常-键盘制止的处置惩罚:键盘制止处置惩罚子步伐。接受按键扫描码转成ascii码,保存到体系的键盘缓冲区。
getchar等调用read体系函数,通过体系调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结

本章介绍了Linux的IO设备管理方法,简述了Unix IO接口及其函数,并分析了printf和getchar的实现。
(第8章1分)
结论

Hello经历的历程:
(1)hello.c由预处置惩罚器举行预处置惩罚,形成hello.i文件。
(2)hello.i颠末编译,形成汇编代码hello.s。
(3)hello.s颠末汇编,天生可重定位目标文件hello.o。
(4)hello.o颠末链接,天生可实行文件hello
(5)shell-bash步伐调用fork函数为hello天生进程,并调用execve函数
(6)execve使hello载入内存并运行。
(7)步伐运行的效果通过I/O设备呈现。
(8)运行制止后被shell回收,内核清空hello的信息。
通过对hello一生的追寻,我认识到一个简单步伐的实行也必要很多很多的步骤,并发现了计算机体系的奥妙之处。我深切感受到计算机体系的精细和强大,每一个简单的任务都必要计算机的各种复杂的操纵来完成。

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

hello.c
源步伐
hello.i
预处置惩罚后得到的文本文件
hello.s
编译后得到的汇编语言文件
hello.o
汇编后得到的可重定位目标文件
hello
可实行目标步伐
elf.txt
hello.o 的 ELF 格式
hello.asm
反汇编hello.o得到的反汇编文件
hello1.asm
反汇编hello可实行文件得到的反汇编文件


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

参考文献

为完本钱次大作业你翻阅的册本与网站等
  Randal E.Bryant David R.O'Hallaron.深入理解计算机体系(第三版).机械工业出版社,2016.
  https://www.cnblogs.com/buddy916/p/10291845.html
  https://www.cnblogs.com/pianist/p/3315801.html
  https://www.cnblogs.com/fanzhidongyzby/p/3519838.html.
  https://www.cnblogs.com/diaohaiwei/p/5094959.html
  https://blog.csdn.net/spfLinux/article/details/54427494
(参考文献0分,缺失 -1分)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 步伐人生-Hello‘s P2P