十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
巴彦淖尔ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
计算机系统
大作业
题 目 程序人生-Hello's P2P
计算机科学与技术学院
2022年5月
摘 要
本文以hello这个最简单的程序回顾了计算机系统如何实现一个程序的运行,从hello这个程序运行的"一生"回顾计算机系统里的重要概念。本文主要涉及编译链接、进程控制、内存管理和IO。
关键词:计算机系统;P2P;编译;链接;进程;虚拟内存;IO
(摘要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本章小结- 7 -
第3章编译- 8 -
3.1编译的概念与作用- 8 -
3.2在Ubuntu下编译的命令- 8 -
3.3 Hello的编译结果解析- 8 -
3.4本章小结- 13 -
第4章汇编- 14 -
4.1汇编的概念与作用- 14 -
4.2在Ubuntu下汇编的命令- 14 -
4.3可重定位目标elf格式- 14 -
4.4 Hello.o的结果解析- 17 -
4.5本章小结- 18 -
第5章链接- 20 -
5.1链接的概念与作用- 20 -
5.2在Ubuntu下链接的命令- 20 -
5.3可执行目标文件hello的格式- 20 -
5.4 hello的虚拟地址空间- 25 -
5.5链接的重定位过程分析- 26 -
5.6 hello的执行流程- 28 -
5.7 Hello的动态链接分析- 29 -
5.8本章小结- 29 -
第6章 hello进程管理- 30 -
6.1进程的概念与作用- 30 -
6.2简述壳Shell-bash的作用与处理流程- 30 -
6.3 Hello的fork进程创建过程- 31 -
6.4 Hello的execve过程- 32 -
6.5 Hello的进程执行- 32 -
6.6 hello的异常与信号处理- 32 -
6.7本章小结- 36 -
第7章 hello的存储管理- 37 -
7.1 hello的存储器地址空间- 37 -
7.2 Intel逻辑地址到线性地址的变换-段式管理- 37 -
7.3 Hello的线性地址到物理地址的变换-页式管理- 39 -
7.4 TLB与四级页表支持下的VA到PA的变换- 40 -
7.5三级Cache支持下的物理内存访问- 42 -
7.6 hello进程fork时的内存映射- 43 -
7.7 hello进程execve时的内存映射- 43 -
7.8缺页故障与缺页中断处理- 44 -
7.9动态存储分配管理- 45 -
7.10本章小结- 45 -
第8章 hello的IO管理- 46 -
8.1 Linux的IO设备管理方法- 46 -
8.2简述Unix IO接口及其函数- 46 -
8.3 printf的实现分析- 47 -
8.4 getchar的实现分析- 49 -
8.5本章小结- 49 -
结论- 49 -
附件- 50 -
参考文献- 51 -
Hello的P2P是指program to process,由程序到进程。也就是从我们编写的c语言程序到进程的过程。Hello.c文件经过cpp预处理得到hello.i,而后经过ccl生成hello.s,在之后经过汇编器as得到hello.o,之后链接器ld将其转换为hello可执行目标文件,最后shell为hello进行fork创建子进程,hello就成了process。
Hello的020即 from zero-0 to zero-0,说的是内存数据的从无到有再到无。初始时内存里没有hello的相关数据,因此是from zero-0,通过shell中的execute函数将hello载入内存为其分配空间,当程序结束后,hello进程被回收,内核删除内存里关于hello的数据,完成to zero-0.
本机:cpu:ryzen5800HRAM:3200MHz 16GB Samsung
虚拟环境:vmware16pro Ubuntu20.04
Halo.asmhello的反汇编
Halo.elfhello的elf格式
Hellohello程序的可执行程序
Hello.asmhello.o的反汇编
Hello.c 源程序
Hello.elfhello.o的elf格式
Hello.ihello的预处理文件
Hello.o hello的可重定位目标文件,为汇编后的结果
Hello.s hello的汇编文件
本章介绍hello从诞生到执行结束的过程,阐述了p2p和020的含义。
(第1章0.5分)
预处理是指预处理器(cpp,C Pre-Processor)根据以字符#开头的命令,修改原始的C程序的过程。
预处理的作用是由预处理器来进行注释删除、包含其他文件、以及执行宏替代,方便后续的编译。
Figure 1 预处理操作
打开经过预处理后的hello.i文件,发现文件有3060行,远远多余之前的程序,仔细观察发现#后include的头文件已经被插入其中,所有注释都已经删除。在hello.i
文件开始的几行内也记录了被插入的头文件的位置。
Figure 2 插入头文件的位置
Figure 3 预处理后产生的文件
本章对预处理的概念和作用进行了说明,并对hello.c进行了预处理操作以验证。
(第2章0.5分)
编译是指通过编译器将程序从便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的过程。
编译的作用是产生目标语言(target language),即汇编语言,为后续的汇编程序准备。
键入命令:gcc -m64 -Og -no-pie -fno-PIC hello.i -o hello.s -S,可生成hello.s文件。
Figure 4 编译命令
3.3.1 数据
程序中包含了字符串常量,在.s文件内如下
Figure 5 字符串常量
文件内也有进行for循环时使用的局部变量i,存在ebp寄存器内。
Figure 6 寄存器内的i变量
程序内的argc和argv作为main函数的参数,一般在edi和rdi内,在调用函数之前有寄存器传递参数。
Figure 7 edi存argc
Figure 8 rbx存argv地址,调用atoi时传递
3.3.2赋值
在c语言程序中没有出现赋值 =操作。
3.3.3类型转换
C程序中未出现类型转换操作
3.3.4 sizeof
C语言程序中未出现sizeof
3.3.5算数操作
For循环里每个循环对i都进行加1操作,在.s文件内如下
Figure 9 算数操作
3.3.6逻辑/位操作
C语言源程序内没有逻辑/位操作。
3.3.7关系操作
For循环每次进行判断应用了==关系操作,在文件内如下
Figure 10 关系操作
每个循环开始前与7比较大小进行==关系操作。
3.3.8数据/指针/结构操作
在for循环的每个循环内需要对数据内元素进行访存操作,在文件内如下
Figure 11 通过寄存器内元素地址进行数组元素访存
3.3.9控制转移
源程序中运用了for循环,在文件内如下
Figure 12 控制转换-for
同时程序内还含有if,在文件内如下
Figure 13 控制转移-if
3.3.10函数操作
源程序调用了printf、atio、sleep、getchar、exit函数,在文件内如下
Figure 14 printf函数
寄存器Rdx,rsi,edi存储的都为printf函数的参数,eax为printf函数的返回值,在调用前置零。
Figure 15 atio函数
寄存器rdi存储着atio函数的参数,eax寄存器存储着该函数的返回值。
Figure 16 sleep函数
该函数的参数储存在edi寄存器内
Figure 17 调用getchar函数
Figure 18 调用exit函数
本章介绍了编译的概念和作用,编译为后续生成二进制机器码做准备。以生成的hello.s为例,分析了编译的结果。
(第3章2分)
使用汇编语言编写的源代码,然后通过相应的汇编程序(assembler)将它们转换成可执行的机器代码。这一过程被称为汇编过程。
注意:这儿的汇编是指从 .s到 .o即编译后的文件到生成机器语言二进制程序的过程。
汇编的作用将汇编语言等价翻译为机器语言,生成可重定位目标程序。
输入的汇编命令为:gcc -m64 -Og -no-pie -fno-PIC hello.s -o hello.o -c
Figure 19 汇编过程
在终端内输入readelf -a hello.o > hello.elf指令以获得.elf文件,内容为hello.o的ELF格式:
Figure 20 hello.o的ELF格式