HIT-ICS 2025春计算机系统大作业 程序人生-Hello’s P2P

摘  要

本报告通过分析hello程序从hello.c源代码到进程终止的完整生命周期,系统阐述了计算机系统的多层次协作机制。首先,通过预处理、编译、汇编与链接阶段,将C语言源代码转换为可执行文件;其次,结合进程管理、存储管理及输入输出管理,深入探讨了进程创建、地址空间转换、动态链接、信号处理等核心机制。实验部分利用GCC、GDB、ReadELF等工具,验证了逻辑地址到物理地址的页式转换、动态链接的PLT/GOT机制、异常处理与终端I/O交互等关键技术。本报告通过理论与实践结合,揭示了操作系统、编译器与硬件的协同设计原理,为深入理解计算机系统提供了完整案例。

关键词:预处理;编译;动态链接;进程管理;存储管理;输入输出管理

目  录

第1章 概述... - 4 -

1.1 Hello简介... - 4 -

1.2 环境与工具... - 4 -

1.3 中间结果... - 4 -

1.4 本章小结... - 5 -

第2章 预处理... - 6 -

2.1 预处理的概念与作用... - 6 -

2.2在Ubuntu下预处理的命令... - 6 -

2.3 Hello的预处理结果解析... - 6 -

2.4 本章小结... - 7 -

第3章 编译... - 8 -

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

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

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

  3.3.1 数据类型与变量... - 8 -

  3.3.2 赋值与表达式... - 9 -

  3.3.3 算术与逻辑操作... - 10 -

  3.3.4 控制转移... - 10 -

  3.3.5 函数操作... - 12 -

  3.3.6 指针与数组操作... - 12 -

  3.3.7 其他操作... - 13 -

3.4 本章小结... - 13 -

第4章 汇编... - 14 -

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

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

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

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

  4.4.1 反汇编与汇编代码对照分析... - 18 -

  4.4.2 机器语言与汇编语言的映射特点... - 20 -

  4.4.3 关键结论... - 21 -

4.5 本章小结... - 21 -

第5章 链接... - 22 -

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

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

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

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

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

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

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

5.8 本章小结... - 35 -

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

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

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

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

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

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

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

  6.6.1 异常类型与信号生成... - 37 -

  6.6.2 键盘操作与信号响应... - 38 -

6.7本章小结... - 42 -

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

7.1 hello的存储器地址空间... - 43 -

7.2 Intel逻辑地址到线性地址的变换-段式管理... - 44 -

7.3 Hello的线性地址到物理地址的变换-页式管理... - 45 -

7.4 TLB与四级页表支持下的VA到PA的变换... - 45 -

7.5 三级Cache支持下的物理内存访问... - 46 -

7.6 hello进程fork时的内存映射... - 46 -

7.7 hello进程execve时的内存映射... - 47 -

7.8 缺页故障与缺页中断处理... - 48 -

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

7.10本章小结... - 49 -

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

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

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

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

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

8.5本章小结... - 53 -

结论... - 54 -

附件... - 56 -

参考文献... - 57 -

第1章 概述

1.1 Hello简介

Hello程序的完整生命周期可概括为P2P(Program to Process)和020(Zero to Zero)两个核心过程:

1. P2P(从程序到进程)

预处理(Preprocessing):hello.c通过宏替换、头文件展开和条件编译生成hello.i,消除注释与冗余信息。

编译(Compilation):将hello.i转换为汇编代码hello.s,完成语法语义分析并生成机器无关的低级表示。

汇编(Assembly):将hello.s翻译为机器指令,生成可重定位目标文件hello.o,包含二进制代码和符号表。

链接(Linking):将hello.o与C标准库(如libc.so)动态链接,解析外部符号(如printf),生成可执行文件hello。

进程加载(Process Loading):Shell通过fork创建子进程,execve将hello加载至内存,形成独立进程空间,CPU执行指令直至终止。

2. 020(从零到零)

进程执行结束后,操作系统回收其占用的内存、文件描述符等资源,进程控制块(PCB)被销毁,状态回归初始“零”状态。

1.2 环境与工具

硬件环境:

处理器 13th Gen Intel(R) Core(TM) i7-13700H   2.40 GHz

机带 RAM 16.0 GB (15.7 GB 可用)

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

软件环境:Windows11 64位,VMwareUbuntu

