计算机系统
大作业
题 目 程序人生-Hello’s P2P
专 业 数据科学与大数据技术
学 号 L20L021702
班 级 2003009
学 生 金珉均
指 导 教 师 郑贵滨
计算机科学与技术学院
2021年5月
摘 要
hello程序在Linux系统的生命周期中,研究hello程序从hello.c经过预处理、编译、汇编、链接,生成可执行文件的全过程。另外,结合教科书知识,详细说明我们的计算机系统如何执行程序管理、存储管理、I/O管理,通过对hello生命周期的探索,让用户更深入地了解计算机系统。
关键词:hello程序;预处理;IO管理;存储管理;链接;虚拟内存;进程管理;
(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
目 录
2.2在Ubuntu下预处理的命令.......................................................................... - 5 -
3.2 在Ubuntu下编译的命令............................................................................. - 6 -
4.2 在Ubuntu下汇编的命令............................................................................. - 7 -
5.2 在Ubuntu下链接的命令............................................................................. - 8 -
5.3 可执行目标文件hello的格式.................................................................... - 8 -
6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -
6.3 Hello的fork进程创建过程..................................................................... - 10 -
6.6 hello的异常与信号处理............................................................................ - 10 -
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 -
8.1 Linux的IO设备管理方法.......................................................................... - 13 -
8.2 简述Unix IO接口及其函数....................................................................... - 13 -
第1章 概述
1.1 Hello简介
P2P (from program to process)
Hello.c是经过cpp的前处理过程,ccl的编译器、as的汇编程序、ld的链接最终成为可执行的目标的Hello,在shell输入开始命令后,shell通过fork生成子处理器,hello从program转变为process。
020( from zero to zero)
shell 为该子进程 execve 映射虚拟内存, 进入程序入口后, 程序开始装入物理内存, 然后进入main函数执行目标代码, CPU 为运行 hello 分配时隙以执行逻辑控制流。程序运行后, shell 父进程将回收 hello 进程, 内核将删除相关数据结构。
1.2 环境与工具
OS: Window 10, Ubuntu 20.04.4 LTS
硬件环境:Intel® Core™ i7-7700HQ; 2.80GHz; 16G RAM;
软件环境:Visual studio 2019, Ubuntu 2004.4.4.0(Canonical Group Limited)
开发与调试工具:gcc,vim,edb,readelf,HexEdit
1.3 中间结果
hello.c : hello的原本文件
hello.i : hello.c预处理之后文本文件
hello.s : hello.i编译后的汇编文件
hello.o : hello.s汇编之后的可重定位目标文件
hello : 链接之后的可执行目标文件
hello.out : hello反汇编之后的可重定位文件
1.4 本章小结
本章简要介绍了hello的p2p, 020过程, 提示了此次实验的信息, 大致介绍了
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
预处理 :编译前对原始程序进行简单处理的编译器的一部分.
- 不过是文本操作,对语法和意义几乎没有考虑
预处理的主要作用
- 删除注释
. 删除原始程序中的注释, 以免编译时翻译
- 宏观(Macro) 置换/扩展
. 简单宏:将符号置换为定义常数(数值、字符串等)
.. 优点:程序可读性增大、常数变更容易等
. 函数宏: 宏像函数一样具有参数
.. 优点:无需函数调用步骤即可提高运行速度
.. 缺点:源代码长度变长
- 编译前将特定句子转换为其它句子
- 合并/ 包含特定文件的内容
- 有条件的编译
- 保存当前编译状态下的各种信息等
2.2在Ubuntu下预处理的命令
命令 :gcc -E hello.c -o hello.i
2.2 命令 gcc -E hello.c -o hello.i i
2.3 Hello的预处理结果解析
2.3 hello.i
将 c 文件编译成 gcc 编译器时,将进入预处理阶段,结果将生成 i 文件。
此步骤包含头文件并扩展宏文件 。 本章说明了预处理的概念和作用,并通过指令制作了预处理阶段结果hello.i文件。
2.4 本章小结
本章说明了预处理的概念和作用,并通过指令制作了预处理阶段结果hello.i文件。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
概念
编译是指将用人类可以理解的语言制作的源代码转换成机械语的工作。
作用
我们用C写的源代码是电脑无法理解的。 因为电脑只能理解由0、1组成的机器语言。 因此,为了能让电脑理解我们制作的源代码,需要翻译成由0、1组成的机械语的编译过程。
源代码通过编译成为由机器语言组成的执行文件。 运行该文件时,可执行文件内容通过操作系统的Loader装载到存储器中,程序会启动。
3.2 在Ubuntu下编译的命令
命令:gcc -S hello.i -o hello.s
3.2 命令:gcc -S hello.i -o hello.s
3.3 Hello的编译结果解析
3.3.1 hello.s
.file : 确定是数据类型还是函数类型
.string : 一个字符串
.rodata:只读代码
=>
3.3.2 main
初始化:
3.3.3 byte
这意味着"将数据从SOURCE转移到DEST" 在movq中,q是quadword的缩写,意思是要转移8byte。
movq:八个字节
movl:四个字节
printf() :
3.3.4 printf
sleep() :
3.3.5 sleep
getchar() :
3.3.6 getchar
3.4 本章小结
本章介绍了编译的概念与作用, 通过命令获得编译的结果,并对其进行了解释。
(第3章2分)
第4章 汇编
4.1 汇编的概念与作用
机器语用另一种语言称为指令(Machine Instruction),指令是由0101010等二进制数组成的数字,每个CPU种类都具有固有的内容。
汇编语言是将这种指令编码成使人能够理解的,与CPU指令(机械语)进行一对一的匹配。
作用
4.2 在Ubuntu下汇编的命令
命令:gcc hello.s -c -o hello.o
4.2 gcc hello.s -c -o hello.o
4.3 可重定位目标elf格式
命令:readelf -h hello.o
4.3.1 readelf -h hello.o
命令 : readelf -S hello.o
4.3.2 readelf -S hello.o
4.4 Hello.o的结果解析
命令:objdump -d -r hello.o
4.4 objdump -d -r hello.o
4.5 本章小结
本章对汇编的概念进行了了解,以hello.s为汇编,生成hello.o重新定位对象文件,分析重新定位对象文件的ELF头、节点、符号列表和可重定位节点,比较hello.s和hello.o逆集合代码的差异,分析从汇编到机械语的每一个的映射关系。(第4章1分)
第5章 链接
5.1 链接的概念与作用
如果我们通过C语言编写程序,则称为Source程序。然后在Compiler对此进行Compile后,生成Object(目的)文件。 编译器不仅负责将源代码翻译成机械语,还负责检查源代码的语法错误。 因此,如果程序是为了发生语法错误而制作的,那么就不能正常编译,就会输出错误。 编译器生成的obj文件与库(Library)连接,生成执行文件(exe)。 这种过程被称为链接(Link)。 另外,执行链接的程序称为链接(Linker)。
5.2 在Ubuntu下链接的命令
命令:
ld -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 -o hello
5.2 ld -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 -o hello
5.3 可执行目标文件hello的格式
命令:readelf -a hello > helloElf.elf
5.3.1 readelf -a hello > helloElf.elf
5.3.2 helloElf.elf
5.4 hello的虚拟地址空间
使用 edb 加载 hello 来查看此进程的虚拟地址空间中的每个段落信息。
5.5 链接的重定位过程分析
命令:objdump -d -r hello > hello.txt
5.6 hello的执行流程
ld-2.27.so!_dl_start
ld-2.27.so!_dl_init
hello!_start
ld-2.27.so!_libc_start_main
_cxa_atexit
_libc_csu_init
_setjmp
_sigsetjmp
_sigjmp_save
main
sleep
getchar
_dl_runtime_resolve_xsave
_dl_fixup
_uflow
exit
————————————————
5.7 Hello的动态链接分析
(以下格式自行编排,编辑时删除)
分析hello程序的动态链接项目,通过edb调试,分析在dl_init前后,这些项目的内容变化。要截图标识说明。
5.8 本章小结
本章说明了链接的概念和作用,并通过指令制作了链接阶段结果hello文件。 对hello进行分析
(第5章1分)
第6章 hello进程管理
6.1 进程的概念与作用
进程的经典定义是正在运行的进程实例。系统的每个程序在某一进程的上下文中运行。上下文由程序正确运转所必需的状态构成。此状态是存储在存储器中的程序的代码、数据、栈、通用目的寄存器的内容、程序计数器、环境变量和文件描述符的集合。 角色: 进程在应用程序中提供的核心抽象分为两种类型。 专门使用逻辑控制流、程序专用处理器、个人地址空间、系统存储器的虚拟系统。
6.2 简述壳Shell-bash的作用与处理流程
Shell起到连接内核和用户之间的作用。另外,Shell是一个指令处理器(Command Processor)。因此,从用户那里输入指令,处理相应指令。
6.3 Hello的fork进程创建过程
常规系统调用只需调用一次即可返回一次 。 但是, fork() 会调用两次。 一次是父进程, 另一个是子进程 。 互不干涉。 呼叫的优先顺序由操作系统的调度算法决定。子进程返回 0, 父进程返回子进程的 ID 。
6.4 Hello的execve过程
execve 函数载入并运行可执行的目标文件 filename , 并导入参数列表 argv 和环境变量列表 envp 。发生错误时, 例如, execve 仅在找不到 filename 时返回调用程序 。因此,与fork一次两次再次呼叫不同,execve一次呼叫后不会再次呼叫。
6.5 Hello的进程执行
逻辑控制流: 当调试器逐级运行应用程序时, 会发现一系列应用程序计数器( PC) 值, 该值相当于应用程序可执行对象文件中包含的指令或正在运行的应用程序共享对象中包含的指令 。该PC的值序列称为逻辑控制流。 并行电流:一个逻辑流的执行在时间上与另一个流重叠。 这被称为并联电流。多个流并发地执行的一般现象称为并发。一个程序和另一个程序轮流启动的概念叫做多任务处理。一个过程执行其控制流的一部分的每个时间段称为时间切片。因此,多任务处理也被称为时间切片。 用户模式:处理器通过某个控制寄存器中的一个模式位,提供一个应用程序可以执行的指令和限制访问的地址空间范围的功能。当未设置模式位时, 进程将在用户模式下运行 。用户模式的流程不允许特权指令和执行,也不允许用户模式的流程直接引用地址空间内的内核区域内的代码和数据。 内核模式: 设置模式位后, 进程将以内核模式运行 。运行内核模式的进程允许您执行命令集的所有命令, 并访问系统内存位置 。 上下文: 重新启动内核已抢占的进程所需的状态 。有多种对象构成,包括公共目的寄存器、浮动点寄存器、程序计数器、用户栈、状态寄存器、内核栈、说明地址空间的页面表、包含当前进程信息的进程表、包含进程打开的文件信息的文件表等。 上下文切换: 内核允许每个进程只保留一个上下文 。 内核重新启动所需的进程 。包括通用目的寄存器、浮动点寄存器、程序计数器、用户站、状态寄存器、内核堆栈及各种内核数据结构。 调度器: 内核将抢占当前进程并重新启动先前抢占的进程 。。
6.6 hello的异常与信号处理
hello 运行过程中发生的异常类型可能会有中断、陷阱、故障、终止等。 中断:异步产生是来自处理器外部I / O设备的信号的结果。硬件中断的非正常处理程序被称为中断处理程序。 陷阱: 超出预期, 命令执行的结果。就像中断处理程序一样,陷阱处理程序将控制装置返回到下一个命令。舰艇最重要的用途是在用户程序和内核之间提供程序等接口。 故障: 故障可能由故障处理程序修改 。当发生故障时,处理器将控制设备转移至故障处理程序。如果处理器可以修改该错误,则控制它返回引起故障的指令并重新运行。否则, 当处理器返回内核中的 abort 例程时, abort 例程将关闭发生故障的程序。 退出: 无法修复的致命错误 。 例如,发生DRAM或SRAM位损坏时发生的奇偶校验错误等硬件错误。终止处理程序绝对不是控制返回应用程序。进程返回正在运行的 abort 例程 。 例程将退出此例程 。 信号允许中断进程和内核不同的进程。每个信号对应于某个系统事件。下层硬件异常由内核异常处理程序处理。 在正常情况下,无法看到用户流程。信号提供了一种通知用户过程发生这种异常的机制。
输入运行过程 Ctrl-C: 停止进程 。
执行过程输入 Ctrl-Z: 内核将 SIGSTP 发送到 hello, 将 SIGCHLD 发送到父进程中, 输入 ps 后, hello 停止, fg 命令将重新启动 hello 并输出剩余部分。
输入 Ctrl-Z 后运行 kill : shell 父进程接收 SIGSTP 信号并打印信号处理程序以终止 hello 进程。
6.7本章小结
本章分析fork和execve函数的执行过程和进行动作,并了解程序执行时异常和信号的处理及上下文转换的信息。
(第6章1分)
第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址: 逻辑地址空间中的另一段地址和偏移地址构成。 以段落描述符为下表, 在 GDT 中查找段落地址、 段落地址 + 偏移地址 = 线性地址。存取指令给出的地址是逻辑地址。 线性地址:线性地址是从逻辑地址到物理地址的中间量。在短路地址加上偏移地址就成为线性地址。 虚拟地址: 使用虚拟地址访问主机时使用的虚拟地址是虚拟地址, 此虚拟地址将在访问主机之前转换为物理地址 。 物理地址: 主存储区是一个字节组成的集合 。 这个集合在每个字节都有一个地址。 这个地址叫做物理地址。
7.2 Intel逻辑地址到线性地址的变换-段式管理
逻辑地址由分段选择者和偏移量组成,线性地址是分段地址和逻辑地址的偏移量之和。段落地址存储在段落描述符中。段落描述符存储在描述符表中, 即 GDT( 全局描述符) 。段落标识符是 16 位长字段之一, 称为段落标识符, 第一个 13 是索引号.
7.3 Hello的线性地址到物理地址的变换-页式管理
线性地址视为VPN(虚拟页码)和VPN(虚拟页码),物理地址由PPN和PPO组成,其中VPN和PPO可以直接转换,VPN必须使用MMU在页面上找到PPN,MMU利用VPN找到页面的相应PTE(页面项目),然后获得PPN,组合VPN(即PPO)和物理地址。线性地址被分类为以固定长度为单位进行效率和管理的小组,称为页面。
7.4 TLB与四级页表支持下的VA到PA的变换
Core i7 MMU使用4个阶段的页面,将虚拟地址翻译成物理地址。36位VPN分为4个9位VPN,分别用于页面的移动量。
7.5 三级Cache支持下的物理内存访问
接收物理地址,发送LI缓存请求数据,如果找不到,在L2缓存中寻找,如果找不到,在L3缓存中寻找,如果还是找不到,在家庭缓存中寻找。这样,TLB和缓存组合完成,可以获得存储器中的数据字。
7.6 hello进程fork时的内存映射
当 fork 函数调用进程时, 内核将在新进程中创建各种数据结构, 并将其分配给他唯一的 PID 。创建当前进程的 mm_struct、 区域结构和页面的原始副本, 以在此进程中创建虚拟内存 。将新进程的所有页面都显示为只读, 当您将两个进程的所有区域显示为个人时复制它
7.7 hello进程execve时的内存映射
execve 删除已存在的用户区域, 删除当前进程中虚拟地址的用户部分中存在的结构 。 映射私有区域, 并创建新应用程序的代码、 数据、 bss 和堆栈区域的新区域结构 。 所有这些区域都是私人的, 会在写入时复制 。 其中, bss 部分映射可执行文件、 堆栈和堆栈初始长度 0、 共享区域, 并将动态链接部分映射到共享区域。 设定程序计数器 。 最后一件事是设置当前进程上下文中的程序计数器指向代码区域的入口点 。
7.8 缺页故障与缺页中断处理
DRAM缓存被称为结肠,呼叫结肠障碍处理程序。 物理内存决定牺牲页面 。 如果页面已修改, 则替换为磁盘, 然后将新页面载入物理内存 。 之后如果再次执行结肠障碍的命令,这次就不会结肠。
7.9动态存储分配管理
动态存储器分配器维持程序的虚拟存储器领域,称为堆栈。分配器将堆栈视为不同大小的块的集合进行维护。每个块都是一个连续的虚拟内存。 已分配或空闲 。分发的积木显著保留,供应用程序使用。富余块可以分配。空块保持空闲,直到当前由应用程序分配为止。保持已分配块的发放状态, 直至释放 。 这些释放被隐藏在您的应用程序正在运行或内存分配器中。 分配器有两种基本风格,要求显著分配块,不同之处在于分配块的释放由哪个实体负责。 显式分配器: 要求显式地释放所有已分配的块。 隐形分配器: 当您请求检测分配给分配器的块何时不再被使用时, 释放该块并自动释放未使用的块称为垃圾收集 。自动释放未使用的分配块的过程被称为垃圾收集。
7.10本章小结
本章讨论了地址空间和地址的管理方式、TLB和3段缓存、多段页面表协同作业的存储器管理机制、以及缺失的页面障碍的处理,同时对动态存储器分配方法进行了分析。
(第7章 2分)
第8章 hello的IO管理
8.1 Linux的IO设备管理方法
(以下格式自行编排,编辑时删除)
设备的模型化:文件
设备管理:unix io接口
8.2 简述Unix IO接口及其函数
(以下格式自行编排,编辑时删除)
8.3 printf的实现分析
(以下格式自行编排,编辑时删除)
[转]printf 函数实现的深入剖析 - Pianistx - 博客园
从vsprintf生成显示信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等.
字符显示驱动子程序:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析
(以下格式自行编排,编辑时删除)
异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结
(以下格式自行编排,编辑时删除)
(第8章1分)
结论
hello.c经过前处理生成前处理文件hello.i,hello.i通过编译器生成汇编代码文件hello.s,hello.s翻译成机械命令,存储在重新定位文件hello.o中,hello.o通过链接解析符号及重新定位生成执行对象文件hello,输入命令语后执行hello,conalder调用hello,hello.o.o,hec,hello,hec,hec,hec,hec,hello。Rest In Peace 헤 Hello执行的功能虽然很简单,但是分析从头到尾Hello的生成、执行过程的话,电脑设计的精巧性、各部分的协同启动、硬件和软件的完美结合、cpu、各级cache、主存储器的协同启动等都体现了电脑底层设计的精巧性。作为程序员,理解计算机系统的底层操作机制非常重要,以后在底层写友好的代码准备比较方便。
(结论0分,缺失 -1分,根据内容酌情加分)
附件
列出所有的中间产物的文件名,并予以说明起作用。
hello.i:预处理后的文件;
hello.s:汇编语言文件;
hello.o: 链接之后的可执行目标文件;
helloElf.elf:hello.o的elf信息;
(附件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分)