盘算机系统
大作业
摘 要
本文从hello.c步调入手开始逐步分析,展示经预处理、编译、汇编和链接生成可执行文件的全过程,阐述盘算机系统对hello步调的历程管理和存储管理,展示hello步调在Linux系统中的完整生命周期。在假造机Ubuntu中,将采用gcc、edb等工具进行探索,从而加深读者对于盘算机系统的明白。
关键词:hello步调;预处理;编译;汇编;链接;历程管理;存储管理
目 录
第1章 概述... - 4 -
1.1 Hello简介... - 4 -
1.2 环境与工具... - 4 -
1.3 中间效果... - 4 -
1.4 本章小结... - 5 -
第2章 预处理... - 6 -
2.1 预处理的概念与作用... - 6 -
2.2在Ubuntu下预处理的下令... - 6 -
2.3 Hello的预处理效果解析... - 6 -
2.4 本章小结... - 7 -
第3章 编译... - 8 -
3.1 编译的概念与作用... - 8 -
3.2 在Ubuntu下编译的下令... - 8 -
3.3 Hello的编译效果解析... - 9 -
3.4 本章小结... - 12 -
第4章 汇编... - 13 -
4.1 汇编的概念与作用... - 13 -
4.2 在Ubuntu下汇编的下令... - 13 -
4.3 可重定位目标elf格式... - 13 -
4.4 Hello.o的效果解析... - 15 -
4.5 本章小结... - 17 -
第5章 链接... - 18 -
5.1 链接的概念与作用... - 18 -
5.2 在Ubuntu下链接的下令... - 18 -
5.3 可执行目标文件hello的格式... - 18 -
5.4 hello的假造地点空间... - 21 -
5.5 链接的重定位过程分析... - 21 -
5.6 hello的执行流程... - 23 -
5.7 Hello的动态链接分析... - 24 -
第6章 hello历程管理... - 26 -
6.1 历程的概念与作用... - 26 -
6.2 简述壳Shell-bash的作用与处理流程... - 26 -
6.3 Hello的fork历程创建过程... - 26 -
6.4 Hello的execve过程... - 26 -
6.5 Hello的历程执行... - 27 -
6.6 hello的异常与信号处理... - 27 -
6.7本章小结... - 30 -
第7章 hello的存储管理... - 31 -
7.1 hello的存储器地点空间... - 31 -
7.2 Intel逻辑地点到线性地点的变换-段式管理... - 31 -
7.3 Hello的线性地点到物理地点的变换-页式管理... - 31 -
7.4 TLB与四级页表支持下的VA到PA的变换... - 31 -
7.5 三级Cache支持下的物理内存访问... - 32 -
7.6 hello历程fork时的内存映射... - 33 -
7.7 hello历程execve时的内存映射... - 33 -
7.8 缺页故障与缺页中断处理... - 33 -
7.9本章小结... - 34 -
结论... - 35 -
附件... - 36 -
参考文献... - 37 -
第1章 概述
1.1 Hello简介
P2P(From Program to Process):从Program开始,hello.c颠末预处理、编译、汇编和链接四个过程生成可执行文件。预处理阶段利用预处理器cpp,根据以#开头的代码修改原始步调,读取头文件,将此中的内容加入源步调得到别的一个c步调hello.i(仍然是一个文本文件)。然后通过编译器编译(词法分析语法分析,语义分析,中间代码生成优化等)生成hello.s。然后通过汇编器(as)进行汇编,根据指令集将汇编步调hello.s翻译为机器指令,并且把这一系列机器指令按照固定的规则进行打包得到可重定位的目标文件hello.o(二进制)。最后链接器进行链接得到可执行文件hello(二进制),在linux环境下利用指令./hello启动步调,shell调用函数fork()产生子历程hello就完成了从Program到Progress的过程。
020(From Zero-0 to Zero-0):开始时内存中并没有hello步调,即从0开始,在运行结束之后,hello历程回收,内核数据也删除,最终将hello在内存中存在的陈迹全部去掉,即以0结束,故为020。
1.2 环境与工具
硬件环境:X64 CPU 3.2GHz,64GB RAM,1TB SSD。
软件环境:Windows 11 64位;VMware Workstation 17;Ubuntu 22.04 LTS 64位。
开发工具:Visual Studio 2022;Codeblocks;vim;gcc;edb。
1.3 中间效果
文件名
| 作用
| hello.c
| 源文件
| hello.i
| 预处理后文件
| hello.s
| 编译后文件
| hello.o
| 可重定位目标文件
| hello
| 可执行目标文件
| hello.elf
| hello.o的elf文件
| hello2.elf
| hello的elf文件
| hello.fan
| hello.o反汇编得到文件
| hello2.fan
| hello反汇编得到文件
|
1.4 本章小结
本章简要介绍了P2P和020的过程,介绍了完资本文过程中利用的环境和开发工具,并给出了hello步调在生命周期中产生的中间文件,初步介绍了hello步调的一生。
第2章 预处理
2.1 预处理的概念与作用
概念:预处理是指预处理器根据以字符#开头的下令(包括宏定义、条件编译和源文件包罗等),修改原始的C步调,插入指定文件,扩展指定的宏,得到一个完整的文本文件。
作用:预处理读取预处理下令,根据不同的下令对源文件进行处理,得到新的文本代码,同时还会删除步调中的解释和多余的空白字符。预处理将源文件中以“include”格式包罗的文件复制到编译的源文件中;用实际值替换用“#define”定义的字符串,进行宏替换;根据“#if”等后面的条件决定须要编译的代码。
2.2在Ubuntu下预处理的下令
预处理下令:gcc -E hello.c -o hello.i
图1 预处理过程
2.3 Hello的预处理效果解析
图2 hello.i文件(开头部门)
图3 hello.i文件(末尾部门)
可以看到,在hello.i文件中仍有hello.c的原内容,是C语言的步调文本。同时,将源文件中的解释删除了。除此之外,hello.i文件中增长了三个头文件(stdio.h,unistd.h,stdlib.h)的源代码,而主函数main并未发生变化。
2.4 本章小结
本章介绍了预处理的概念及作用,并演示了在Ubuntu假造机下对hello.c进行预处理的过程,对预处理效果hello.i进行了分析。
第3章 编译
3.1 编译的概念与作用
概念:编译是指编译器将预处理后得到的.i文件(文本文件)处理成为.s文件(文本文件),它包罗一个汇编语言步调。
作用:编译将高级语言转为较低级的汇编语言。分为五个阶段:词法分析、语法分析、语义检查和中间代码生成、代码优化、目标代码生成。
1词法分析:词法分析的任务是对由字符构成的单词进行处理,从左至右逐个字符地对源步调进行扫描,产生一个个的单词符号,把作为字符串的源步调改造成为单词符号串的中间步调。执行词法分析的步调称为词法分析步调或扫描器。
2语法分析:以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的步调,按该语言利用的语法规则分析检查每条语句是否有正确的逻辑结构,步调是最终的一个语法单位。编译步调的语法规则可用上下文无关文法来刻画。
3中间代码:源步调的一种内部表示,或称中间语言。中间代码的作用是可使 编译步调的结构在逻辑上更为简朴明确,特别是可使目标代码的优化比力 容易实现中间代码。
4代码优化:代码优化是指对步调进行多种等价变换,使得从变换后的步调出发,能生成更有用的目标代码。所谓等价,是指不改变步调的运行效果。所谓有用,主要指目标代码运行时间较短,以及占用的存储空间较小。这种变换称为优化。
5目标代码生成:目标代码生成器把语法分析后或优化后的中间代码经汇编步调汇编生成汇编语言代码,成为可执行的机器语言代码。
3.2 在Ubuntu下编译的下令
编译下令:gcc -S hello.i hello.s
图4编译下令
3.3 Hello的编译效果解析
图5 hello.s文件(部门)
赋值操纵利用mov,主要应用后缀为l与q,l表示四字节,q表示八字节。全局变量main,范例function,保存在.text。
图6 全局变量main
字符串以string标注。
图7 字符串
局部变量int i:movl $0,-4(%rbp)指将0赋给局部变量i,将i保存在地点%rbp-4处。
图8 局部变量i
数组*argv[],整型数据argc:movq %rsi ,-32(%rbp),将argv首地点保存在%rbp-32处,movl %edi ,-20(%rbp),将argc保存在%rbp-20处。
图9 char *argv[]和int argc
(1)加法:add a,b等价于b=a+b。hello中主要应用如下:
图10 加法操纵
(2)减法:sub a,b等价于b=b-a。hello中主要应用如下
图11 减法操纵
(3)地点之间的赋值leaq a,b等价于b=&a,具体应用如下:
图12 地点赋值
关系操纵指cmp a,b,即比力a与b的大小,通常与控制转移语句一起利用。hello中出现的控制转移语句有je,a和b相等则跳转;jle,b小于即是a则跳转;以及jmp,无条件跳转,具体如下:
(1)je:比力argc和4,即是跳转到L2
图13 je跳转
(2)jle:比力i和8,i<=8则跳转到L4
图14 jle跳转
(3)jmp:直接跳转到L3
图15 jmp跳转
调用函数时用指令call,hello中一共调用了以下函数:
图16 puts函数
图17 exit函数
图18 printf函数
图19 atoi函数
图20 sleep函数
图21 getchar函数
3.4 本章小结
本章介绍了编译的概念及作用,演示了在Ubuntu假造机下对hello.i进行编译得到hello.s的过程,并分析了编译效果。在效果分析部门,对hello.c中存在的数据及赋值操纵、算术操纵、关系操纵、控制转移和函数操纵进行了具体的分析,具体解读了hello的编译效果。
第4章 汇编
4.1 汇编的概念与作用
概念:汇编是指将.s文件进行翻译的过程。汇编器(as)将.s文件翻译成.o文件,即从编译后的文件到生成机器语言二进制步调的过程。
作用:将汇编代码翻译成机器语言,使得盘算性能够直接识别和执行。
4.2 在Ubuntu下汇编的下令
汇编下令:gcc -c hello.s -o hello.o
图22 汇编下令
4.3 可重定位目标elf格式
下令:readelf -a hello.o >hello.elf
图23 生成elf文件
对生成的elf文件分析如下:
图24 elf头
首先以一个16字节序列开始,形貌了生成该文件的系统的字大小和字节次序。剩下的部门包罗资助链接器进行语法分析和解释目标文件的信息,此中包括ELF头的大小、目标文件的范例(可重定位、可执行、共享)、机器范例(X86-64等,本例中为假造机unix)、节头部表的文件偏移以及节头部表中条目的大小和数量。
图25 节头
包罗各节的名称、大小、范例、地点和偏移量。
图26 .rela.text
节中包罗了该步调所调用的函数puts、exit、printf、atoi、sleep、getchar,别的还包罗着两处字符串(L0,L1)(用.rodata表示),这一节中写明了它们的名称、信息、寻址范例(绝对寻址、PC相对寻址)、偏移量以及符号值。
图27 .rala.eh_frame
.rela.text节利用了绝对寻址,而.rela.eh_frame节利用了PC相对寻址。
图28 符号表
符号表存储了步调中定义和引用的函数和全局变量的信息。每个可重定位目标文件在.symtab中都有一张符号表。
4.4 Hello.o的效果解析
反汇编下令:objdump -d -r hello.o > hello.fan
图29 反汇编下令
图30 反汇编文件
比力hello.fan与hello.s文件,有如下几处不同:
在hello.s文件中,直接利用语句call后面加函数名进行调用。
图31 hello.s文件中调用函数
而在hello.fan中,则利用重定位符号引用的方式调用函数,须要与动态链接器作用才能确定函数运行时地点。
图32 hello.fan文件中调用函数
hello.s中jxx后直接跟所要跳转的段,如L1、L2等。
图33 hello.s文件中的跳转语句
hello.fan中jxx后跟所要跳转地点相对于main的偏移量。
图34 hello.fan中的跳转语句
hello.s中通过段地点加%rip完成。
图35 hello.s中全局变量访问
hello.fan中则通过0+%rip完成。
图36 hello.fan中全局变量访问
4.5 本章小结
本章介绍了汇编的概念及作用,分析了elf文件的各构成部门,对hello.o文件进行反汇编并与hello.s文件进行了比力。
第5章 链接
5.1 链接的概念与作用
概念:链接是指将一个或多个由编译器或汇编器生成的目标文件和库链接为一个可执行文件的过程,也就是从.o文件到可执行文件的过程。目标文件是包括机器码和链接器可用信息的步调模块。链接可以执行于编译时,也就是在源代码被翻译成机器代码时;也可以执行于加载时,也就是在步调被加载器加载到内存并执行时;也可以执行于运行时,也就是由应用步调来执行。
作用:链接使得分离编译成为可能,这样,不须要将一个大型的应用步调组织为一个巨大的源文件,而是可以把它分解为更小、更好管理的模块,可以独立地修改和编译这些模块。当我们改变这些模块中的一个时,只需简朴地重新编译它,并重新链策应用,而不必重新编译其它文件。
5.2 在Ubuntu下链接的下令
链接下令为ld -o hello -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 /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o
图37 链接下令
5.3 可执行目标文件hello的格式
输入下令readelf -a hello >hello2.elf生成文件hello2.elf。
图38 生成elf文件
对生成的elf文件分析如下:
图39 elf头
与上一章hello.elf大同小异,分析详见上一章。可以看到,文件范例变为可执行文件。
图40 节头
(3)步调头
图41 步调头
该节为可执行文件相比与可重定位文件新增的,包罗了偏移量、假造地点及物理地点,根据查阅资料得知:
PHDR:指定步调头表在文件及步调内存映像中的位置和大小
INTERP:指定要作为解释步调调用的以空字符结尾的路径名的位置和大小。
LOAD:指定由p_filesz和p_memsz形貌的可装入段。
DYNAMIC:指定动态链接信息。
NOTE:指定辅助信息的位置和大小。
GNU_STACK:标志栈是否可执行
GNU_RELRO:重定位后需被设定为只读内存区域
(4)重定位节
图42 重定位节
(5)符号表
图43 符号表
5.4 hello的假造地点空间
图44 edb查看hello的假造地点空间
可以看到,在步调头表中形貌的段的各类信息(范例、起始地点和大小等)均和Data Dump查看效果同等。实际上,全部段的假造地点信息都被正确而完整地记录在了步调头表中。
5.5 链接的重定位过程分析
输入下令objdump -d -r hello >hello2.fan将hello反汇编并保存在hello2.fan中。
图45 反汇编下令
不同之处:
(1)增长了很多函数:在hello中多了很多函数如printf等,原因是链接时将库中所用代码加入hello。
图46 新增函数
(2)地点:hello.o中无确切地点,未进行重定位,而hello中已经有了确定的假造地点,说明已完成重定位。
图47 hello文件
图48 hello.o文件
5.6 hello的执行流程
子步调名
| 步调地点
| <_init>
| 4004c0
| <.plt>
| 4004e0
| <puts@plt>
| 4004f0
| <printf@plt>
| 400500
| <getchar@plt>
| 400510
| <atoi@plt>
| 400520
| <exit@plt>
| 400530
| <sleep@plt>
| 400540
| <_start>
| 400550
| <_dl_relocate_static_pie>
| 400580
| <main>
| 400582
| <__libc_csu_init>
| 400610
| <__libc_csu_fini>
| 400680
| <_fini>
| 400684
|
5.7 Hello的动态链接分析
dl_init前PIC函数调用的目标地点都实际指向PLT中的代码逻辑,GOT部门采取了延迟绑定,GOT保存下一下令的地点。dl_init执行后,重定位确定函数地点。
查看hello2.elf文件可以得到GOT的起始位置为0x403ff0。再用edb查看.got的内容。
图49 hello2.elf文件
图50 edb查看.got
5.8 本章小结
本章介绍了链接的概念及作用,演示了在Ubuntu假造机下对hello.o进行链接得到hello的过程,并分析了链接效果。分析效果时用readelf查看了hello的ELF文件,从ELF头、节头部表和步调头部表的角度分别进行了分析,验证了段在假造地点空间的位置。同时也利用objdump查看了hello的反汇编代码,分析了hello的执行流程,并对hello进行了动态链接分析。
第6章 hello历程管理
6.1 历程的概念与作用
概念:历程的经典定义就是一个执行中的步调的实例。系统的每一个步调都是运行在某一个历程上下文中。上下文是由步调正确运行所须要的状态构成的。这个状态包括存放在内存中的步调的代码和数据,它的栈、通用目的寄存器的内容、步调计数器、环境变量以及上下文形貌符的聚集。
作用:利用户得到一种假象,就好像我们的步调是系统当前唯一运行的步调一样,我们的步调好像独占的利用处理器和内存。处理器就好像是无间断地一条一条执行我们步调中的指令,最后我们的代码和数据好像是系统内存中唯一的对象。
6.2 简述壳Shell-bash的作用与处理流程
作用:shell是一个应用步调,是操纵系统中用户与系统内核进行交互的界面。
处理流程:
1终端历程读取用户由键盘输入的下令行;
2分析下令行字符串,获取下令行参数,并构造传递给execve的argv向量;
3检查第一个下令行参数的是否是一个内置的shell下令。如果不是内部下令,调用fork创建新历程或子历程;
4在子历程中用步骤2获取的参数,调用execve()执行指定步调;
5如果用户没要求背景进行,则shell利用waipid等候作业终止后返回;如果用户要求背景运行,则shell返回。
6.3 Hello的fork历程创建过程
在终端中输入下令行,shell判断是否为内置下令。若不是,shell通过fork函数创建一个新的运行的子历程。新的子历程几乎与shell有完全雷同的地点空间,这就意味着当父历程调用fork时,子历程可以读写父历程中打开的任何文件;但又不完全雷同,最大的区别就是它们拥有不同的PID。
6.4 Hello的execve过程
子历程调用exceve函数在当前子历程的上下文加载并运行一个新的步调,此处即hello步调。exceve函数加载并运行可执行目标文件hello,且带参数列表argv和环境变量argc。加载器会删除现有的用户区域;映射私有空间,创建新的代码、数据、堆和栈区域,将代码段和数据段初始化为hello的代码和数据,堆和栈被置空;映射共享区域,实现动态链接;设置PC,将其指向hello步调的起始位置,即从下条指令开始执行hello步调。
6.5 Hello的历程执行
历程上下文:上下文就是内核重新启动一个被抢占的历程所需的状态,上下文切换机制是建立在较低层异常机制之上的。
历程时间片:时间片是指CPU分配给每个步调的运行时间,每个线程被分配一个时间段,作为它的时间片。给不同历程分配不同时间片就可以形成好像多个历程在同时进行的效果。
用户态与核心态:为了能让处理器安全运行,须要限制应用步调可执行指令所能访问的地点范围。因此分别了用户态与核心态。核心态可以说是拥有最高的访问权限,处理器以一个寄存器当做模式位来形貌当前历程的特权。历程只有故障、中断或陷入系统调用时才会得到内核访问权限,其他情况下始终处于用户权限之中,保证了系统的安全性。
系统在执行历程时,会反复横跳,一段时间执行一个步调,每个步调只执行一段时间,系统以时间片轮转调度算法来实现历程之间的调度,这种系统以该方法实现“同时”执行多个步调的过程叫做并发。
6.6 hello的异常与信号处理
可能出现的异常一共有四种,即中断、陷阱、故障、终止。它们的产生原因及处理如下所示。
图51 异常种别、产生原因及处理
发送信号:
(1)不停乱按
图52 不停乱按
可以看到,乱按并未使步调停止运行。实际上,乱按的输入被当成下令存放在缓冲区中。
(2)按回车
图53 按回车
可以看到,输入回车也并未使步调运行收到影响,输入的回车也被加入到了缓冲区,在结束之后被下令行录入。
(3) 按Ctrl+C
图54 按Ctrl+C
可以看到,按下Ctrl+C后步调运行直接停止。接下来利用ps和jobs下令查看。
图55 利用ps和jobs下令查看
可以看到,ps无相应pid,jobs和fg无效果可知,说明hello历程已被结束。
(4) 按Ctrl+Z
图56按Ctrl+Z
图57 利用ps和jobs下令查看
可以看到,在输入Ctrl+Z之后,步调运行停止了,但颠末对ps及jobs的查看可知,该历程时被挂起而未结束,输入fg后继承进行。
(5) kill
图58 kill
可以看到,利用kill可使历程终止。
利用pstree可查看全部指令。
图59 利用pstree查看
6.7本章小结
本章介绍了历程的概念与作用,介绍了 shell 的作用和处理流程,分析了调用 fork 创建新历程、调用 execve加载并执行hello的过程。还以乱按键盘、按回车、按Ctrl+C、按下Ctrl+Z和kill为例,分析了hello的异常与信号处理。
第7章 hello的存储管理
7.1 hello的存储器地点空间
逻辑地点:步调产生的和段相关的偏移地点,由一个标识符加上一个指定段内的相对地点的偏移量构成。
线性地点(假造地点):逻辑地点到物理地点变换之间的中间层。段中的偏移地点加上相应段的基地点就生成了一个线性地点。
物理地点:指出目前CPU外部地点总线上的寻址物理内存的地点信号,用于内存级芯片的单位寻址,是地点变换的最终效果地点。
7.2 Intel逻辑地点到线性地点的变换-段式管理
逻辑地点由[段选择符:偏移量]构成,线性地点由段首地点与逻辑地点中的偏移量构成。此中,段首地点存放在段形貌符中。而段形貌符存放在形貌符表中,也就是GDT(全局形貌符表)或LDT(局部形貌符表)中。
段选择符(16位)由三部门构成。高13位是索引号,可以在形貌符表中找到对应的形貌符;紧接着TI指示段形貌符是在GDT还是LDT中;最低两位表示哀求者特权级别。由此,便可以通过段选择符的指示在段形貌符表中找到对应的段形貌符,然后便可从段形貌符中得到段首地点,将其与逻辑地点中的偏移量相加,就得到了线性地点。
7.3 Hello的线性地点到物理地点的变换-页式管理
系统将假造页作为进行数据传输的单位。假造内存分割被成为假造页,物理内存也被分割为物理页,大小和假造页雷同。恣意时刻假造页都被分为三个不相交的子集:未分配的(VM系统还未分配的页)、缓存的(当前已经缓存在物理内存的已分配页)、未缓存的(当前未缓存在物理内存的已分配页)。
每次将假造地点转换为物理地点,都会查询页表来判断一个假造页是否缓存在DRAM的某个地方,如果不在DRAM的某个地方,通过查询页表条目可以知道假造页在磁盘的位置。页表将假造页映射到物理页。
7.4 TLB与四级页表支持下的VA到PA的变换
将VPN分为多级,在每一级都找到对应的位置。当到达最后一层时会得到 PPN,与 VPO 毗连就得到了最终的物理地点。
图60 TLB与四级页表支持下的VA到PA的变换
7.5 三级Cache支持下的物理内存访问
将已得到的物理地点拆分为CT(标记)、CI(组索引)和CO(块偏移),在L1 Cache中依据组索引,找到对应的组,再依据标记查找是否存在并判断是否有用,最后根据块偏移找到块。如果上述条件均满足则命中,否则按次序对L2 Cache、L3 Cache、内存进行雷同操纵,直到命中,然后向上级返回。如果有空闲块则将目标块放置到空闲块中,否则将缓存中的某个块驱逐,将目标块放到被驱逐块的位置。
图61 三级Cache支持下的物理内存访问
7.6 hello历程fork时的内存映射
当fork 函数被shell调用时,内核为hello历程创建各种数据结构,并分配给它一个唯一的PID 。为了给hello历程创建假造内存,它创建了hello历程的mm_struct 、区域结构和页表的原样副本。它将两个历程中的每个页面都标记为只读,并将两个历程中的每个区域结构都标记为私有的写时复制。当fork 在hello历程中返回时,hello历程如今的假造内存刚好和调用fork 时存在的假造内存雷同。当这两个历程中的任一个后来进行写操纵时,写时复制机制就会创建新页面,因此,也就为每个历程保持了私有地点空间的抽象概念。
7.7 hello历程execve时的内存映射
execve函数在当前历程中加载并运行包罗在可执行目标文件hello中的步调,用hello步调有用地替换了当出息序。加载并运行hello须要:
1删除已存在的用户区域:删除当前历程假造地点的用户部门中的已存在的区域结构。
2映射私有区域:为新步调hello的代码、数据、bss 和栈区域创建新的区域结构。全部这些新的区域都是私有的、写时复制的。代码和数据区域被映射为hello文件中的.text和.data 区。bss 区域是哀求二进制零的,映射到匿名文件,其大小包罗在hello中。栈和堆区域也是哀求二进制零的,初始长度为零。
3映射共享区域:如果hello步调与共享对象(或目标)链接,那么这些对象都是动态链接到这个步调的,然后再映射到用户假造地点空间中的共享区域内。
4设置当前历程上下文中的步调计数器,使之指向代码区域的入口点。下一次调度这个历程时,它将从这个入口点开始执行。
7.8 缺页故障与缺页中断处理
当假造地点在MMU中查找页表时发现对应的物理内存不在主存中,须要操纵系统将其调入主存,这称为缺页故障。
1哀求调页: 当历程调用malloc()之类的函数调用时,并未实际上分配物理内存,而是仅仅分配了一段线性地点空间,在实际访问该页框时才分配物理页框,这样可以节流物理内存的开销。在内存回收时,该物理页面的内容被写到了磁盘上,被系统回收了,这时间须要再分配页框,并且读取其保存的内容。
2写时复制:当fork一个历程时,子历程并未完整复制父历程的地点空间,而是共享相关的资源,父历程的页表被设为只读的,当子历程进行写操纵时,会触发缺页异常,从而为子历程分配页框。
3地点范围外的错误:内核访问无效地点、用户态历程访问无效地点等。
4内核访问非连续性地点:用于内核的高端内存映射,高端内存映射仅仅修改了主内核页表的内容,当历程访问内核态时须要将该部门的页表内容复制到自己的历程页表内里。
5缺页中断处理:缺页处理步调是系统内核中的代码,选择一个捐躯页面,如果这个捐躯页面被修改过,那么就将它互换出去,换入新的页面并更新页表。当缺 页处理步调返回时,CPU重新启动引起缺页的指令,这条指令再次发送VA到 MMU,这次MMU就能正常翻译VA了。
7.9本章小结
本章介绍了存储器地点空间的概念,以及用段式管理和页式管理实现线性地点到物理地点的变换。同时,分析了TLB与四级页表支持下的VA到PA的变换、三级cache支持下的物理内存访问、fork和execve函数的内存映射、缺页故障和缺页中断处理。
结论
Hello的一生有如下过程:
1预处理:将hello.c外部库拓展到hello.i中;
2编译:根据hello.i文件进行编译形成汇编文件hello.s;
3汇编:颠末汇编将汇编语言转化为机器语言存在二进制文件hello.o中;
4链接:将库中函数以某种方式合在hello.o中形成可执行目标文件;
5fork:调用fork创建历程;
6execve:调用execev进行加载;
7执行CPU为其分配资源;
8结束:子历程被父历程回收,资源空间被回收。
附件
文件名
| 作用
| hello.c
| 源文件
| hello.i
| 预处理后文件
| hello.s
| 编译后文件
| hello.o
| 可重定位目标文件
| hello
| 可执行目标文件
| hello.elf
| hello.o的elf文件
| hello2.elf
| hello的elf文件
| hello.fan
| hello.o反汇编得到文件
| hello2.fan
| hello反汇编得到文件
|
参考文献
[1] 辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[2] KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
[3] 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.
[4] 兰德尔E.布莱恩特等. 深入明白盘算机系统. 北京:机械工业出版社,2016:1-640.
[5] 步调头 - 链接步调和库指南 (oracle.com)
[6] 用Ubuntu编写第一个C步调并预处理、编译、汇编、链接_北岛寒沫的博客-CSDN博客_ubuntu创建c语言文件
[7] https://baike.baidu.com/item/%E7%BC%96%E8%AF%91/1258343
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |