HIT ICS大作业:程序人生——Hello‘s P2P
计算机系统
大作业
题 目 程序人生-Hello’s P2P
专 业 计算机
学 号
班 级
学 生
指 导 教 师 史先俊
计算机科学与技术学院
2022年5月
关键词:深入理解计算机系统;程序生命周期;Linux平台;进程;存储;
2.2在Ubuntu下预处理的命令............................................................................. - 5 -
5.3 可执行目标文件hello的格式........................................................................ - 8 -
6.2 简述壳Shell-bash的作用与处理流程........................................................ - 10 -
6.3 Hello的fork进程创建过程......................................................................... - 10 -
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.2 简述Unix IO接口及其函数.......................................................................... - 13 -
第1章 概述
1.1 Hello简介
hello.c文件是一个C语言程序。功能为在接收正确的参数之后,会在控制台中输出”Hello 学号 姓名 秒数”。要使得程序可以运行,程序需要经历以下过程:预处理(宏定义,展开头文件)、编译(翻译为汇编语言程序)、汇编(翻译成可重定位的目标程序)、链接(生成可执行目标程序),最终得到可执行文件,我们称为程序的Program To Progress,即P2P。
1.2 环境与工具
硬件环境:AMD Ryzen 7 4800H with Radeon Graphics 2.90 GHz
软件环境:Windows 10 家庭中文版 64位 VirtualBox/Vmware 11以上;Ubuntu 20.04 LTS 64位
开发工具:CodeBlocks;vi/vim/gpedit+gcc;Visual Studio 2010 64位以上;GDB/OBJDUMP;DDD/EDB等
1.3 中间结果
1.4 本章小结
对程序hello的一生进行了大体的介绍,简介作业环境工具和中间文件。
第2章 预处理
2.1 预处理的概念与作用
概念:预处理是指程序源代码在被翻译为目标代码的过程中,生成二进制码之前的过程,由预处理器对程序源代码文本进行处理,其结果再由编译器核心进一步进行编译。
2.2在Ubuntu下预处理的命令
gcc -m64 -no-pie -fno-PIC -E hello.c -o hello.i
2.3 Hello的预处理结果解析
打开运行上述预处理指令得到的文件,发现文件前面存在大量由头文件展开导入的内容,在hello.c中对应着
由此合理猜测:预处理最大的作用是解析头文件的引用,并将其展开。
由图中行号可见,文件3000行后才出现源程序的main函数,可见头文件展开的规模之大。
2.4 本章小结
第3章 编译
3.1 编译的概念与作用
概念:编译是将高级语言转换成汇编语言的过程,编译器(ccl)会进行词法分析,语法分析,并进行翻译(尽管机器仍然无法理解编译后的程序)
作用:编译后hello.i转化为hello.s,其中包含汇编语言程序,程序员可从汇编语言看到程序更偏向底层的运作,例如如何操控数据,调用哪些内存与寄存器。
3.2 在Ubuntu下编译的命令
gcc -m64 -no-pie -fno-PIC -S hello.i -o hello.s
3.3 Hello的编译结果解析
现在针对操作处理,数据类型,观察对比hello.c与hello.s,对hello.s进行分析:
字符串常量:在汇编代码中发现代码中存在的两个字符串:"用法: Hello 学号 姓名秒数!\n","Hello %s %s\n"
i作为局部变量一般存储于栈中,观察汇编代码得i的存储位置如图。
由原函数得知存在对三个函数的调用exit(),sleep(),getchar(),printf(),atoi
其中调用atoi(),sleep()的时候,参数均被存入%rdi。atoi的返回值存入%rax后又存入%rdi为sleep调用(atoi为类型转换函数)。
在for循环中含有i<8的关系操作,此外if判断中还含有argc!=4的关系操作。
若未满足argc!=4,则跳转至L2继续程序,否则调用exit(1)。
3.4 本章小结
第4章 汇编
4.1 汇编的概念与作用
概念:把汇编代码翻译成机器代码,即目标代码的过程,即由.s文件到.o文件。
4.2 在Ubuntu下汇编的命令
gcc -m64 -no-pie -fno-PIC -c hello.s -o hello.o
4.3 可重定位目标elf格式
执行readelf -a hello.o>hello_ELF.txt,即可生成elf格式的文件。
ELF头以16字节的序列开始(包含系统字的大小和字节顺序),其余部分包含ELF头大小、目标文件类型、机器类型、节头部表的文件偏移、条目大小和数量。
unsigned char e_ident[EI_NIDENT];
//包含用以表示ELF文件的字符,以及其他一些与机器无关的信息。开头的4个字节值固定不变,为0x7f和ELF三个字符。
Elf32_Half e_machine;//运行该程序需要的体系结构
Elf32_Off e_phoff;// Program header table 在文件中的偏移量
Elf32_Off e_shoff;// Section header table 在文件中的偏移量
Elf32_Word e_flags;// ELF文件平台的相关属性(IA32=0)
Elf32_Half e_ehsize;// ELF header长度
Elf32_Half e_phentsize;// 表示Program header table中条目大小
Elf32_Half e_phnum;// 表示Program header table中条目数量
Elf32_Half e_shentsize;// 表示Section header table中条目大小
Elf32_Half e_shnum;// 表示Section header table中条目数量
Elf32_Half e_shstrndx;// 包含节名称的字符串的下标
节头是保存ELF文件段的基本属性的结构。ELF文件的段结构由段表决定,编译器,链接器,装载器通过段表来访问各个段的属性。
Elf32_Word sh_type; // 段的类型(代码段,数据段,符号表)
Elf32_Word sh_flags; / 段在进程虚拟地址空间中的属性
Elf32_Off sh_offset; // 段在文件中的偏移
Elf32_Word sh_addralign; // 段地址对齐
链接器需要通过重定位表中的信息来对目标文件中的部分进行重定位。
4.4 Hello.o的结果解析
输入objdump -d -r hello.o即可查看hello.o的反汇编结果。(已输出为hello_obj.txt)
4.5 本章小结
本章简单介绍了汇编操作的概念与作用,对.s文件进行汇编后,将其转化为elf格式并进行分析,最终反汇编.o文件并与.s文件进行对比。
第5章 链接
5.1 链接的概念与作用
概念:链接是处理可重定位文件,把各种符号引用和符号定义转换为可执行文件,组合成一个单一文件的过程。
链接分为静态链接和动态链接:前者是程序开发阶段程序员用ld静态链接器手动链接的过程,后者动态链接则是程序运行期间系统调用动态链接器自动链接的过程。
作用:令不同模块的代码互相整合,可以将多个文件链接彻底转化为机械代码,生成可执行文件。使得分离编程成为可能。
5.2 在Ubuntu下链接的命令
5.3 可执行目标文件hello的格式
输入readelf -S hello(已生成文件hello_ELF2.txt)
5.4 hello的虚拟地址空间
使用edb加载hello,查看本进程的虚拟地址空间各段信息,并与5.3对照分析说明。
打开Plugins-SymbolViewer,观察虚拟空间地址各段信息。与5.3对比发现一致。
5.5 链接的重定位过程分析
输入objdump -d -r hello>hello_obj2.txt,生成hello的反汇编文件hello_obj2.txt。
与前面生成的反汇编hello_obj.txt比较,发现新文件中引入了调用函数(如atoi,sleep,printf等)的详细解释。
5.6 hello的执行流程
使用edb执行hello,说明从加载hello到_start,到call main,以及程序终止的所有过程。请列出其调用与跳转的各个子程序名或程序地址。
5.7 Hello的动态链接分析
分析hello程序的动态链接项目,通过edb调试,分析在dl_init前后,这些项目的内容变化。要截图标识说明。
执行_dl_init之后,global_offset表的值从0到被赋予正确的偏移量。
5.8 本章小结
本章了解了链接的概念与作用,分析链接后的可执行文件的ELF格式,了解了动态链接,重定位以及执行过程。
第6章 hello进程管理
6.1 进程的概念与作用
概念:进程是一个执行中的程序的实例,每个程序都运行在进程的上下文中。
6.2 简述壳Shell-bash的作用与处理流程
Shell解释用户输入的命令,然后将其送到内核;Shell还具有编程语言,允许编写由shell命令组成的程序。
6.3 Hello的fork进程创建过程
在shell内输入命令./hello 120L020315 胡泽恩 2,于是shell调用fork()函数,创建一个子进程来执行hello。调用一次,返回两次。
6.4 Hello的execve过程
6.5 Hello的进程执行
6.6 hello的异常与信号处理
可能信号:1.SIGINT 2.SIGSTP 3.SIGCONT 4.SIGKILL
在程序执行过程中敲打键盘,并未对程序造成影响,在之后被识别为输入,可见过程中的输入并未对程序运行造成任何影响。
在执行途中按下ctrl+z,发送SIGTSTP信号,使其停止。输入jobs或ps均能看见该进程。
在hello执行过程中,按下ctrl+c,发送SIGINT信号,终止该进程。
6.7本章小结
本章介绍了进程的概念作用,运行原理,进程的用户模式和内核模式、上下文切换、重要函数fork和execve、异常与信号、进程的并发执行等等。
第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址:又称相对地址,是程序运行由CPU产生的与段相关的偏移地址部分。用于描述程序运行段。
物理地址:内存地址寄存器中的地址,内存单元的真正地址。在前端总线上传输而且唯一。
线性地址:在保护模式下,“段基址+段内偏移地址”叫做线性地址,是用于描述程序分页信息的地址。
虚拟地址:虚拟地址并不真实存在于计算机中。每个进程都分配有自己的虚拟空间,而且只能访问自己被分配使用的空间。虚拟空间受到物理内存大小的限制。
7.2 Intel逻辑地址到线性地址的变换-段式管理
7.3 Hello的线性地址到物理地址的变换-页式管理
7.4 TLB与四级页表支持下的VA到PA的变换
7.5 三级Cache支持下的物理内存访问
将物理地址拆分成CT(标记)+CI(索引)+CO(偏移量),然后在一级cache内部找,如果未能寻找到标记位为有效的字节(miss)的话就去二级和三级cache中寻找对应的字节,找到之后返回结果。
7.6 hello进程fork时的内存映射
fork函数被shell进程调用时,内核为新进程创建各种数据结构,并分配给他一个唯一的PID。它创建了当前进程的mm_struct区域结构和页表的原样副本,并且将两个进程中的每个页面都标记为只读。
7.7 hello进程execve时的内存映射
exceve函数加载和执行程序Hello,需要以下几个步骤:
2.映射私有区域。为Hello的代码、数据、bss和栈区域创建新的区域结构,所有这些区域都是私有的、写时复制的。
3.映射共享区域。比如Hello程序与标准C库libc.so链接,这些对象都是动态链接到Hello的,然后再用户虚拟地址空间中的共享区域内。
4.设置程序计数器。exceve做的最后一件事就是设置当前进程上下文的计数器,使得其指向入口。
7.8 缺页故障与缺页中断处理
1.段错误:先判断这个缺页的虚拟地址是否合法,遍历所有的合法区域结构,如果这个虚拟地址对所有的区域结构都无法匹配,那么就返回一个段错误(segment fault)。
2.非法访问:接着查看这个地址的权限,判断一下进程是否有读写改这个地址的权限。
3.如果不是上面两种情况那就是正常缺页,牺牲一个页面然后换入新的页面并更新到页表。
缺页中断处理:当发生缺页故障时,将控制转移给处理程序,处理程序从磁盘加载适当的页面,然后将控制转移给引起故障的指令。接着指令再次执行,相应的物理页面已经驻留在内存中,就可以没有故障地运行指令了。
7.9动态存储分配管理
动态内存分配器维护着一个进程的虚拟内存区域,称为堆。堆是一个请求二进制零的区域,它紧接在未初始化的数据区域后开始,并向上生长。对于每个进程,内核维护着一个变量brk,指向堆的顶部。
分配器有两种风格——显示分配器和隐式分配器,但是这两种风格都要求应用显示的分配块。
其中显示分配器要求显示释放任何已分配的块,如malloc、new等。
隐式分配器要求分配器检测一个已分配块何时不再被程序所使用,那么就释放这个块。所以也叫垃圾收集器。
显示分配器有以下几点要求:能够处理任意请求序列;立即相应请求;只是用堆;对齐开;不修改已分配的块。在性能上有两点追求:最大化吞吐,最大化内存利用率;两者通常矛盾。
7.10本章小结
本章较为详细的介绍了计算机系统存储的概念,引入了四种地址的概念,分别介绍了内存的分页式管理,三级cache的高层内存管理等等,在计算机系统学习占有很大的比重。
第8章 hello的IO管理
8.1 Linux的IO设备管理方法
文件分为普通文件:包含任意数据的文件;目录(文件夹):包含一组链接的文件,每个链接都将一个文件名映射到一个文件。套接字:用来与另一个进程进行跨网络通信的文件;命名通道;符号链接;字符和块设备;
设备管理:unix io接口:打开和关闭文件,读取和写入文件,改变当前文件的位置。
8.2 简述Unix IO接口及其函数
int open(char *filename, int flags, mode_t mode);
ssize_t read(int fd, void *buf, size_t n);
read函数从描述符为fd的当前文件位置复制最多n个字节到内存位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。
ssize_t write(int fd, const void *buf, size_t n);
write函数从内存位置buf复制之多n个字节到描述符fd的当前文件位置。
DIO *opendir(const char *name);
函数opendir以路径名为参数,返回指向目录流的指针。流是对条目有序列表的抽象,在这里是指目录项的列表。
struct dirent *readdir(DIR *dirp);
每次对readdir的调用返回的都是指向流dirp中下一个目录项的指针,或者,如果没有更过目录项则返回NULL。
int dup2(int oldfd, int newfd);
dup2函数复制描述符表表项oldfd到描述符表项newfd,覆盖描述符表表项newfd以前的内容。如果newfd已经打开了,dup2会在复制oldfd之前关闭newfd。
8.3 printf的实现分析
printf需要做的事情是:接受一个fmt的格式,然后将匹配到的参数按照fmt格式输出。
从上图可见,调用了两个外部函数:vsprintf,write。
vsprintf的作用是将所有的参数内容格式化之后存入buf,然后返回格式化数组的长度。write函数是将buf中的i个元素写到终端的函数。
字符显示驱动子程序:从ASCII到字模库到显示vram,(存储每一个点的RGB颜色信息)。
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析
getchar()是 stdio.h.中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了。
实际上是输入设备->内存缓冲区->程序getchar
异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结
本章节讲述了linux的I/O设备管理机制与相关函数,简单分析了printf和getchar函数的实现方法以及操作过程。
结论
汇编:将hello.s汇编成为可重定位目标文件hello.o
链接:将hello.o与动态链接库链接成为可执行文件hello
运行:在shell中输入./hello 120L020315 胡泽恩 1
运行程序:shell调用execve,execve调用启动加载器,加映射虚拟内存,进入程序后开始载入物理内存,然后进入 main函数。
附件
参考文献
[1] GCC编译优化和调试选项 https://zhuanlan.zhihu.com/p/342695075
[2] 深入理解计算机系统 Randal E. Bryant David R. O’Hallaron
[3] ELF文件格式 百度百科 https://baike.baidu.com/item/ELF/7120560#1
HIT ICS大作业:程序人生——Hello‘s P2P相关推荐
- HIT计算机系统大作业-程序人生-Hello’s P2P
计算机系统大作业 ** 由于采用静态部署,需要看图片详细分析的小伙伴请移步个人博客网站:** 个人博客 题目:程序人生-Hello's P2P 学号: 姓名:熊峰 摘要: hello程序作为最简单的. ...
- HIT 计算机系统 大作业 程序人生-Hello’s P2P
计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机类 学 号 1180300223 班 级 1803002 计算机科学与技术学院 2019年12月 摘 要 本文主要介绍了一个 ...
- hit csapp大作业 程序人生-Hello’s P2P
计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机科学与技术 学 号 2021112810 班 级 2103103 学 生 肖芩芩 指 ...
- ICS大作业——程序人生 Hello‘s P2P
- HIT 深入理解计算机系统 大作业 程序人生-Hello’s P2P
HIT 深入理解计算机系统 大作业 程序人生-Hello's P2P 本论文旨在研究 hello 在 linux 系统下的整个生命周期.结合 CSAPP 课本, 通过 gcc 等工具进行实验,从而将课 ...
- HITICSAPP2019大作业——程序人生-Hello’s P2P
俺是Hello,额是每一个 程序猿 ¤的初恋(羞羞--)却在短短几分钟后惨遭每个菜鸟的无情抛弃(呜呜--),他们很快喜欢上sum.sort.matrix.PR.AI.IOT.BD.MIS--,从不回头 ...
- 【2022】哈工大计算机系统大作业——程序人生Hello’s P2P
2022哈工大计算机系统大作业--程序人生Hello's P2P 摘要 第1章 概述 1.1 Hello简介 1.2 环境与工具 1.3 中间结果 1.4 本章小结 第2章 预处理 2.1 预处理的概 ...
- 2022春哈工大ICS大作业——程序人生-hello‘sP2P
计算机系统(初发布于2022/5/15,修改于2022/5/20) 大作业 题 目 程序人生-Hello's P2P 专 业 学 号 班 级 学 生 沈业力 ...
- 2022计算机系统大作业——程序人生-Hello’s P2P
计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机 学 号 120L021716 班 级 2003005 学 生 蔡泽栋 指 导 ...
- 哈工大计算机系统大作业——程序人生-Hello’s P2P
计算机系统 大作业 题 目程序人生-Hello's P2P 专 业 计算机科学与技术 学 号120L022401 班 级 200300 ...
最新文章
- 3D视觉技术的6个问答
- AI 版 Nature Index 排名,两种结果折射中国 AI 实力软肋
- BCOS系统合约介绍
- java把二维转换为一维_在R语言中什么函数可以将二维数组转换成一维数组
- 机器学习-分类算法-朴素贝叶斯算法07
- 下一个嵌入式大神,难道不是你吗?
- android跑分和ios,手机:苹果VS安卓 跑分不代表手机流畅度
- 中用BBP公式计算_如何计算基础代谢率
- UI设计干货素材|简单素材模板教你分分钟提高UI设计水平!
- Oracle Logminer 说明
- python数据格式化后导入数据库_MySQL导入格式化数据
- javascript中的计时器
- Android去掉wps广告,WPS解锁高级功能,PC和安卓版去除广告,精简版!
- 关于virtual box安装windows xp虚拟机遇到的一个问题
- 【机器学习算法】线性回归算法
- 服务器装系统报0x0000005d,Win8系统安装过程中提示ErrorCode:0x0000005D怎么办
- 快速跳转到行首/行尾 快捷键
- mysql导入时区_【MySQL】将时区信息导入MYSQL
- 数学建模学习(98):CHIO优化算法
- 太阳高度角计算题_【高考地理】地理计算题型汇总(附太阳高度角专题设计)...
热门文章
- 国内四大骨干网与十大ISP服务商
- 金额查错:某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某1笔或几笔, 如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗?
- BTC 安装和使用笔记
- 炫舞时代服务器维护中怎么办,《炫舞时代》皇宫大区前世今生系统bug怎么办 异常问题解决及补偿介绍...
- 如何成为一个优秀的数据科学家的投石之路
- 【Java】图像透明渐变融合
- RXA-Thanos是一个SpringCloud 分布式事务解决方案
- PPT文件打开的时候需要输入密码才能编辑?
- Python3.X 爬虫实战(静态下载器与解析器)
- 运营小红书需要注意什么?这4个方法助你成为小红书达人!(下)