计算机系统大作业

计算机系统

大作业

题     目  程序人生-Hellos P2P  

专       业   计算机科学与技术                     

学     号    8200880103                    

班   级    2036012                    

学       生    易明炜              

指 导 教 师     刘宏伟                

计算机科学与技术学院

2022年5月

摘  要

本篇报告以hello.c程序的一生为例,对计算机系统所学的知识进行了整理、复习和重温,在Ubuntu虚拟机下分析hello的一生。重点分析了hello.c转化为可执行文件前所经历的四个阶段——预处理阶段、编译阶段、汇编阶段、链接阶段,并对进程管理进行了深入的分析。

关键词:预处理 编译 汇编 链接 进程管理                            

(摘要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简介

根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。

Hello的P2P过程

在visiual stdio中输入C语言代码生成hello.c源程序,经历预处理阶段生成hello.i文件,经历编译阶段翻译成hello.o汇编语言程序,经历汇编阶段翻译成机器语言指令,生成可重定位目标程序,经历链接阶段生成可执行文件。在shell中启动后,调用fork函数生成子进程。hello由program转化为process.

Hello 的020过程

在shell中,通过execve为进程映射虚拟内存,进入程序入口后,程序开始载入物理内存,接着执行main函数执行目标代码,CPU为正在运行中的Hello分配时间片执行逻辑控制流。当程序结束后,shell父进程回收Hello子进程,最后内核删除有关数据结构。

1.2 环境与工具

列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。

硬件环境:处理器 AMD Ryzen 7 4800H with Radeon Graphics,2900 Mhz,8 个内核,16 个逻辑处理器,16G RAM ,476.92GB SSD

软件环境:Window 64位 Ubuntu-20.04.4 64位, VirtualBox 6.1

Visual Studio 2019 64位;CodeBlocks 20.03 64位:

开发调试工具:vi/vim/gedit+gcc/edb

1.3 中间结果

列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。

Hello.c

源程序

Hello.i

Hello.c预处理生成hello.i文件

Hello.s

Hello.i编译生成hello.s汇编文件

Hello.o

Hello.s汇编后生成的可重定位目标文件

Hello.ld

Hello.o链接后生成的可执行文件

elf.txt

Hello.o的elf格式文件

Elf_hello.txt

Hello.ld的elf格式文件

1.4 本章小结

通过本章学习,我对Hello的P2P、020过程内容有了了解,也对整个实验中用到的中间文件进行了总结。

(第1章0.5分)


第2章 预处理

2.1 预处理的概念与作用

以下格式自行编排,编辑时删除

预处理概念

预处理一般是指在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的第一个过程。预处理器(cpp)根据字符#开头的命令,修改原始C程序,得到另一个C程序,通常以.i作为文件扩展名。

预处理作用

在预处理阶段,计算机使用预处理器对原始C程序进行修改。预处理指令包括条件编译、文件包含、宏替换、行控制、抛错、杂注和空指令。

(1)条件编译

预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中的指定部分包含或是排除在外,排除一般是将指定代码转换为空行。

(2)宏替换

2种替换:1.用实际值替换被#define定义的字符串 2.读取系统头文件内容,将其直接插入程序文本中。

(3)行控制

以#line为开头,后接行号和可选字符串,用于改变宏“__LINE__”的值。

(4)抛错

以“#”或“error”为开头,用于在预处理阶段发出停止诊断的信息。

(5)杂注

向C实现传递额外信息,或是消除注释。

2.2在Ubuntu下预处理的命令

图1 Ubuntu下预处理的命令

图2  hello.i文件内容

图3  hello.i文件内容

2.3 Hello的预处理结果解析

经过预处理阶段,计算机用预处理器将hello.c翻译为hello.i文件,打开hello.i,代码从原先的23行变为3060行,代码仍用C语言编写,main函数仍可读。Hello.c中的宏被替换插入了指定的系统头文件内容。

2.4 本章小结

通过本章练习,我对计算机预处理阶段有了具体的认识,对hello.c转化成hello.i文件时所经历的宏替换有了更深的了解。

(第2章0.5分)


第3章 编译

3.1 编译的概念与作用

注意:这儿的编译是指从 .i 到 .s 即预处理后的文件到生成汇编语言程序

编译的概念

1.用编译器(ccl)从源语言编写的源程序生成目标汇编语言程序的过程,如编译器将hello.i翻译成hello.s,其包含一个汇编语言程序。

2.用编译器产生目标程序的动作

编译作用

将高级语言程序翻译为汇编语言代码,为不同高级语言的不同编译器提供了通用的输出语句。      

3.2 在Ubuntu下编译的命令

图4 Ubuntu下编译的命令

图5 hello.s内容

图6  hello.s内容

3.3 Hello的编译结果解析

3.3.1数据

1.常量

图7 汇编语言的常量

上面两个字符串被存储在.rodata节中

2.变量

(1)全局变量

图8 汇编语言的全局变量

全局变量main存储在.type节中

(2)局部变量

图9 汇编语言的局部变量

局部变量1被存储在%edi寄存器中

3.3.2赋值操作

图10 汇编语言的赋值操作

%edi位置赋予1的值。

3.3.3算数操作

图11 汇编语言的加法操作

%rax=%rax+16

3.3.4控制转移

图12 汇编语言的控制转移操作

7和-4(%rbq)中存储的值比较,若-4(%rbq)中存储的值小于等于7则跳转

3.3.5数组操作

图12 汇编语言的数组循环操作

Hello.c中for循环用到了argv[]数组,编译结果如上

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

3.4 本章小结

通过本章学习,我对编译阶段有了具体的认识,对汇编语言指令有了更为深入 的了解。

(第3章2分)


第4章 汇编

4.1 汇编的概念与作用

以下格式自行编排,编辑时删除

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

汇编概念

汇编器将hello.s翻译为机器语言指令,将这些指令打包成可重定位目标程序,并将结果保存在目标文件。

汇编作用

1.将文本文件hello.s翻译成文本文件hello.o

4.2 在Ubuntu下汇编的命令

应截图,展示汇编过程!

图13 Ubuntu下汇编的命令

4.3 可重定位目标elf格式

图14 典型ELF可重定位目标文件格式

由上述典型的ELF可重定位目标文件格式分析elf.txt

    1.ELF头以一个16字节的序列开始,该序列描述了生成该文件的系统的字的大小和字节顺序。ELF头剩下的部分包含了帮助链接器语法分析和解释目标文件的信息,其中包括ELF头的大小、目标文件的类型(如可重定位、可执行或者共享的)、机器类型(如x86-64)、节头部表(section header table)的文件偏移,以及节头部表中条目的大小和数量。不同节的位置和大小是有节头部表描述的,其中目标文件中每个节都有一个固定大小的条目(entry)。

图15 ELF头

2.节头表

由表知有13个节

    

图16 节头表

3.符号表

   一个符号表,它存放在程序定义和引用的函数和全局变量的信息。不包含局部变量的数目。

图17 符号表

每个节由0起始,只可读不可写。

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

4.4 Hello.o的结果解析

以下格式自行编排,编辑时删除

objdump -d -r hello.o  分析hello.o的反汇编,并请与第3章的 hello.s进行对照分析。

图18 hello.o 反汇编指令

图19 hello.o 反汇编结果


图20 hello.o 反汇编结果

将hello.o的反汇编结果与hello.s进行对比

1.每一行汇编语言左侧多出了一行机器语言指令

2.在hello.o反汇编结果中分支转移函数直接给出了跳转的虚拟地址,而hello.s则是给出了跳转的节(段)名称。

3.hello.s中操作数为10进制,hello.s中操作数为16进制。

4.hello.s调用函数用的是函数名称,hello.o反汇编结果用的是跳转的虚拟地址。

5.访问全局变量时,hello.s使用.LC0(%rip),hello.o反汇编结构用的是0x0(%rip)。

4.5 本章小结

通过本章学习,我对汇编阶段有了具体的认识,对elf文件格式及其所含信息有了更为深入的了解,并对hello.o反汇编结果与hello.s有了纵向对比。

(第4章1分)


5链接

5.1 链接的概念与作用

以下格式自行编排,编辑时删除

注意:这儿的链接是指从 hello.o 到hello生成过程。

链接概念

链接是指将各种代码和数据片段收集并组合成一个单一文件的过程,这个文件可以被复制到内存并执行。

链接作用

1.链接使得分离编译成为可能。

2.利用链接能帮助构造大型程序

3.利用链接避免一些危险的编程错误

4.利用链接可以利用共享库。

5.2 在Ubuntu下链接的命令

以下格式自行编排,编辑时删除

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

图21 hello.o在Ubuntu下链接的命令

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

分析hello的ELF格式,用readelf等列出其各段的基本信息,包括各段的起始地址,大小等信息。

图22  hello.ld的ELF格式转化指令

5.3.1 ELF头

图23可执行目标文件的ELF格式内容

由图知该可执行由27个节组成

5.3.2 节头部表

图24 节头部表前半段

图24 节头部表后半段

5.3.3符号表

图25 符号表

5.4 hello的虚拟地址空间

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


图26  edb内hello.ld的data dump内容

上图显示

    整个hello.ld程序位于0x0000000000401000-0x0000000000402000段中,而虚拟地址从0x00401000开始,到0x00401ff0结束

    与5.3对比,ELF各节所在位置在5.4中虚拟地址范围内。

5.5 链接的重定位过程分析

objdump -d -r hello 分析hello与hello.o的不同,说明链接的过程。

结合hello.o的重定位项目,分析hello中对其怎么重定位的。

 

 

图27 hello.ld反汇编代码

   Hello.o与hello.ld反汇编代码的不同

1.hello.o中每一节都是由重定位条目作为地址的,hello.ld反汇编代码中调用函数或是跳转直接使用虚拟地址

2.hello.ld的反汇编代码比hello.o多了一些节如<init>、<.plt>

3.hello.ld反汇编代码比hello.o多了如printf@plt、getchar@plt等函数。

5.6 hello的执行流程

以下格式自行编排,编辑时删除

使用edb执行hello,说明从加载hello到_start,到call main,以及程序终止的所有过程。请列出其调用与跳转的各个子程序名或程序地址。

子程序名

程序地址

Hello.ld!_init

0x00401000

Hello.ld!_start

0x004010f0

Hello.ld!_dl_relocate_static_pie

0x00401120

Hello.ld!_main

0x004011125

5.7 Hello的动态链接分析

   (以下格式自行编排,编辑时删除

分析hello程序的动态链接项目,通过edb调试,分析在dl_init前后,这些项目的内容变化。要截图标识说明。

在ELF文件中的动态链接项目

图28 ELF文件中的动态链接项目

在edb调试后得到对比图

图29 init运行前的data dump

图30 init运行后的data dump

对比可知,init 运行前跳转地址都为0,运行init函数后,调转地址变为非0值,指向正确目标地址。

5.8 本章小结

通过本章学习,我对链接的概念与作用有了进一步的了解,并对ubuntu下hello.ld的反汇编及其分析有了具体的认识,并对程序的执行过程,动态链接分析等知识点重新巩固。

以下格式自行编排,编辑时删除

(第5章1分)


6hello进程管理

6.1 进程的概念与作用

进程的概念

进程的经典定义就是一个执行中程序的实例。系统中的每个程序都运行在某个进程的上下文中,上下文是由程序正确运行所需的状态组成的,包括存放在程序中的代码和数据,它的栈、通用目的寄存器内容、程序计数器、环境变量以及打开文件描述符的集合。

进程的作用

   1.一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占地使用处理器。

   2.一个私有的地址空间,它提供一个假象,好像我们的程序独占地使用内存系统

6.2 简述壳Shell-bash的作用与处理流程

shell作用

1.Shell是一个交互级的应用级程序,它代表用户运行其他程序。

2.shell能为用户提供操作界面,提供内核服务,解释用户输入的命令。

3.shell可以在多个程序间传递数据,将一个程序的输入作为另一个程序的输出。

shell处理流程

1.从终端读入输入的命令。

2.将输入的字符串切分获得所有参数。

3.如果是内置命令则立即执行,否则调用相应程序执行。

4.shell应该接受键盘输入信号,并对这些信号进行处理。

6.3 Hello的fork进程创建过程

在终端输入命令行后,shell进行切分并处理,如果不是内置命令,则父进程调用fork函数创建一个新的子进程。新的子进程几乎但不完全与父进程相同。子进程得到与父进程用户级虚拟地址空间相同的(但是独立的)一份副本,包括代码和数据段、堆、共享库以及用户栈。子进程还获得与父进程任何打开文件描述符相同的副本,这就意味着子进程可以读写父进程任意打开的文件。两者最大的区别在于它们有不同的PID。

6.4 Hello的execve过程

以下格式自行编排,编辑时删除

execve函数在当前进程的上下文中加载并运行一个新程序。execve函数加载并运行可执行目标文件,且带参数列表argv和环境变量列表envp。只有当出现错误时,例如找不到hello文件,execve才会返回到调用程序。所以与fork一次调用返回两次不同,execve调用一次并从不返回。

execve先等父进程调用fork函数创建一个子进程,然后在子进程中调用一个新的程序。

6.5 Hello的进程执行

以下格式自行编排,编辑时删除

结合进程上下文信息、进程时间片,阐述进程调度的过程,用户态与核心态转换等等。

1.逻辑控制流

进程的运行实质是CPU从程序计数器指示的地址处取出指令并执行,值的序列称为逻辑控制流

2.一个要运行多个进程的系统,逻辑流的执行可能是交错的。每个进程执行其的流的时候,可能会被抢占由其他进程执行。当一个逻辑流在时间上与另一个重叠则成为并发流。进程执行它的逻辑控制流的一部分时间成为进程时间片。

3.用户模式

用户模式的进程不允许执行特殊指令,也不允许直接引用地址空间中内核区的代码和数据。

4.内核模式

内核模式的进程可以执行指令集中任何命令,并且可以访问系统中任何内存位置。

5.上下文

上下文是由程序正确运行所需的状态组成的,包括存放在程序中的代码和数据,它的栈、通用目的寄存器内容、程序计数器、环境变量以及打开文件描述符的集合。

6.调度

在进程执行时,内核可以直接抢占当前进程,并重新开始一个先前被抢占的进程,该决策称之为调度。

同时上下文切换时

(1)保存当前进程的上下文

(2)恢复先前被抢占的进程的下文

(3)控制传递给新进程,系统调用、中断可能引起上下文切换。

6.6 hello的异常与信号处理

以下格式自行编排,编辑时删除

 hello执行过程中会出现哪几类异常,会产生哪些信号,又怎么处理的。

 程序运行过程中可以按键盘,如不停乱按,包括回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps  jobs  pstree  fg  kill 等命令,请分别给出各命令及运行结截屏,说明异常与信号的处理。

hello执行过程中可能出现4种异常:中断、陷阱、故障、终止。

图31 hello执行可能的4类异常

类别

原因

中断

来自I/O设备的信号

陷阱

有意的异常

故障

潜在可恢复的错误

终止

不可恢复的错误

产生信号处理方式

1.中断处理

图32 中断处理

2.陷阱和系统调用

 

图33 陷阱和系统调用

3.故障

 

图34 故障

4.终止

 

图35 终止

程序运行各命令和结果截屏

1.正常运行

 

图36 正常运行

2.Ctrl+Z

    键盘输入Ctrl+Z 指令后,进程收到SIGTSTP信号,暂时挂起。

(1)ps、jobs

输入ps命令符后发现hello进程仍未结束,进程PID为41272.

输入Jobs命令符后发现显示当前作业。

 

图37 输入Ctrl+Z后再输入ps、jobs截图

(2)pstree

 

图38 pstree(进程树)截图

(3)fg

   键盘输入fg命令符后,hello被暂时挂起的进程恢复到前台运行。

 

图39 fg截图

(4)kill

hello被挂起后,在键盘上输入kill命令符,hello进程结束。

 

图40 kill截图

3.Ctrl+C

键盘输入Ctrl+C后,进程收到SIGINT信号,进程结束。

 

图41 Ctrl+C截图

4.中途乱按

 

图42 中途乱按截图

在输入回车符以前,乱按输入的字符不会被记录;输入回车符后,乱按的字符会被当做指令被执行。

6.7本章小结

通过本章学习,我对hello进程管理有了更具体的认知,对进程概念及作用、fork函数、execve函数、异常与信号处理等知识点做出来进一步巩固。

(第6章1分)


7hello的存储管理

7.1 hello的存储器地址空间

以下格式自行编排,编辑时删除

结合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动态存储分配管理

以下格式自行编排,编辑时删除

Printf会调用malloc,请简述动态内存管理的基本方法与策略。

7.10本章小结

以下格式自行编排,编辑时删除

(第7章 2分)


8hello的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所经历的过程。

你对计算机系统的设计与实现的深切感悟,你的创新理念,如新的设计与实现方法。

以hello.c程序的一生为例,本文对计算机系统所学的知识进行了整理、复习和重温,在Ubuntu虚拟机下分析hello的一生。重点分析了hello.c转化为可执行文件前所经历的四个阶段——预处理阶段、编译阶段、汇编阶段、链接阶段,并对进程管理进行了深入的分析。

hello经历过程

1.hello.c预处理到hello.i文本文件

2.hello.i编译成hello.s汇编文件

3.hello.s汇编成二进制可重定位目标文件hello.o

4.hello.o链接生成可执行文件hello.ld

5.父进程调用fork生成子进程。

6.execve函数加载运行当前进程上下文中加载运行程序hello.ld

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


附件

列出所有的中间产物的文件名,并予以说明起作用。

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

Hello.c

源程序

Hello.i

Hello.c预处理生成hello.i文件

Hello.s

Hello.i编译生成hello.s汇编文件

Hello.o

Hello.s汇编后生成的可重定位目标文件

Hello.ld

Hello.o链接后生成的可执行文件

elf.txt

Hello.o的elf格式文件

Elf_hello.txt

Hello.ld的elf格式文件


参考文献

为完成本次大作业你翻阅的书籍与网站等

[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.

[7]https://blog.csdn.net/HITSTU/article/details/106337934

[8]https://blog.csdn.net/zhiai_/article/details/124834481

(参考文献0分,缺失 -1分)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值