【2023】哈工大计算机系统大作业——程序人生Hello’s P2P

目录

第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 本章小结............................................... - 5 -

第3章 编译................................................... - 6 -

3.1 编译的概念与作用............................... - 6 -

3.2 在Ubuntu下编译的命令.................... - 6 -

3.3 Hello的编译结果解析........................ - 6 -

3.4 本章小结............................................... - 6 -

第4章 汇编................................................... - 7 -

4.1 汇编的概念与作用............................... - 7 -

4.2 在Ubuntu下汇编的命令.................... - 7 -

4.3 可重定位目标elf格式........................ - 7 -

4.4 Hello.o的结果解析............................. - 7 -

4.5 本章小结............................................... - 7 -

第5章 链接................................................... - 8 -

5.1 链接的概念与作用............................... - 8 -

5.2 在Ubuntu下链接的命令.................... - 8 -

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

5.4 hello的虚拟地址空间......................... - 8 -

5.5 链接的重定位过程分析....................... - 8 -

5.6 hello的执行流程................................. - 8 -

5.7 Hello的动态链接分析........................ - 8 -

5.8 本章小结............................................... - 9 -

第6章 hello进程管理.......................... - 10 -

6.1 进程的概念与作用............................. - 10 -

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

6.3 Hello的fork进程创建过程............ - 10 -

6.4 Hello的execve过程........................ - 10 -

6.5 Hello的进程执行.............................. - 10 -

6.6 hello的异常与信号处理................... - 10 -

6.7本章小结.............................................. - 10 -

第7章 hello的存储管理...................... - 11 -

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 -

7.9动态存储分配管理.............................. - 11 -

7.10本章小结............................................ - 12 -

第8章 hello的IO管理....................... - 13 -

8.1 Linux的IO设备管理方法................. - 13 -

8.2 简述Unix IO接口及其函数.............. - 13 -

8.3 printf的实现分析.............................. - 13 -

8.4 getchar的实现分析.......................... - 13 -

8.5本章小结.............................................. - 13 -

结论............................................................... - 14 -

附件............................................................... - 15 -

参考文献....................................................... - 16 -


第1章 概述

1.1 Hello简介

P2P(From Program to Process)过程:
hello的生命周期是从一个高级C语言程序开始的,分为四个阶段:首先经过预处理器cpp进行预处理,生成文本文件hello.i,然后经过编译器ccl生成hello.s汇编程序,接着经过汇编器as生成hello.o文件,最后经过链接器ld将其与引用到的库函数链接,生成可执行文件hello。再通过系统创建一个新进程并且把程序内容加载,实现有程序到进程的转化。
O2O(From Zero-0 to Zero-0)过程:
程序运行前,shell调用execve函数将hello程序加载到相应的上下文中,将程序内容载入物理内存。然后调用main函数。程序运行结束后,父进程回收进程,释放虚拟内存空间,删除相关内容。这就是hello.c的O2O过程。

 《图1 hello的编译运行过程》

1.2 环境与工具

硬件环境:X64 CPU;2GHz;4G RAM;256GSSD Disk 以上
软件环境:Windows11 64位;VMware Workstation Player 17;Ubuntu 22.04.2
开发和调试工具:gdb;edb;readelf;objdump;Code::Blocks20.03

1.3中间结果

编写这篇文章生成的中间结果文件以及文件内容如下表格所示

hello.i:hello.c预处理后的文件。
hello.s:hello.i编译后的文件。
hello.o:hello.s汇编后的文件。
hello:hello.o链接后的文件。
hello1asm.txt:hello.o反汇编后代码。
hello2asm.txt:hello反汇编后代码。
hello.o_elf:hello.o用readelf -a hello.o指令生成的文件。
hello_elf:hello用readelf -a hello指令生成的文件。

1.4 本章小结

本章根据hello的自白,概括介绍了hello的P2P和O2O的过程。此外,还介绍了本实验用到的硬软件环境和开发调试工具。

第2章 预处理

2.1 预处理的概念与作用

2.1.1预处理的概念:

在编译源文件时,系统会自动使用预处理程序对源程序中的预处理部分进行处理,并在处理完毕后自动进入对源程序的编译阶段。C语言提供了多种预处理功能,主要用于处理以#开头的预处理指令,例如宏定义(#define)、文件包含(#include)、条件编译(#ifdef)等。

2.1.2预处理的作用:

