计算机系统
大作业
题 目 程序人生-Hello’s P2P
专 业 计算机
学 号 xxxx
班 级 1936603
学 生 xxx
指 导 教 师 刘宏伟
计算机科学与技术学院
2021年6月
摘 要
本文借助hello程序的运行过程介绍了计算机系统的底层知识:程序加工、进程执行、存储管理等。主要采用实验验证的方法,通过在Ubuntu操作系统+x64cpu上分解hello程序运行的各个阶段,展示一个“小生命”从新生到结束的过程,最终达到深入理解计算机系统的目的。能够使读者在日常的编程中提高系统能力,从计算机系统去考虑问题,而不仅仅是考虑数据结构和算法。
**关键词:**计算机系统;Linux;程序的运行;进程管理;存储管理;
(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
**
**
目 录
第1章 概述
1.1 Hello简介
本论文会从一个hello程序的一生作为示例,分析一个C语言程序在linux+
X64环境下所要经历的全部内容。
首先从编写高级语言源程序开始,我们需要建立一个hello.c文件,并按照特定的语法写入程序,但是此时的程序还不能执行,我们需要经过预处理(展开头文件、宏定义等)、编译(翻译为汇编语言程序)、汇编(翻译为可重定位的目标程序)、链接(生成可执行的目标程序),最终生成一个可以执行的程序hello。
接着,这个程序要想运行,需要在shell中输入命令./hello 1190401018
黄子扬,shell在磁盘上找到相应的程序,现fork一个子进程,接着用execve将hello的上下文加载入这个子进程,并开始执行。程序执行结束后,它并不会立刻完全消失,需要等待父进程将其回收,至此,它才能完全从世界上消失。
在控制流执行的过程中,离不开硬件的帮忙,而现代的处理器的流水线设计,大大提高了吞吐率,使得不同程序的取值、译码、执行、访存、写回、更新PC六大阶段可以在一定条件下并行,极大的提高了运行速率。
程序当然是需要存储空间的了,当前的系统具有四级页表、三级cache、还有容量超大的主存和磁盘,如此复杂却又精细的一套内存管理系统,让hello能够尽情的运行在计算机系统上。cpu从虚拟地址开始,首先查找TLB,如果直接找到则能直接翻译为物理地址,否则则按照级别从多级页表中查找,最终翻译为物理地址,接着又到L1cache中去寻找我们要的字节数据,如果没找到,则按照存储体系从上到下继续寻找。
1.2 环境与工具
列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。
软件环境:Windows10 64位; Vmware 15.6;Ubuntu 20.04 LTS 64位
硬件环境:X64 CPU;2GHz;2G RAM;256GHD Disk
开发与调试工具:gcc、gdb、vscode、readelf、edb
1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
附件1 hello.c
作用:高级语言源程序
附件2 hello.i
作用:预处理生成的.i文件
附件3 hello.s
作用:编译生成的.s文件(汇编语言文件)
附件4 hello.o
作用:汇编生成的.o文件(可重定位的目标文件)
附件5 hello.elf
作用:hello.o的elf格式,用于展示可重定位的elf文件格式
附件6 hello.asm
作用:hello.o的反汇编格式,用汇编语言的格式来观察可重定位的目标文件
附件7 hello
作用:链接生成的可执行的目标文件
附件8 hello_exe.elf
作用:hello的elf格式,用于展示可执行的elf文件格式
附件9 hello_exe.asm
作用:hello的反汇编格式,用汇编语言的格式来观察可执行的目标文件
1.4 本章小结
本章从总体上介绍了hello程序的一生,主要从p2p的过程,即从高级语言源程序到正在执行的进程的过程,和020的过程,即从程序还没开始执行到最终进程被回收的过程,这两个过程来展开的。
本章的精华涵盖了一个程序执行的几乎所有方面:预处理、编译、汇编、链接、fork子进程、execve切换上下文、进程信号机制、硬件执行流程(F、D、E、M、W、U)、从cache到磁盘的存储体系、进程回收机制等。
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
概念:预处理一般是指在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的过程。典型地,由预处理器(preprocessor)
对程序源代码文本进行处理,得到的结果再由编译器核心进一步编译。通常由以下几个操作组成:
头文件展开:将#include包含的文件插入到该指令位置
宏展开:展开所有的宏定义,并删除#define
条件编译:处理所有的条件预编译指令: #if、 #ifdef、 #else
删除注释
添加行号和文件名标识:编译调试时显示行号信息
保留#pragma命令
作用:
宏定义可以简化我们的编程,赋予一个常量有意义的特定的名字,在编程中可以方便程序员的操作,在预处理后会统一进行替换;
头文件的包含可以帮助程序员调用其他模块定义的函数、功能,方便将一个大型程序进行系统化、模块化、组件化;
注释只是在源文件中帮助程序员理解而写的文字,完全没必要在编译的时候考虑,所以一律删掉;
条件编译可以帮助程序员有选择地进行编译,针对不同情况进行处理;
添加行号信息则是方便程序员进行调试操作,能够在debug的时候快速定位错误位置。
2.2在Ubuntu下预处理的命令
gcc -m64 -no-pie -fno-PIC -E hello.c -o hello.i
图2-2-1 预处理命令
图2-2-2 预处理后得到的文件hello.i
2.3 Hello的预处理结果解析
我们打开预处理得到的hello.i文件