HIT计算机系统课程报告-程序人生-Hello’s P2P

计算机系统

大作业

题 目 ++程序人生++ ++-Hello's P2P++

专 业 ++计算学部++

学   号 ++2023113173++

班   级 ++23L0517++

学 生 ++郭卓远++

指 导 教 师 ++吴锐++

计算机科学与技术学院

2025 年5月

摘 要

摘要是论文内容的高度概括,应具有独立性和自含性,即不阅读论文的全文,就能获得必要的信息。摘要应包括本论文的目的、主要内容、方法、成果及其理论与实际意义。摘要中不宜使用公式、结构式、图表和非公知公用的符号与术语,不标注引用文献编号,同时避免将摘要写成目录式的内容介绍。

**关键词:**关键词1;关键词2;......;

(摘要0分,缺失-1分, 根据内容精彩称都酌情加分0-1分

本文以经典的Hello程序为例,全面分析了其在计算机系统中的完整生命周期,从源代码到可执行文件的生成过程,再到进程的执行与终止。通过深入研究预处理、编译、汇编、链接、进程管理、存储管理及I/O管理等关键环节,揭示了计算机系统各层次间的协同工作机制。

在预处理阶段,头文件包含、宏替换和条件编译等操作将源代码转换为适合编译的中间形式。编译阶段将高级语言代码翻译为汇编指令,同时进行代码优化。汇编器进一步生成机器码目标文件,而链接器则完成符号解析和重定位,生成可执行文件。

程序运行时,操作系统通过fork和execve机制创建进程,并为其分配独立的虚拟地址空间。内存管理单元(MMU)通过段式与页式机制实现地址转换,TLB和缓存系统显著提升了访问效率。进程执行过程中,CPU时间片调度、异常处理和信号机制确保了程序的并发执行与资源管理。

本文还探讨了动态链接、写时复制(COW)、缺页处理等关键技术,并结合实际调试工具(如GDB、objdump)对程序行为进行了分析。通过Hello程序这一简单案例,展示了现代计算机系统在资源隔离、并发控制和安全保障方面的核心设计思想。

**关键词:**计算机系统;进程管理;存储管理;链接与加载;异常处理

目 录

[第1章 概述............................................................................................................. - 4 -](#第1章 概述............................................................................................................. - 4 -)

[1.1 Hello简介...................................................................................................... - 4 -](#1.1 Hello简介...................................................................................................... - 4 -)

[1.2 环境与工具..................................................................................................... - 4 -](#1.2 环境与工具..................................................................................................... - 4 -)

[1.3 中间结果......................................................................................................... - 4 -](#1.3 中间结果......................................................................................................... - 4 -)

[1.4 本章小结......................................................................................................... - 4 -](#1.4 本章小结......................................................................................................... - 4 -)

[第2章 预处理......................................................................................................... - 5 -](#第2章 预处理......................................................................................................... - 5 -)

[2.1 预处理的概念与作用..................................................................................... - 5 -](#2.1 预处理的概念与作用..................................................................................... - 5 -)

[2.2在Ubuntu下预处理的命令.......................................................................... - 5 -](#2.2在Ubuntu下预处理的命令.......................................................................... - 5 -)

[2.3 Hello的预处理结果解析.............................................................................. - 5 -](#2.3 Hello的预处理结果解析.............................................................................. - 5 -)

[2.4 本章小结......................................................................................................... - 5 -](#2.4 本章小结......................................................................................................... - 5 -)

[第3章 编译............................................................................................................. - 6 -](#第3章 编译............................................................................................................. - 6 -)

[3.1 编译的概念与作用......................................................................................... - 6 -](#3.1 编译的概念与作用......................................................................................... - 6 -)

[3.2 在Ubuntu下编译的命令............................................................................. - 6 -](#3.2 在Ubuntu下编译的命令............................................................................. - 6 -)

[3.3 Hello的编译结果解析.................................................................................. - 6 -](#3.3 Hello的编译结果解析.................................................................................. - 6 -)

[3.4 本章小结......................................................................................................... - 6 -](#3.4 本章小结......................................................................................................... - 6 -)

[第4章 汇编............................................................................................................. - 7 -](#第4章 汇编............................................................................................................. - 7 -)

[4.1 汇编的概念与作用......................................................................................... - 7 -](#4.1 汇编的概念与作用......................................................................................... - 7 -)

[4.2 在Ubuntu下汇编的命令............................................................................. - 7 -](#4.2 在Ubuntu下汇编的命令............................................................................. - 7 -)

[4.3 可重定位目标elf格式................................................................................. - 7 -](#4.3 可重定位目标elf格式................................................................................. - 7 -)

[4.4 Hello.o的结果解析...................................................................................... - 7 -](#4.4 Hello.o的结果解析...................................................................................... - 7 -)

[4.5 本章小结......................................................................................................... - 7 -](#4.5 本章小结......................................................................................................... - 7 -)

[第5章 链接............................................................................................................. - 8 -](#第5章 链接............................................................................................................. - 8 -)

[5.1 链接的概念与作用......................................................................................... - 8 -](#5.1 链接的概念与作用......................................................................................... - 8 -)

[5.2 在Ubuntu下链接的命令............................................................................. - 8 -](#5.2 在Ubuntu下链接的命令............................................................................. - 8 -)

[5.3 可执行目标文件hello的格式.................................................................... - 8 -](#5.3 可执行目标文件hello的格式.................................................................... - 8 -)

[5.4 hello的虚拟地址空间.................................................................................. - 8 -](#5.4 hello的虚拟地址空间.................................................................................. - 8 -)

[5.5 链接的重定位过程分析................................................................................. - 8 -](#5.5 链接的重定位过程分析................................................................................. - 8 -)

[5.6 hello的执行流程.......................................................................................... - 8 -](#5.6 hello的执行流程.......................................................................................... - 8 -)

[5.7 Hello的动态链接分析.................................................................................. - 8 -](#5.7 Hello的动态链接分析.................................................................................. - 8 -)

[5.8 本章小结......................................................................................................... - 9 -](#5.8 本章小结......................................................................................................... - 9 -)

[第6章 hello进程管理................................................................................... - 10 -](#第6章 hello进程管理................................................................................... - 10 -)

[6.1 进程的概念与作用....................................................................................... - 10 -](#6.1 进程的概念与作用....................................................................................... - 10 -)

[6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -](#6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -)

[6.3 Hello的fork进程创建过程..................................................................... - 10 -](#6.3 Hello的fork进程创建过程..................................................................... - 10 -)

[6.4 Hello的execve过程................................................................................. - 10 -](#6.4 Hello的execve过程................................................................................. - 10 -)

[6.5 Hello的进程执行........................................................................................ - 10 -](#6.5 Hello的进程执行........................................................................................ - 10 -)

[6.6 hello的异常与信号处理............................................................................ - 10 -](#6.6 hello的异常与信号处理............................................................................ - 10 -)

[6.7本章小结....................................................................................................... - 10 -](#6.7本章小结....................................................................................................... - 10 -)

[第7章 hello的存储管理................................................................................ - 11 -](#第7章 hello的存储管理................................................................................ - 11 -)

[7.1 hello的存储器地址空间............................................................................ - 11 -](#7.1 hello的存储器地址空间............................................................................ - 11 -)

[7.2 Intel逻辑地址到线性地址的变换-段式管理............................................ - 11 -](#7.2 Intel逻辑地址到线性地址的变换-段式管理............................................ - 11 -)

[7.3 Hello的线性地址到物理地址的变换-页式管理....................................... - 11 -](#7.3 Hello的线性地址到物理地址的变换-页式管理....................................... - 11 -)

[7.4 TLB与四级页表支持下的VA到PA的变换............................................. - 11 -](#7.4 TLB与四级页表支持下的VA到PA的变换............................................. - 11 -)

[7.5 三级Cache支持下的物理内存访问.......................................................... - 11 -](#7.5 三级Cache支持下的物理内存访问.......................................................... - 11 -)

[7.6 hello进程fork时的内存映射.................................................................. - 11 -](#7.6 hello进程fork时的内存映射.................................................................. - 11 -)

[7.7 hello进程execve时的内存映射.............................................................. - 11 -](#7.7 hello进程execve时的内存映射.............................................................. - 11 -)

[7.8 缺页故障与缺页中断处理........................................................................... - 11 -](#7.8 缺页故障与缺页中断处理........................................................................... - 11 -)

[7.9动态存储分配管理....................................................................................... - 11 -](#7.9动态存储分配管理....................................................................................... - 11 -)

[7.10本章小结..................................................................................................... - 12 -](#7.10本章小结..................................................................................................... - 12 -)

[第8章 hello的IO管理................................................................................. - 13 -](#第8章 hello的IO管理................................................................................. - 13 -)

[8.1 Linux的IO设备管理方法.......................................................................... - 13 -](#8.1 Linux的IO设备管理方法.......................................................................... - 13 -)

[8.2 简述Unix IO接口及其函数....................................................................... - 13 -](#8.2 简述Unix IO接口及其函数....................................................................... - 13 -)

[8.3 printf的实现分析........................................................................................ - 13 -](#8.3 printf的实现分析........................................................................................ - 13 -)

[8.4 getchar的实现分析.................................................................................... - 13 -](#8.4 getchar的实现分析.................................................................................... - 13 -)

[8.5本章小结....................................................................................................... - 13 -](#8.5本章小结....................................................................................................... - 13 -)

[结论......................................................................................................................... - 14 -](#结论......................................................................................................................... - 14 -)

[附件......................................................................................................................... - 15 -](#附件......................................................................................................................... - 15 -)

[参考文献................................................................................................................. - 16 -](#参考文献................................................................................................................. - 16 -)

第1章 概述

1.1 Hello简介

程序员通过编辑器将Hello程序以源代码(hello.c)的形式输入计算机,这是程序的静态表示。随后,这个源代码经历了完整的编译链接过程:预处理器扩展宏和包含文件,编译器将C代码转换为汇编语言,汇编器将汇编代码转换为机器码生成目标文件,最后链接器将目标文件与库函数结合生成可执行文件。

当用户执行这个程序时,操作系统通过shell(Bash)接收执行请求,随后为程序创建进程(Process)。这个转变包括操作系统调用fork()创建新进程,execve()加载程序,mmap()映射内存空间。操作系统为进程分配CPU时间片,使其得以执行。内存管理单元(MMU)负责虚拟地址(VA)到物理地址(PA)的转换,通过TLB、多级页表、多级缓存和页面文件等机制优化访问性能。

进程执行时,CPU按照取指令、译码、执行的流水线模式运行。同时,操作系统的I/O管理和信号处理机制确保程序能够响应键盘输入并在屏幕上显示输出。当程序执行完毕后,操作系统负责回收资源,终止进程。

1.2 环境与工具

操作系统: Ubuntu 24.10 amd64

编译器: gcc 9.4.0

调试与分析工具:

GDB 9.2 - 用于程序调试

objdump 2.34 - 用于分析目标文件和可执行文件

1.3 中间结果

hello.i - 预处理后的文件

作用:包含了展开后的所有宏和包含文件的源代码

hello.s - 汇编语言文件

作用:包含了编译器生成的汇编代码

hello.o - 目标文件

作用:包含了机器码但尚未链接的中间文件

hello - 可执行文件

作用:最终可以直接运行的程序

hello.objdump - 反汇编结果文件

作用:显示可执行文件的详细汇编代码和结构

hello.nm - 符号表文件

作用:列出可执行文件中的所有符号及其地址

hello.strace - 系统调用跟踪文件

作用:记录程序执行过程中的所有系统调用

hello.ltrace - 库函数调用跟踪文件

作用:记录程序执行过程中的库函数调用

1.4 本章小结

本章概述了Hello程序的基本概念和完整生命周期,从源代码编写到编译链接,再到进程的创建、执行和终止。通过Hello程序,我们可以直观地了解计算机系统中程序执行的全过程,体会从静态程序到动态进程的转变。

第2章 预处理

2.1 预处理的概念与作用

预处理是编译过程中的第一个阶段,主要由C预处理器(CPP)负责执行。预处理的主要作用是对源代码进行文本处理,为后续的编译做准备。预处理过程包括以下核心功能:

  1. 头文件包含:将#include指令指定的头文件内容插入到源代码中。
  2. 宏替换:将源代码中的宏定义(#define)替换为其实际内容。
  3. 条件编译:根据预处理指令(#ifdef, #ifndef, #if, #else, #elif, #endif)选择性地包含或排除代码段。
  4. 注释移除:删除源代码中的所有注释。
  5. 特殊符号处理:处理特殊符号,如连接符(##)和字符串化操作符(#)。
  6. 行号标记:插入行号标记,以便编译器在报错时能够准确指出错误位置。

预处理的作用在于简化程序编写,增强代码的可移植性和可维护性,同时为编译器提供统一的、无宏和无注释的源代码文本。

2.2在Ubuntu下预处理的命令

2.3 Hello的预处理结果解析

预处理后的hello.i文件包含了原始hello.c文件的所有代码,以及通过#include指令引入的所有头文件内容。预处理器在文件中插入了形如# 行号 "文件名"的标记,用于在编译过程中跟踪代码的原始位置。所有在hello.c中通过#include引入的头文件都被完整地展开并插入到预处理后的文件中,所有宏定义都被替换为其实际值,所有注释都被删除,头文件中的条件编译指令(如#ifdef, #ifndef)已经被处理,只保留了符合条件的代码部分,预处理过程极大地扩展了源代码,将所有必要的声明和定义都包含进来,为后续的编译过程提供了完整的上下文。

2.4 本章小结

本章详细介绍了C语言预处理的概念、作用和在Linux系统下的实现方式。我们通过对hello.c文件进行预处理,生成了hello.i中间文件,并对其内容进行了分析。

预处理作为编译过程的第一步,完成了头文件包含、宏替换、条件编译处理和注释移除等重要任务。预处理后的文件包含了程序运行所需的所有声明和定义,为后续的编译、汇编和链接过程奠定了基础。
第3章 编译

3.1 编译的概念与作用

编译是将预处理后.i文件转换为汇编语言代码.s文件的过程。在整个程序生成流程中,编译是连接高级语言与底层机器语言的关键环节。编译器在这一阶段完成了这些任务:

词法分析:将源代码分解为标记(tokens),如关键字、标识符、运算符和常量。

语法分析:根据语言的语法规则,将标记序列组织成语法树(parse tree),检查程序的语法结构是否正确。

语义分析:检查程序的语义是否正确,包括类型检查、变量声明检查等。

中间代码生成:将语法树转换为中间表示形式(IR),便于后续优化。

代码优化:对中间代码进行优化,如消除冗余计算、常量折叠、循环优化等,以提高程序执行效率。

目标代码生成:将优化后的中间代码转换为目标机器的汇编语言代码。

编译的核心作用是将人类容易理解的高级语言代码转换为更接近计算机硬件的低级代码,同时确保转换过程中保持程序的语义不变。编译器还负责进行代码优化,提高程序的运行效率和资源使用率。

3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果解析

3.3.1 常量

以下为字符串常量LC0与LC1,存储于只读数据段。

3.3.2 变量

3.3.2.1 全局变量:无

3.3.2.2 局部变量:%edi: 存储第一个参数(argc)

%rsi: 存储第二个参数(argv)

%rbx: 保存argv指针

%ebp: 用作循环计数器

%eax: 用作返回值

3.3.2.3 静态变量:无

3.3.3 表达式与操作

3.3.3.1 赋值操作:mov指令进行赋值

3.3.3.2 算数操作:加法用addl,减法使用subq,如图调节栈指针

3.3.3.3 逻辑/位操作:cmpl进行比较

3.3.3.4 关系操作:jne .L6 如果不等于则跳转,jg .L7 如果大于则跳转

3.3.3.5 数组/指针操作:通过基址加偏移访问数组:

3.3.3.6 类型转换:strtol调用将字符串转换为长整型

3.3.4 控制转移:包括条件分支,循环:

cmpl $5, %edi + jne .L6 相当于if(argc != 5);

cmpl $9, %ebp + jg .L7 相当于if(counter > 9);

.L2标签开始循环,jmp .L2 实现循环跳回,addl $1, %ebp 循环计数器递增

3.3.5 函数操作

3.3.5.1 传参:%edi第一个参数,%esi第二个参数,%edx第三个参数,%rcx第四个参数,%r8第五个参数

3.3.5.2 局部变量:通过栈空间和寄存器保存局部变量,pushq %rbp 和 pushq %rbx 保存寄存器

3.4 本章小结

介绍了将预处理后的C源代码转换为x86-64汇编代码的过程。通过分析Hello程序的编译结果,深入了解了高级语言结构如何映射到底层汇编指令。

编译器在这一阶段完成了词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等任务。这些步骤共同将人类易读的高级语言代码转换为更接近计算机硬件的低级汇编代码。

通过分析Hello程序的汇编代码,我们详细了解了x86-64体系结构下的函数调用约定、参数传递机制、整数运算、条件判断、循环结构、字符串处理、栈帧管理、指针操作和函数返回值处理等关键概念。这些都是理解计算机系统底层工作机制的重要基础。
第4章 汇编

4.1 汇编的概念与作用

汇编是将汇编语言(.s文件)转换为机器语言(.o文件)的过程。这一阶段的主要作用包括将助记符形式的汇编指令转换为二进制机器码,解析符号引用,生成重定位条目,生成可重定位目标文件(ELF格式),保留调试信息和符号表供后续链接使用。在Hello程序的生命周期中,汇编阶段是连接高级语言与机器语言的关键桥梁,它确定了程序的底层表示形式

4.2 在Ubuntu下汇编的命令

4.3 可重定位目标elf格式

分析hello.o的ELF格式,用readelf等列出其各节的基本信息,特别是重定位项目分析。

文件头:

程序头表:

节表:

重定位节:

符号表:

4.4 Hello.o的结果解析

使用objdump -d -r hello.o:

可以看到每行末尾的指令基本相同,但前面都会有一行十六进制编码,hello.s是由汇编语言组成的,相对于计算机能识别的机器级指令,汇编代码仍是抽象语言;而反汇编得到的代码不仅仅有汇编代码,还有机器语言代码。机器语言代码是计算机可识别执行的,是一种纯粹的二进制编码。

在分支转移时,.s文件会跳转到如.L7的代码字段,而在反汇编中则会直接跳转到所指定的代码地址。

4.5 本章小结

本章通过分析hello.o的ELF格式和反汇编代码,深入研究了汇编阶段的工作机制和输出结果。关键发现有:

  1. 汇编阶段将助记符转换为机器码,但保留重定位信息
  2. ELF格式包含多个节,.text节存放代码,.rela.text节存放重定位信息
  3. 机器语言与汇编语言的映射关系清晰,但地址引用需要链接阶段解决
  4. 函数调用和分支转移在目标文件中使用相对地址或占位符
  5. 可重定位目标文件为链接器提供了必要的信息以生成可执行文件
    第5章 链接

5.1 链接的概念与作用

链接是将一个或多个可重定位目标文件(.o)合并生成可执行文件的过程,其主要作用包括:

  1. 符号解析:将每个符号引用与符号定义关联起来
  2. 重定位:将符号定义与内存位置关联,并修改所有对这些符号的引用
  3. 合并输入文件:将不同目标文件的节合并为可执行文件的段
  4. 解析外部依赖:处理程序使用的外部库函数和变量

在Hello程序的生命周期中,链接阶段解决了地址空间分配和外部引用问题,使程序能够被加载执行。

注意:这儿的链接是指从 hello.o 到hello生成过程。

    1. 在Ubuntu下链接的命令

使用ld的链接命令,应截图,展示汇编过程! 注意不只连接hello.o文件

    1. 可执行目标文件hello的格式

分析hello的ELF格式,用readelf等列出其各段的基本信息,包括各段的起始地址,大小等信息。

ELF头:

节头:

程序头:

    1. hello的虚拟地址空间

使用gdb/edb加载hello,查看本进程的虚拟地址空间各段信息,并与5.3对照分析说明。

只读代码段(0x400000-0x401000)对应ELF的LOAD段(Flags=R E)

可写数据段(0x403000-0x404000)对应ELF的第二个LOAD段

动态链接库映射到高地址空间

    1. 链接的重定位过程分析

objdump -d -r hello 分析hello与hello.o的不同,说明链接的过程。

结合hello.o的重定位项目,分析hello中对其怎么重定位的。

hello.o的地址空间从0开始相对地址,而hello的地址空间为实际的虚拟内存地址;hello.o的外部函数调用使用占位符+重定位条目,hello解析为实际地址;数据引用方面hello.o使用0偏移+重定位条目,hello解析为实际数据段地址;hello.o按节(section)组织,hello按段(segment)组织,节被合并到可执行段。

重定位:

当链接器处理函数调用时,比如对puts的调用,目标文件中只保留了一个空的操作数和一个重定位条目。链接器需要计算puts函数在内存中的实际位置,并根据调用指令的地址计算出正确的相对偏移量。

对于数据访问同样。当程序引用字符串常量时,链接器会确定该字符串最终所在的只读数据段地址,并生成合适的相对寻址指令。这种相对寻址方式使得代码可以独立于加载地址运行,为地址空间布局随机化(ASLR)等安全特性奠定了基础。

    1. hello的执行流程

使用gdb/edb执行hello,说明从加载hello到_start,到call main,以及程序终止的所有过程(主要函数)。请列出其调用与跳转的各个子程序名或程序地址。

  1. _start
  2. __libc_start_main
  3. main
  4. puts/printf
  5. sleep
  6. getchar
  7. exit

关键函数调用序列:

_start (0x4010f0)

→ __libc_start_main (0x7ffff7de80b0)

→ main (0x401152)

→ puts@plt (0x400040)

→ sleep@plt (0x400050)

→ getchar@plt (0x400060)

→ exit (0x7ffff7de9e60)

    1. Hello的动态链接分析

分析hello程序的动态链接项目,通过edb/gdb调试,分析在动态链接前后,这些项目的内容变化。要截图标识说明。

初始时,GOT条目指向PLT中的解析代码,第一次调用函数后,动态链接器解析实际地址并更新GOT,后续调用直接通过GOT跳转到目标函数。

5.8 本章小结

本章通过分析链接过程和可执行文件hello,深入研究了链接器的工作机制和动态链接原理。关键发现包括:

  1. 链接阶段合并多个目标文件并解析外部依赖
  2. 可执行文件具有完整的虚拟地址空间布局
  3. 重定位过程将符号引用绑定到实际地址
  4. 程序执行通过_start开始,经过一系列初始化后进入main函数
  5. 动态链接实现了库函数的延迟绑定,提高了加载效率

通过本章分析,我们理解了程序从目标文件到可执行文件的转换过程,以及程序加载执行的完整生命周期,为后续程序运行分析奠定了基础。

第6章 hello进程管理

6.1 进程的概念与作用

进程是计算机系统中程序执行的实例,是操作系统资源分配的基本单位。每个进程拥有独立的地址空间、文件描述符、环境变量等系统资源。Hello程序从静态的可执行文件到动态运行的实例,正是通过进程机制实现的。

进程的主要作用包括:

资源隔离:防止程序间相互干扰

并发执行:通过时间片轮转实现多任务

权限控制:通过用户/内核模式保障系统安全

状态管理:维护程序执行上下文

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

Shell是用户与操作系统内核间的命令行接口,主要功能包括:

  1. 命令解析:

读取用户输入"hello 2023113173 GuoZhuoYuan 18291413837 2"

解析命令和参数,处理通配符、重定向等特殊字符

  1. 进程创建:

调用fork创建子进程

在子进程中execve加载hello程序

父进程等待子进程结束或转为后台运行

  1. 环境管理:

维护环境变量

管理作业控制(jobs、fg、bg等)

处理信号(Ctrl-C、Ctrl-Z等)

6.3 Hello的fork进程创建过程

当在Shell中输入hello命令后,Shell调用fork()系统调用创建子进程复制父进程(Shell)的地址空间、文件描述符等,获得新的进程ID(PID);子进程准备执行hello:继承Shell的工作目录和环境变量,保持打开的文件描述符(stdin/stdout/stderr)

    1. Hello的execve过程

在fork创建的子进程中,Shell调用execve()加载hello程序,操作系统验证文件权限和格式,加载程序头和段信息,设置新的代码段、数据段和堆栈,初始化寄存器(包括程序计数器PC)。最后进行参数传递。

6.5 Hello的进程执行

结合进程上下文信息、进程时间片,阐述进程调度的过程,用户态与核心态转换等等。

当在Shell中执行hello时,Shell首先通过fork系统调用创建一个与自己完全相同的子进程。然后子进程通过execve系统调用加载hello可执行程序,操作系统会验证文件权限和格式后,用hello程序的代码段和数据段替换当前进程的地址空间内容,并初始化寄存器状态,使得程序计数器指向main函数入口。在hello进程执行期间,操作系统通过时间片轮转机制为其分配CPU资源,当进程调用printf输出信息或执行sleep暂停时,会主动让出CPU进入等待状态;若时间片用完则会由时钟中断强制引发调度。执行过程中,用户输入的Ctrl-C或Ctrl-Z等信号会触发内核向进程发送相应信号,hello进程可能因此被终止或暂停,这些信号处理涉及用户态与内核态的多次切换。最终,当main函数返回或调用exit后,进程终止,内核回收其占用的所有资源.

6.6 hello的异常与信号处理

以下格式自行编排,编辑时删除

hello执行过程中会出现哪几类异常,会产生哪些信号,又怎么处理的。

程序运行过程中可以按键盘,如不停乱按,包括回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps jobs pstree fg kill 等命令,请分别给出各命令及运行结截屏,说明异常与信号的处理。

  1. 按下Crtl+Z,进程收到SIGSTP信号,hello进程挂起并向父进程发送SIGCHLD,Ctrl+C发送SIGINT信号,Hello进程被终止。
  1. 按下ps查看进程的执行状况
  1. 运行jobs可以看到停止的作业
  1. 运行pstree可以查看所有运行中的进程的树状图

6.7本章小结

本章通过hello程序分析了Linux进程管理的核心机制,包括Shell的fork-exec机制用于加载程序,进程拥有独立的地址空间和运行上下文,CPU时间片轮转实现并发执行,系统调用和信号处理涉及用户态/内核态转换,理解到异常和信号是进程间通信的重要方式。

hello程序虽然简单,但其生命周期完整展现了操作系统进程管理的各项关键技术,包括进程创建、执行调度、资源管理和信号处理等。这些机制共同支撑了现代操作系统的多任务执行能力。

第7章 hello的存储管理

7.1 hello的存储器地址空间

结合hello说明逻辑地址、线性地址、虚拟地址、物理地址的概念。

逻辑地址(由程序产生的段内偏移地址)经过段式管理转换为线性地址(虚拟地址空间的连续地址),再通过页式管理映射为物理地址(实际内存中的地址)。现代Linux主要使用平坦内存模型,逻辑地址通常等于线性地址。虚拟地址是进程视角的统一地址空间,而物理地址是DRAM芯片上的实际存储位置。

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

x86架构采用段式管理进行首次地址转换。hello进程的代码段、数据段等对应不同的段选择符(CS、DS等)。CPU将逻辑地址分解为"段选择符:偏移量",通过段选择符在GDT(全局描述符表)或LDT(局部描述符表)中查找段描述符,获取段基址后与偏移量相加得到线性地址。

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

Linux采用页式管理将hello的线性地址转换为物理地址。系统将4KB大小的页作为基本单位,通过多级页表实现映射。当hello访问0x401000(main函数地址)时,MMU解析虚拟地址为页表索引和页内偏移,通过CR3寄存器找到顶级页目录,逐级查询PDPT、PD、PT页表项,获得物理页框号后与页内偏移组合成物理地址。若页表项显示页面不在内存(Present位为0),则触发缺页异常。hello的只读代码段和可读写数据段分别映射到不同的物理页,实现内存保护。

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

hello进程的地址转换通过TLB(快表)加速。当CPU访问栈变量地址时,首先查询TLB缓存,若命中直接获得物理地址,未命中则启动四级页表遍历:

CR3指向PML4表(第4级)

39-47位索引PML4项→获取PDPT基址(第3级)

30-38位索引PDPT项→获取PD基址(第2级)

21-29位索引PD项→获取PT基址(第1级)

12-20位索引PT项→获取物理页框

将转换结果缓存到TLB。

hello的频繁访问的代码页(如循环体)会长期驻留TLB,显著提高性能。

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

hello访问物理内存时,CPU缓存子系统发挥作用。例如执行"mov (%rax),%ebx"时,首先查询L1 dCache,命中则3-5周期完成访问,未命中查询L2 Cache,仍未命中查询L3 Cache。最后访问主存。

hello的连续数组访问会因空间局部性产生缓存命中,而随机内存访问则可能导致缓存行逐出。MESI协议维护多核间缓存一致性,确保hello在多核环境下的正确执行。

7.6 hello进程fork时的内存映射

当Shell为hello调用fork()时,内核复制父进程的mm_struct和vm_area_struct

,建立相同的虚拟地址空间布局,将页表项标记为写时复制(COW),新老进程共享同一物理页。

例如hello的代码段(只读)保持共享,而数据段(可写)在首次修改时触发COW缺页异常,内核再分配新物理页。这种机制显著减少fork开销,使hello进程快速启动。

7.7 hello进程execve时的内存映射

execve加载hello时,释放原进程除文件描述符外的所有资源,解析ELF格式,建立代码段、数据段等映射。.text映射为只读、可执行(R-X),.data映射为可读写(RW-),.bss初始化为零页,设置堆区(brk)和栈区(自动增长),加载动态链接器(ld.so)处理共享库。

hello的代码段采用内存映射文件方式,首次访问时由缺页异常实际加载页面,节省启动时间。

7.8 缺页故障与缺页中断处理

hello执行时可能触发多种缺页异常:

  1. COW缺页:fork后首次写数据,内核复制新页
  2. 文件映射缺页:首次访问代码段,从磁盘加载.text
  3. 匿名页缺页:访问堆栈新区域,分配零页
  4. 权限缺页:写只读页(如代码段)触发段错误

处理流程:

CPU保存现场,陷入内核,查询vm_area_struct判断合法性,执行相应补救措施(读盘、分配页等),更新页表,返回用户态继续执行。

7.9动态存储分配管理

当hello调用printf时,其内部可能通过malloc申请缓冲区。glibc使用以下策略管理堆内存:小内存(<64KB)采用brk扩展的隐式空闲链表,大内存采用mmap匿名映射。

分配算法:分离空闲链表(不同大小类)

例如printf临时缓冲区可能从fast bins(单链表缓存)快速获取,减少系统调用开销。

Printf 会调用malloc ,请简述动态内存管理的基本方法与策略。(此节课堂没有讲授,选做,不算分)

7.10本章小结

本章分析了hello程序的完整存储管理机制。从逻辑地址到物理地址的转换通过段页式管理实现,TLB和Cache显著提升访问效率。fork的COW机制和execve的按需分页优化了进程创建。缺页异常处理保障了虚拟内存的透明性,动态内存分配满足程序灵活需求。

(第 7 2 分)

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

以下格式自行编排,编辑时删除

设备的模型化:文件

设备管理:unix io接口

8.2 简述Unix IO接口及其函数

以下格式自行编排,编辑时删除

8.3 printf的实现分析

以下格式自行编排,编辑时删除

[转]printf 函数实现的深入剖析 - Pianistx - 博客园

从vsprintf生成显示信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等.

字符显示驱动子程序:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。

显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。

8.4 getchar的实现分析

以下格式自行编排,编辑时删除

异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。

getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。

8.5本章小结

以下格式自行编排,编辑时删除

(第 8 选做 0 分)

结论

用计算机系统的语言,逐条总结hello所经历的过程。

你对计算机系统的设计与实现的深切感悟,你的创新理念,如新的设计与实现方法。

  1. 预处理阶段:hello.c经过预处理,头文件内容被插入程序文本,生成hello.i文件。
  2. 编译阶段:编译器将hello.i编译为汇编代码,输出hello.s文件。
  3. 汇编阶段:汇编器将hello.s转换为机器指令,生成可重定位目标文件hello.o。
  4. 链接阶段:链接器对hello.o进行重定位,将调用的系统函数如printf等链接到目标文件,生成可执行文件hello。
  5. 进程创建:在shell中输入运行命令后,操作系统通过fork()创建子进程运行hello程序。
  6. 地址转换:程序运行时,虚拟地址首先转换为线性地址,再映射为物理地址进行访问。
  7. 程序执行:hello程序正常执行,通过文件管理系统完成I/O操作并输出结果。
  8. 进程终止:程序运行结束后,由shell父进程回收终止的hello子进程。

Hello程序虽小,却完整呈现了现代计算机系统的核心设计逻辑。从虚拟内存的透明抽象到异常处理的精确控制,各子系统通过严谨的接口定义和状态机模型,构建出既稳定可靠又高效灵活的执行环境。在未来的学习与工作中,我也将不忘在计算机系统学到的知识,继续探索,更深入的了解计算机。

(结论 0 分,缺失 -1 分)

附件

列出所有的中间产物的文件名,并予以说明起作用。

hello.c 源代码

hello.i 预处理后的程序

hello.s 汇编代码

hello.o 可重定位目标文件

hello 可执行文件

Objdump_hello.o hello.o的反汇编文件

Objdump_hello hello的反汇编文件

(附件 0 分,缺失 -1 分)

参考文献

为完成本次大作业你翻阅的书籍与网站等

1\] Randal E. Bryant and David R. O'Hallaron. 2010. Computer Systems: A Programmer's Perspective (2nd. ed.). Addison-Wesley Publishing Company, USA. \[2\] https://github.com/wangmu0115/Book-CSAPP \[3\] https://www.csdn.net **(参考文献** **0** **分,缺失** **-1** **分)**

相关推荐
apcipot_rain2 个月前
原神“十盒半价”问题的兹白式建模分析
python·数学·算法·函数·数据科学·原神·数列
小森程序员7 个月前
基于原神游戏物品系统小demo制作思路
游戏·原神·物品收集·物品消耗
MCYH02061 年前
C++抽卡模拟器
java·c++·算法·概率·原神
琪露诺大湿1 年前
SpringMVC (3)
java·运维·服务器·网络·spring boot·java-ee·原神
琪露诺大湿1 年前
JavaEE-多线程初阶(4)
java·开发语言·jvm·java-ee·基础·1024程序员节·原神
琪露诺大湿1 年前
JavaEE-多线程初阶(2)
java·开发语言·jvm·mysql·java-ee·1024程序员节·原神
顶顶年华正版软件官方2 年前
苹果电脑可以玩《原神》吗?原神可以在Mac上玩吗?苹果电脑玩原神怎么样
linux·游戏·macos·苹果电脑·原神·crossover软件
与妖为邻2 年前
修改了原神4.8版本升级数据表
javascript·css·html·css3·localstorage·原神
李小白杂货铺2 年前
游戏名台词大赏
游戏·原神·崩坏3·崩铁·经典台词