开发与调试工具:Visual Studiovim objump edb gcc readelf等工具

1.3 中间结果

表1-1 中间结果

文件名称

功能

hello.c

源程序

hello.i

预处理后得到的文本文件

hello.s

编译后得到的汇编语言文件

hello.o

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

hello.elf

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

hello.asm

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

hello

链接后得到的可执行文件

hello1.elf

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

hello1.asm

反汇编hello得到的反汇编文件

1.4 本章小结

本章概述了Hello程序从源代码到进程的完整生命周期(P2P)及其终止后的资源回收(020),明确了预处理、编译、汇编、链接与进程加载的关键步骤。同时,列出了实验所需的软硬件环境与工具,并展示了生成的中间结果文件。后续章节将基于此框架,逐步深入分析每个环节的实现细节。

第2章 预处理

2.1 预处理的概念与作用

预处理是C程序编译过程中的第一阶段,其核心任务是对源代码进行文本级别的处理,为后续的编译阶段提供“纯净”的输入。具体作用包括:

1. 宏替换:处理#define定义的宏,将其替换为实际值或代码片段。

2. 头文件展开:递归展开#include指令,将头文件内容插入源文件中。

3. 条件编译:根据#ifdef、#ifndef等指令选择性保留或删除代码块。

4. 删除注释:移除所有单行(//)和多行注释(/* ... */)。

5. 添加行号标记:插入#line指令,便于编译器报错时定位原始代码位置。

2.2在Ubuntu下预处理的命令

使用的命令是:gcc -E hello.c -o hello.i

同时,通过ls命令验证文件的存在。

图2-1 预处理

如图2-1所示, hello.i出现在了目录下。

2.3 Hello的预处理结果解析

打开hello.i文件,分析预处理后的代码变化:

图2-2 hello.i

1. 头文件展开

原始代码:

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

预处理结果:

#include指令被替换为对应头文件的全部内容。例如,stdio.h展开后包含printf、getchar等函数的声明,以及FILE、size_t等类型的定义,代码量从几行扩展至近千行。

2. 宏与条件编译处理

原始代码中未定义自定义宏,但标准库中的宏(如NULL)被展开为((void*)0)。

条件编译指令(如#ifdef)未被使用,因此预处理后无变化。

3. 注释删除与代码格式

所有注释(如// 秒数=手机号%5)被完全删除。

代码保留原始缩进结构,但行号因头文件插入而大幅增加。

2.4 本章小结

预处理阶段通过宏替换、头文件展开和注释删除,将原始的hello.c转换为仅包含有效代码的hello.i。此阶段未修改程序的逻辑结构,但为后续编译提供了标准化的输入。生成的hello.i文件是后续编译阶段的起点,其内容直接决定了汇编代码的生成方式。

第3章 编译

3.1 编译的概念与作用

编译是将预处理后的高级语言代码转换为目标机器架构相关的汇编语言代码的过程。其主要作用包括:

1. 语法与语义检查:验证代码是否符合C语言规范,检测类型错误、未声明变量等问题。

2. 中间代码生成与优化:生成抽象语法树(AST)或中间表示(IR),并进行初步优化(如常量折叠、死代码删除)。

3. 汇编代码生成:将优化后的中间代码转换为特定架构(如x86-64)的汇编指令,为后续汇编阶段提供输入。

hello程序中,编译阶段将hello.i文件转换为hello.s,为机器码生成奠定基础。

3.2 在Ubuntu下编译的命令

使用的命令是:gcc -S hello.i -o hello.s

图3-1 编译

如图3-1所示,hello.s出现在了目录下。

3.3 Hello的编译结果解析

3.3.1 数据类型与变量

1. 局部变量

C代码:int i;(未赋初值)

汇编实现:

图3-2 局部变量

变量i存储在栈帧偏移-4(%rbp)处,初始值通过movl $0显式赋0。

subq $32, %rsp为main函数分配32字节栈空间,包含局部变量和参数对齐。

2. 字符串常量

C代码:

"用法: Hello 学号 姓名 手机号 秒数!"

"Hello %s %s %s\n"

汇编实现:

图3-3 字符串常量

字符串常量存储在只读数据段(.rodata),通过标签(如.LC0)引用。编译器将字符串中的汉字编码成UTF-8格式,一个汉字占3个字节。字节之间用\分割开。

3.3.2 赋值与表达式

1. 赋值操作</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值