.摘 要

本文简要分析了hello这一程序从“出生”到“成人”的过程,并介绍了相应的计算机系统组成成分在其中扮演的角色。主要包括预处理,编译,汇编,链接,进程管理,存储管理,I/O管理几个部分。

关键词:hello,预处理,编译,汇编,链接,进程管理,存储管理,I/O管理;

(摘要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简介
P2P是指from program to process,对原程序进行包括预处理(.c文件 -> .i文件),汇编(.i文件 ->
.s文件),链接(.s文件 -> .o文件)的一系列操作后,形成可执行文件。执行该文件时,OS为该文件fork产生进程(process)。
020是指from zero to
zero。程序开始执行后,OS为其映射到虚拟内存,执行目标代码,然后mmap分配时间片,最终在硬件上实现。实现后由内核使内存等恢复到程序执行前的状态,即020。
1.2 环境与工具
硬件:Intel®Core™ i5-7200U CPU @ 2.50GHz (4 CPUs), ~2.7GHz
软件:Ubuntu18.04.1 LTS
开发和调试工具:gcc, gdb, as, ld, readelf等
1.3 中间结果
Hello.c: 源文件
Hello.i: 预处理输出文件
Hello.s: 编译输出文件
Hello.o:汇编输出文件
Hello:链接输出文件
1.4 本章小结
本章简要介绍了文章的创作环境,以及过程文件。
(第1章0.5分)

第2章 预处理
2.1 预处理的概念与作用
概念:在编译之前进行的处理
作用: 1·宏替换,将宏名替换为文本。
2·加载头文件
3·处理条件编译
2.2在Ubuntu下预处理的命令

如图。
2.3 Hello的预处理结果解析
hello.i打开截图如下(节选)


可以看到,原来仅三十行左右的代码扩展到了三千多行。其中main函数部分没有发生变化,而头文件部分展开,宏定义也被处理。若文件包含中存在嵌套关系,cpp会逐层展开,这样hello.i就可以直接被译为.s文件。
2.4 本章小结
本章主要介绍了预处理的概念和作用,并以hello作为例子简要的分析预处理的过程以及得到的结果。

(第2章0.5分)

第3章 编译
3.1 编译的概念与作用
概念:将程序员所撰写的编程语言翻译成汇编语言的过程。
作用:通过语法检验,代码优化等过程,将程序员便于记忆和认知的编程语言转化为机器可识别的语言。
注意:这儿的编译是指从 .i 到 .s 即预处理后的文件到生成汇编语言程序

3.2 在Ubuntu下编译的命令
gcc -S -v hello.c -o hello.s (其中-v选项作用是查看过程信息,可去)

3.3 Hello的编译结果解析
3.3.1 int sleepsecs=2.5;(全局变量)(类型转换)
对应汇编如图:

其中,“.”是伪指令的标识符,long(quad)以及后面数字的大概范围的不同,对应了c语言中不同的数据类型(例如int对应long,long和long
long对应quad,double对应两个long等)。后面的数字是变量的值,由于类型是int,编译器把2.5转化成了2;section对应所在的节;align是对齐信息。
3.3.2控制转移
(1)if(argc!=3)

等于3时跳转,略过条件语句内的部分。

(2)for(i=0;i<10;i++)-----i<10部分

这段代码接在循环语句之后,若符合循环条件,则跳回循环部分.L4。
3.3.3 函数调用
(1)printf(“Usage: Hello 学号 姓名!\n”);

先将要输出的格式(以字符串的形式)调到本节中。

用偏移量得到字符串地址,传参,调用函数。
(2)printf(“Hello %s %s\n”,argv[1],argv[2]);

基本同上。
(3)sleep(sleepsecs);

利用偏移量得到地址,传参(sleepsecs),调用,基本同上。
(4)getchar();

直接调用,如上。
(5)exit(1);

传参调用,参数是返回状态值。
3.3.4数组操作
printf(“Hello %s %s\n”,argv[1],argv[2]);(数组部分)
将第三个参数argv[2]存在%rdx中(第一个参数是格式字符串)。
接上图,第二个参数argv[1]存在%rsi中。
即汇编中用首地址加偏移量的方式表示数组。

3.4 本章小结
本章简要地介绍了编译的概念和作用,并以hello文件作为例子,对编译的过程和结果进行了详细的解析。
(第3章2分)

第4章 汇编
4.1 汇编的概念与作用
概念:把汇编语言翻译成机器语言的过程,亦称为符号语言。
作用:汇编语言的诞生是由于机器代码难以记忆,所以用助记符代替操作码形成的方便记忆的语言,这种机器不能直接识别。用程序将其翻译为机器语言后,才可以被识别运行。
注意:这儿的汇编是指从 .s 到 .o 即编译后的文件到生成机器语言二进制程序的过程。
4.2 在Ubuntu下汇编的命令

如图。
4.3 可重定位目标elf格式
readelf -a hello.o得到如下结果:

可以看到ELF文件中的架构:ELF头,节头,程序头,包括重定位节在内的各种节的信息,以及符号表。
节头中存有节的基本信息,包括序号,名称,大小,类型,偏移量等信息。
命令“readelf -S 文件名”可单独查看节头。

重定位节.rela.text中包含.text节的重定位信息,在链接时程序将通过这些信息和代码提供的偏移找到正确的需要调用的函数地址。本程序中,需要重定位的包括.rodata节中的两个数据,全局变量sleepsecs,
函数puts, exit, printf, sleep, getchar。
4.4 Hello.o的结果解析
键入objdump -d -r hello.o指令得到结果如下:
对比hello.s如下图:
通过对比可以发现,两者汇编代码有一些不同,而这些就是汇编过程实现的操作:
1·.o文件中每条语句都有了一个偏移量,便于跳转寻址。

2·去掉了面向程序员的助记符,跳转/调用指令后的函数名/助记符替换为了相对偏移地址。由于尚未进行链接,无法确定函数地址,所以偏移暂时为零。同时,在重定位节中添加相应条目。
3·为全局变量提供偏移量寻址。由于尚未进行链接,无法确定具体地址,所以偏移暂时为零。同时,添加重定位条目,等待链接。
4.5 本章小结

本章简要介绍了汇编的概念和作用,提供了Ubuntu下汇编的命令。同时,以hello文件为例,分析了ELF文件的格式,并通过对.o文件的反汇编和.s文件的对比分析了汇编过程的实现过程。
(第4章1分)

第5章 链接
5.1 链接的概念与作用
概念:将各种代码和数据片段收集并组合成一个单一文件的过程,这个文件可以被加载到内存中执行。
作用:使分离编译成为可能。我们不用将一个大型的应用程序组织为一个巨大的源文件,而是可以分解为更小,更好管理的模块,可以独立地修改和编译单一模块。
注意:这儿的链接是指从 hello.o 到hello生成过程。
5.2 在Ubuntu下链接的命令

如图。
5.3 可执行目标文件hello的格式
输入readelf -a hello,结果如下:

可以看出,其ELF文件的大概结构仍然为ELF头,节头,程序头,包括重定位节在内的各种节,其中多了一个链接的信息。
5.4 hello的虚拟地址空间
键入命令edb --symbols hello得到结果如下:

5.5 链接的重定位过程分析
键入objdump -d -r hello得到结果如下:

通过本图以及对比节头信息(4.3图 & 5.3图1),可以发现:
1·增加了一些外部函数。
2·增加了包括.init, .plt, .fini在内的一些节。
3·相对偏移地址变为了虚拟内存的地址。

链接时,链接器通过符号表和节头了解到.data和.text在每个文件中的偏移和大小,进行合并,然后为新的合并出来的数据和代码节分配内存,并映射虚拟内存地址。最后修改对各种符号的引用,完成重定位。
5.6 hello的执行流程
Gdb结果如下:

(循环部分,重复printf,sleep,略)

5.7 Hello的动态链接分析
键入readelf -R .interp hello得到结果如下:

5.8 本章小结

本章简要介绍了链接的概念和作用,以及Ubuntu下的链接命令。并以hello文件为例,查看了链接后的文件格式,并对虚拟地址分配,重定位,动态链接等过程进行了分析。
(第5章1分)

第6章 hello进程管理
6.1 进程的概念与作用
概念:操作系统对一个正在运行的程序的一种抽象。

作用:一个程序在系统上运行时,操作系统会提供一种,程序在独占这个系统,包括处理器,主存,I/O设备的假象。处理器看上去在不间断地一条一条执行程序中的指令…这些假象都是通过进程的概念实现的。(摘自《深入理解计算机系统》)
实际应用:查看系统中正在运行的程序;查看系统状态;停止或杀死指定进程。
6.2 简述壳Shell-bash的作用与处理流程
Shell指操作界面,可以接收用户命令并调用相关程序。处理流程如下:
1·读取输入命令并处理得到参数。
2·判断输入命令是内置还是外部命令,内置命令立刻执行,外部命令则调用相关程序。
3·根据后续输入向相应进程发送信号。
4·处理接收到的信号,更新进程状态。
6.3 Hello的fork进程创建过程
Fork函数再进程的当前位置创建一个新进程,新进程具有与原进程完全相同的状态(除PID)。创建过程如下:
1·为新进程复制父进程的堆栈等数据空间。
2·创建新进程。
6.4 Hello的execve过程
Execve函数在当前进程的上下文中加载并运行一个新程序。当读取文件出现错误时,返回原程序,否则不返回。具体步骤如下:
1·根据第一个参数加载文件,通过启动代码对栈进行设置,并完成控制传递。
2·顺序执行,用第二,三个参数调用main函数
6.5 Hello的进程执行

系统执行进程时,内核可以暂停当前进程,并启用其他进程,这个过程称为调度,而这些进程以及它们的PC值所构成的序列就是逻辑控制流。当进程被执行时,内核代码不断地根据上下文信息,时间片等进行判断,并根据其结果转移控制权,完成调度。
P.S. 上下文信息:指内核重新启动一个被抢占的进程所需要的状态,由通用寄存器,浮点寄存器,程序计数器,用户栈,状态寄存器,内核栈等构成。
时间片:一个进程执行它的控制流的每一时间段。(摘自《深入理解计算机系统》)
6.6 hello的异常与信号处理
1·ctrl - c

2·ctrl – z

(1) ps

(2) jobs

(3) pstree(部分)

(4) fg

(5) kill

6.7本章小结
本章简要介绍了进程的概念和作用,以及shell的处理流程。同时以hello文件为例分析了fork,execve,进程执行,以及异常和信号处理的过程。
(第6章1分)

第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址:指由程序产生的与段相关的偏移地址。分为段标识符和段内偏移。
线性地址:到物理地址的过渡。分为目录索引,页索引,页内偏移。
虚拟地址:为更有效地管理内存,并减少不同程序间内存冲突的问题,现代系统提供了一种对主存的抽象概念,称为虚拟内存。
物理地址:在主存中的地址。
7.2 Intel逻辑地址到线性地址的变换-段式管理
1·观察段选择符,0则转换的是GDT(全局)中的段,否则就是LDT(局部)中的段。
2·根据相应寄存器,找到其起始地址。
3·通过段标识符找到对应的基地址。
4·用基地址加上偏移,得到线性地址。
7.3 Hello的线性地址到物理地址的变换-页式管理(以32位为例)
1·根据线性地址前十位找到对应页表的地址。
2·根据线性地址中间十位找到对应页的起始地址。
3·页的起始地址加上线性地址最后十二位,得到物理地址。
7.4 TLB与四级页表支持下的VA到PA的变换
将VA分为四段。依次通过每段地址找到对应的PML4,PGD,PMD,PTE表,找到对应地址,组合得到PA。
7.5 三级Cache支持下的物理内存访问

物理地址分为标记,组索引和块偏移。首先,在L1中匹配组索引位,若匹配成功,则根据标记和偏移的匹配结果决定缺失或是命中。若组索引匹配不成功,则进入下一级cache,重复直至进入内存。
7.6 hello进程fork时的内存映射
Fork会为新进程(子进程)复制一个与父进程完全相同只读数据空间,并为其分配另一片内存和虚拟地址。分配时会将其标记为私有,防止过程中被父进程影响。
7.7 hello进程execve时的内存映射

调用Execve时,系统首先删除了当前进程中用户部分已有的结构,然后映射私有区域(建立新的文件结构,包括.data在内的各种节),共享区域(当前进程的动态链接),并设置PC。
7.8 缺页故障与缺页中断处理
1·段错误:地址不合法,即无法匹配到已有的区域结构中。
2·非法访问:没有应有的读写权限。
3·正常缺页:选择一页进行替换。
7.9动态存储分配管理
分配器有两种风格,显示分配器(要求应用显式地释放任何已分配的块),隐式分配器(要求分配器检测一个已分配块是否仍然需要,不需要则释放)。
分配策略:
1·空闲链表:
(1) 隐式:在每块的头,尾部增加32位存储块大小,以及是否空闲。
(2) 显式:在隐式的基础上在头部增加对前后空闲块的指针。
(3) 分离:同时维护多个空闲链表。
2·带边界标记的合并:
利用每块头尾的大小和空闲状态信息合并空闲块。
3·无合适空闲块时,申请额外的堆空间。
7.10本章小结
本章简要介绍了文件的存储管理,包括各种地址的转换,错误的处理,以及动态存储的分配模式。
(第7章 2分)

第8章 hello的IO管理
8.1 Linux的IO设备管理方法
设备的模型化:文件
1·普通文件(ls -al第一个属性为“-”)
2·目录文件(ls -al第一个属性为“d”)
3·设备文件
设备管理:unix io接口
1·开关文件。
2·读写文件。
3·改变当前文件的位置。
8.2 简述Unix IO接口及其函数
1·open:打开已存在的文件或建立新文件。
2·close:关闭已打开的文件,会返回结果状态。
3·ssize_tread:在文件的指定位置赋值。
8.3 printf的实现分析
Vsprintf:接受一个格式化的命令,并把制定的匹配的参数格式化输出。
Write:把字符串中n个元素的值写到终端(n为第二个参数)
系统调用:显示格式化的字符串。
8.4 getchar的实现分析
异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结
本章简要介绍了hello文件的I/O管理,包括设备管理方法,接口函数,以及读写函数的实现分析。
(第8章1分)
结论

Hello从原程序.c文件经过预处理,编译,汇编,链接得到了可执行文件。执行时,通过os对命令的处理结果,hello被分配到了自己的存储空间,虚拟内存地址和时间片。过程中,I/O不断接受信号并对其进行处理。运行结束后,内核清除已分配的数据空间,还原系统状态。
(结论0分,缺失 -1分,根据内容酌情加分)

附件
Hello.c: 源文件
Hello.i: 预处理输出文件
Hello.s: 编译输出文件
Hello.o:汇编输出文件
Hello:链接输出文件
(附件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)
<http://www.ie.nthu.edu.tw/info/ie.newie.htm%EF%BC%88Big5%EF%BC%89>.
[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/
<http://www.sciencemag.org/cgi/> collection/anatmorp.
(参考文献0分,缺失 -1分)

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信