哈工大计算机系统大作业----程序人生

摘  要

本研究聚焦于解释C语言程序如何从源代码转换为可执行文件。在Linux系统下,以简单的C语言文件hello.c为对象,全面深入地探讨了该程序的完整生命周期。从最初的原始程序出发,系统性地研究了编译、链接、加载、运行、终止和回收等关键阶段,以揭示hello.c文件整个的生命过程。此文不仅理论上探讨了这些工具的原理和方法,还实际演示了它们的操作和结果,阐述了计算机系统的工作原理和体系结构,意在助读者深入理解和掌握C语言程序的编译和执行过程,赋予冰冷的指令以浪漫的色彩。

关键词:计算机系统;C语言;程序生命周期;底层原理

目  录

第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简介

P2P:即From Program to Process。指从hello.cProgram)变为运行时进程(Process)。要让hello.c这个C语言程序运行起来,需要先把它变成可执行文件,这个变化过程有四个阶段:预处理,编译,汇编,链接,完成后就得到了可执行文件,然后就可以在shell中执行它,shell会给它分配进程空间。

020:即From Zero-0 to Zero-0。指最初内存并无hello文件的相关内容,shell用execve函数启动hello程序,把虚拟内存对应到物理内存,并从程序入口开始加载和运行,进入main函数执行目标代码,程序结束后,shell父进程回收hello进程,内核删除hello文件相关的数据结构。

1.2 环境与工具

硬件环境:

处理器:12th Gen Intel(R) Core(TM)i5-12500H   2.50 GHz

机带RAM:16.0GB

系统类型:64位操作系统,基于x64的处理器

软件环境:Windows11 64位,VMwareUbuntu 20.04 LTS

开发与调试工具:Visual Studio 2021 64位;vim objump edb gcc readelf等工具

1.3 中间结果

hello.i         预处理后得到的文本文件

hello.s         编译后得到的汇编语言文件

hello.o        汇编后得到的可重定位目标文件

hello.elf      用readelf读取hello.o得到的ELF格式信息

hello.asm      反汇编hello.o得到的反汇编文件

hello1.elf       由hello可执行文件生成的.elf文件

hello1.asm     反汇编hello可执行文件得到的反汇编文件

1.4 本章小结

本章首先介绍了hello的P2P,020流程,包括流程的设计思路和实现方法;然后,详细说明了本实验所需的硬件配置、软件平台、开发工具以及本实验生成的各个中间结果文件的名称和功能。

第2章 预处理

2.1 预处理的概念与作用

2.1.1预处理的概念

预处理步骤是指预处理器在程序运行前,对源文件进行简单加工的过程。预处理过程主要进行代码文本的替换工作,用于处理以#开头的指令,还会删除程序中的注释和多余的空白字符。预处理指令可以简单理解为#开头的正确指令,它们会被转换为实际代码中的内容(替换)。

2.1.2预处理的作用

预处理过程中并不直接解析程序源代码的内容,而是对源代码进行相应的分割、处理和替换,主要有以下作用:

头文件包含:将所包含头文件的指令替代。

宏定义:将宏定义替换为实际代码中的内容。

条件编译:根据条件判断是否编译某段代码。

其他:如注释删除等。

简单来说,预处理是一个文本插入与替换的过程预处理器

2.2在Ubuntu下预处理的命令

预处理的命令:gcc -E hello.c -o hello.i

2.3 Hello的预处理结果解析

在Linux下打开hello.i文件,我们对比了源程序和预处理后的程序。结果显示,除了预处理指令被扩展成了3000行之外,源程序的其他部分都保持不变,说明.c文件的确是被修改过了。

在代码中, main 函数之前的大段代码源自于头文件 <stdio.h>, <unistd.h>, <stdlib.h> 的展开。下面以 stdio.h 的展开为例进行说明:

在预处理过程中,#include 指令的作用是将指定的头文件内容包含到源文件中。<stdio.h> 是标准输入输出库的头文件,它包含了用于读写文件、标准输入输出的函数原型和宏定义等内容。

当预处理器遇到 #include<stdio.h> 时,它会在系统的头文件路径下查找 stdio.h 文件(一般位于 /usr/include 目录下),然后将 stdio.h 文件中的内容复制到源文件中。stdio.h 文件中可能还有其他的 #include 指令,比如 #include<stddef.h> 或 #include<features.h> 等,这些头文件也会被递归地展开并包含到源文件中。

预处理器不会对头文件中的内容进行任何计算或转换,只是简单地进行复制和替换。

预处理器的作用:预处理器在编译过程中首先处理 #include 指令,它通过在系统的头文件路径中查找指定的头文件并将其内容包含到源文件中来展开这些指令。

头文件的作用:头文件通常包含函数原型、宏定义和其他必要的声明,这些声明允许在多个源文件中共享代码和定义。

递归展开:当 stdio.h 包含其他头文件时,比如 stddef.h 或 features.h,这些头文件也会被递归地展开,确保所有必要的定义和声明都包含在最终的源文件中。

简单替换:预处理器只是简单地复制和替换头文件内容,不进行任何形式的计算或逻辑操作。

通过这种方式,所有相关的头文件内容都被包含到源文件中,从而使编译器在后续的编译阶段可以正确解析和编译代码。

2.4 本章小结

本章讲述了在linux环境中,如何用命令对C语言程序进行预处理,以及预处理的含义和作用。然后用一个简单的hello程序演示了从hello.c到hello.i的过程,并用具体的代码分析了预处理后的结果。通过分析,我们可以发现预处理后的文件hello.i包含了标准输入输出库stdio.h的内容,以及一些宏和常量的定义,还有一些行号信息和条件编译指令。

第3章 编译

3.1 编译的概念与作用

3.1.1编译的概念

计算机程序编译的概念是指将用高级程序设计语言书写的源程序,翻译成等价的汇编语言格式程序的翻译过程。

3.1.2编译的作用

计算机程序编译的作用是使高级语言源程序变为汇编语言,提高编程效率和可移植性。计算机程序编译的基本流程包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段。

3.2 在Ubuntu下编译的命令

编译的命令:gcc -S hello.i -o hello.s

3.3 Hello的编译结果解析

3.3.1汇编初始部分

在main函数前有一部分字段展示了节名称:

.file              声明出源文件

.text              表示代码节

.section   .rodata   表示只读数据段

.align              声明对指令或者数据的存放地址进行对齐的方式

.string              声明一个字符串

.globl              声明全局变量

.type               声明一个符号的类型

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值