
大作业
题 目 程序人生-Hello’s P2P
专 业 电子与信息工程学院
学 号 2023111573
班 级 23L0502
学 生 刘沛霖
指 导 教 师 刘宏伟
2024年5月
本研究以典型 C 语言程序hello.c为分析载体,系统阐释程序从源代码生成到进程执行的完整生命周期。通过对预处理、编译、汇编、链接、进程激活及存储寻址等关键环节的深度剖析,揭示计算机系统底层协同机制。实验基于 Ubuntu 22.04 LTS 操作系统平台,综合运用 GCC 工具链、二进制分析工具及动态调试器(GDB),详尽记录程序形态转换的技术细节。重点探讨 ELF 文件格式规范、虚拟地址空间组织策略、动态符号解析机制、进程调度算法及内存分层管理技术,验证现代计算机系统通过分层抽象与资源优化实现高效执行的设计范式,为系统级软件开发与性能调优提供理论支撑与实践路径。
关键词:计算机系统;程序生命周期;ELF格式;进程管理;存储管理;动态链接
(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
目录
第1章 概述
1.1 Hello简介
根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。
- Hello 的 P2P 过程(From Program to Process)
P2P 即程序到进程的转换过程,体现了计算机系统从静态代码到动态执行的核心机制,涉及编译系统、进程管理、内存映射与 CPU 调度等关键环节:
程序(Program)的诞生
用户通过编辑器将代码写入hello.c,形成磁盘上的静态源文件(程序)。该文件需经过编译流程四阶段:
预处理(cpp):展开头文件、宏定义,生成.i文件(如处理#include指令);
编译(gcc):将 C 代码翻译为汇编语言,生成.s文件;
汇编(as):汇编器将汇编代码转换为机器指令,生成.o目标文件;
链接(ld):连接器合并目标文件与标准库,生成可执行程序(如hello),此时程序以二进制形式存储于磁盘,尚未占用内存资源。
进程(Process)的激活
在 Shell 中执行./hello时,操作系统通过以下步骤将程序转换为进程:
进程创建:父进程(Shell)调用fork()系统调用创建子进程,复制自身地址空间;
程序加载:子进程通过execve()系统调用加载hello可执行文件,清空原有地址空间并建立新的虚拟地址空间映射(如代码段、数据段、堆、栈);
内存管理:操作系统通过mmap()将可执行文件内容映射到虚拟内存,同时借助MMU(内存管理单元)完成虚拟地址(VA)到物理地址(PA)的转换,依赖TLB(转换检测缓冲区)、4 级页表和3 级 Cache加速地址翻译,确保程序指令与数据的快速访问;
CPU 调度:进程进入就绪队列,操作系统通过时间片轮转算法为其分配 CPU 资源,使其进入运行态,执行 “取指 - 译码 - 执行” 流水线操作,完成代码逻辑(如输出 “Hello”)。
进程的生命周期
程序执行完毕后,进程进入终止态:操作系统回收其占用的内存(如通过munmap()释放mmap区域)、文件句柄等资源,进程状态变为 “僵尸进程” 直至父进程调用wait()读取其退出状态,最终彻底销毁进程控制块(PCB)。
二、Hello 的 O2O 过程(From Zero-0 to Zero-0)
O2O 体现程序从 “零” 状态启动到资源归零的完整生命周期,涵盖存储初始化、执行期资源占用与最终释放的闭环:
存储层面:磁盘上的hello可执行文件中,未初始化的全局变量(如int x;)对应二进制值为 0 或未定义,称为 “BSS 段”;代码段(.text)和已初始化数据段(.data)则存储明确的指令与数据。
地址空间:程序未加载时,虚拟地址空间尚未创建,VA 与 PA 无映射关系,操作系统通过页表机制为后续加载预留地址空间结构。
执行期非零状态:资源占用的 “有”
程序运行时,操作系统为其分配非零资源:
内存资源:通过mmap分配代码段、数据段、堆、栈的虚拟地址区域,其中堆用于动态内存分配(如malloc),栈用于存储函数调用栈帧;物理内存通过页调度机制(如缺页中断)按需加载到 Cache,提升访问效率。
CPU 资源:进程通过时间片获得 CPU 使用权,执行算术操作(如+、*)、逻辑操作(如&&、|)、控制转移(如if、for)等指令,完成计算任务。
I/O 资源:通过系统调用(如write)操作键盘、显示器等设备,实现输入输出,期间涉及中断处理与 DMA(直接内存访问)技术,减少 CPU 干预。
终止归零状态(Zero-0):资源回收的 “无”
程序执行结束后,操作系统执行零化清理:
内存归零:通过free或自动回收机制释放动态分配的内存(如堆空间),页表条目被删除,VA 与 PA 映射解除,物理内存页可能被写回磁盘(如Pagefile)或标记为空闲;
进程状态归零:进程退出状态(通常为 0)存入 PCB,父进程读取后,内核销毁 PCB,进程标识符(PID)回归可用池,实现 “从进程到无进程” 的状态归零;
I/O 资源归零:关闭打开的文件描述符,释放设备控制权,中断处理程序恢复初始状态,确保设备就绪等待下一次操作。
1.2 环境与工具
列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。
硬件环境:X64 CPU;2.5GHz;16GRAM
软件环境:Windows11;VMware Workstation Pro;Ubuntu 20.24
开发工具:Codeblocks 64位;vi/vim/gedit+gcc;GDB;OBJDUMP;EDB
1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
- hello.i:预处理文件,展开头文件与宏定义,指令:gcc -E hello.c -o hello.i
- hello.s:汇编代码文件,指令:gcc -S hello.i -o hello.s
- hello.o:可重定位目标文件,指令:gcc -c hello.s -o hello.o
- hello:可执行文件,指令:gcc hello.o -o hello
1.4 本章小结
本章概述 Hello 程序的生命周期、实验环境及中间文件,构建从程序到进程的整体认知,为后续章节的深入分析奠定基础。
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
预处理的概念:
程序设计领域中,预处理一般是指在程序源代码被翻译为目标代码的过程中,生成二进制代码之前的过程。
预处理器的作用:
一般由预处理器(preprocessor)对程序源代码文本进行处理,这个过程并不对程序的源代码进行解析,但它把源代码分割或处理成为特定的单位。
2.2在Ubuntu下预处理的命令
命令:gcc -E hello.c -o hello.i

2.3 Hello的预处理结果解析

预处理器将头文件替换为了对本地文件的引用,增加了大段头文件本身的内容,不会对头文件中的内容做任何计算或转换,只是简单地复制和替换。
2.4 本章小结
本章讲述了编译过程的第一步预处理,介绍了预处理的概念和作用,并通过实际操作生成了hello.i文件,通过对比分析清楚了预处理的作用与原理。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
编译阶段将预处理后的 C 代码(hello.i)转换为汇编代码(hello.s),核心步骤包括:
词法分析:分解为 token(如关键字、操作符);
语法分析:构建抽象语法树(AST),检查语法正确性;
语义分析:类型检查、作用域解析;
代码生成:生成目标架构的汇编指令;
代码优化:常量传播、死代码消除等。
注意:这儿的编译是指从 .i 到 .s 即预处理后的文件到生成汇编语言程序
3.2 在Ubuntu下编译的命令
命令:gcc -S hello.i -o hello.s

3.3 Hello的编译结果解析
转载自CSDN-专业IT技术社区