所有预处理器(cpp)命令都以井号(#)开头。井号必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。

以下是预处理器的功能和指令解释:

(1)在#include处添加对应的头文件。

(2)删除#define并展开相应的宏,使用#undef取消已经定义的宏。

(3)#ifdef用于判断宏是否已经定义,若已定义则返回真;#ifndef用于判断宏是否未定义,若未定义则返回真。

(4)处理所有条件预编译指令,例如#if和#endif。根据#if后面的条件决定需要编译的代码。

(5)#if用于判断给定条件是否为真,若为真则编译下面的代码;#else可用作#if的替代方案;#elif用于在前面的#if给定条件不为真时,判断当前条件是否为真,若为真则编译下面的代码;#endif用于结束#if……#else条件编译块。

(6)#error用于在遇到标准错误时输出错误信息。

(7)#pragma用于使用标准化方法,向编译器发布特殊的命令。

2.2在Ubuntu下预处理的命令

在终端中执行这个命令,gcc -E是使用GCC编译器的预处理功能,它将对hello.c文件进行预处理,并将结果输出到hello.i文件中。另一种方法是使用cpp命令,它也可以对hello.c文件进行预处理,并将结果通过重定向操作符(>)输出到hello.i文件中。无论使用哪种方法,都能生成名为hello.i的文本文件。

《图2-2-1 Ubuntu下预处理指令gcc及结果》

 《图2-2-2 Ubuntu下预处理指令cpp及结果》

2.3 Hello的预处理结果解析

在hello.i文件中,你可以看到经过预处理后的代码,其中已经去除了注释。文件的开头部分包含了所需的头文件,用于引入程序中所需的函数和定义。而文件的末尾部分(3077行至3091行)是与hello.c文件中的main函数完全一致的代码。这意味着在预处理阶段,hello.i文件中的代码已经展开并与原始代码中的main函数完全一致。

 《图2-3-1 hello.c预处理结果》

2.4 本章小结

在本章中,我们首先解释了预处理的概念,即在编译之前对源代码进行处理的过程。预处理的作用是通过执行预处理指令,如宏定义、文件包含和条件编译等,对源代码进行修改和准备,以便后续的编译过程能够顺利进行。

接着,我们以hello.c程序为例,展示了如何在Ubuntu操作系统下进行程序的预处理。通过使用gcc编译器的预处理功能,我们执行了相应的命令,对hello.c文件进行了预处理操作。预处理的结果是生成了一个经过宏展开、文件包含等处理的新文件,即hello.i。

最后,我们对预处理结果进行了分析。通过观察hello.i文件,我们可以看到注释已经消失,程序加载了所需的头文件,并且最后的代码部分与原始代码中的main函数完全一致。这样的分析帮助我们理解预处理的过程和影响,以便更好地理解和优化程序。

 第3章 编译

3.1 编译的概念与作用

3.1.1编译的概念:

在编译过程中,hello.i文件是经过预处理后的代码,其中包含了宏展开、文件包含和其他预处理指令的结果。接下来,编译器将对hello.i文件进行翻译,将其转换为另一个文本文件hello.s。

hello.s文件是汇编语言程序的表示形式,它包含了一系列汇编指令,用于表示原始代码的底层操作和指令。这个文件是编译器将高级语言代码转换为机器可执行指令的中间步骤。

通过将hello.i翻译为hello.s,编译器将代码从高级语言转换为汇编语言,为后续的汇编过程做准备。这个过程将源代码转化为更接近底层的指令级表示,为最终生成可执行文件做准备。

3.1.2编译的作用:

高级语言是一种人们容易理解和编写的编程语言,它使用类似自然语言的语法和结构。然而,计算机不能直接理解和执行高级语言代码。因此,需要通过编译过程将高级语言代码转换为机器指令,这些指令是计算机可以直接执行的低级指令。

机器指令是计算机硬件能够理解和执行的指令,它们以二进制形式表示,并对应于特定的操作和数据处理。与之对应的是汇编指令,它们以助记符的形式表示机器指令,使得人们更容易理解和编写这些指令。

通过将高级语言源程序转换为机器指令,计算机可以更轻松地理解和执行代码,而且这些指令与汇编指令一一对应。这样的转换过程为后续的汇编过程做好了准备,使得代码可以进一步转换为底层的机器语言,并最终生成可执行文件,使计算机能够正确执行程序。

3.2 在Ubuntu下编译的命令

打开终端,输入cc1 hello.i -o hello.s 或 gcc -S hello.c -o hello.s 

《图3-2-2 Ubuntu下编译gcc》

3.3 Hello的编译结果解析

编译过程是整个过程构建的核心部分,编译成功,源代码会从文本形式转换为机器语言。
下面是hello.s汇编文件内容:

 《图3-3-1 hello.s文件内容》

3.3.1对文件信息的记录

《图3-3-1 hello.s文件内容》

 该代码是汇编文件(.s)部分和文件信息的部分。
.file "hello.c": 此指示符表示当前汇编文件是由名为 "hello.c" 的源文件创建的。 源文件名称可以与调试信息相连接,供调试器使用。
.text: 此指示符定义了代码部分 。 代码部分是程序指令( 机械或汇编)所在的位置。 text部分将包含程序的主要代码 。
. section. rodata: 此指示符定义了只读数据部分。 rodata 部分用于存储程序中使用的字符串常数或其他只读数据 。
.align 8: 此指示符设置数据的排序 。 8表示在这里排列成8字节。 数据对齐是为了提高数据访问效率而在存储器上调整数据布局的工作。
.file "hello.c" 显示源文件的信息, .text 定义了代码部分。 section.rodata 设置了只读数据部分, .align 8 调整数据的排序。 这些切片和对齐设置用于控制组装代码的结构和数据访问的效率。

3.3.2对局部变量的操作

局部变量存储在栈中,当进入函数main的时候,会根据局部变量的需求,在栈上申请一段空间供局部变量使用。当局部变量的生命周期结束后,会在栈上释放。

 《图3-3-2-1 hello.s文件内容》

局部变量操作在main函数内进行。 下面我们来看一下代码块,以说明给定代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值