本文主要介绍了hello程序在Linux系统中的生命周期。我们将结合《深入理解计算机系统》中的内容,通过研究分析hello.c经过预处理、编译、汇编、链接生成可执行文件的过程,以及计算机系统对hello可执行目标程序的进程、存储以及I/O管理,让读者对计算机系统的主要结构和基本原理有一个更加清晰的认识。
关键词:hello;Linux;计算机系统;处理器体系结构;存储器体系结构;进程
目 录
4.3.2 ELF头(ELF Header)... - 17 -
4.3.3 节头部表(Section Headers)... - 18 -
4.3.4 重定位节(Relocation section)... - 19 -
4.3.5 符号表(Symbol table)... - 20 -
5.3.2 ELF头(ELF Header)... - 24 -
5.3.3 节头部表(Section Headers)... - 25 -
5.3.4 重定位节(Relocation section)... - 27 -
5.3.5 符号表(Symbol table)... - 27 -
5.5.2 hello和hello.o的不同... - 29 -
6.2 简述壳Shell-bash的作用与处理流程... - 34 -
6.3 Hello的fork进程创建过程... - 35 -
7.2 Intel逻辑地址到线性地址的变换-段式管理... - 41 -
7.3 Hello的线性地址到物理地址的变换-页式管理... - 43 -
7.4 TLB与四级页表支持下的VA到PA的变换... - 44 -
7.5 三级Cache支持下的物理内存访问... - 46 -
7.6 hello进程fork时的内存映射... - 47 -
7.7 hello进程execve时的内存映射... - 47 -
第1章 概述
1.1 Hello简介
根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。
1、P2P:从program到process的过程。
(1)Program:在editor中编辑输入代码获得hello.c文件。
(2)Process:在linux当中,hello.c文件通过cpp的预处理、ccl的编译器、as的汇编器以及ld的链接,最终成为一个可执行目标程序hello。然后,在shell中键入启动命令后,shell调用fork为其产生一个子进程。
2、020:
(1)shell为 hello进程execve,映射虚拟内存,进入程序入口后程序开始载入物理内存。
(2)进入main函数执行目标代码,CPU为运行的hello分配时间片执行逻辑控制流。
(3)当程序运行结束后,shell父进程负责回收hello进程,内核删除相关数据结构。
1.2 环境与工具
硬件环境:X64 CPU;2.60 G Hz;8.00 GB RAM;512 G HDD
软件环境:Windows10 64 位;VMware 15.5.0;Ubuntu Desktop 18.04
开发与调试工具:gcc,as,ld,vim,edb,readelf,VScode
1.3 中间结果
文件名 |
文件作用 |
hello.i |
hello.c预处理后的文本文件 |
hello.s |
hello.i编译后的汇编文件 |
hello.o |
hello.s汇编后的可重定位目标文件 |
hello |
hello.o链接后的可执行目标文件 |
elf.txt |
hello.o的ELF格式 |
Helloelf.txt |
hello的ELF格式 |
Obj_hello |
hello.o的反汇编代码 |
Obj_helloo |
hello的反汇编代码 |
1.4 本章小结
本章主要介绍了hello的P2P和020的具体含义和过程,列出了作业中配置的软硬件环境、开发和调试工具以及中间过程中产生的一些文件。后文将对以本章作为总领进行具体详细的展开。
第2章 预处理
2.1 预处理的概念与作用
1、预处理的概念
预处理中会展开以#起始的行,试图解释为预处理指令(preprocessing directive) ,修改原始的C程序,其中 ISO C/C++要求支持的包括#if、 #ifdef、 #ifndef、 #else、 #elif、 #endif(条件编译)、 #define(宏定义)、 #include(源文件包含)、 #line(行控制)、 #error(错误指令)、 #pragma(和实现相关的杂注)以及单独的#(空指令)。预处理指令一般被用来使源代码在不同的执行环境中被方便的修改或者编译。
2、预处理的作用
(1)处理头文件包含指令:将源文件中用#include形式声明的头文件内容复制到程序中。例如hello.c中的#include<stdio.h>命令使预处理器将头文件stdio.h的内容合并到程序中。
(2)处理宏定义指令:用实际值替换#define定义的字符串。
(3)处理条件编译指令:根据条件编译指令#if、#ifdef等来决定需要编译那些代码,并删除不需要编译的代码。
(4)处理特殊符号:预编译程序可以识别一些特殊的符号,预编译程序对于在源程序中出现的这些串将用合适的值进行替换。
(5)去除注释。
2.2在Ubuntu下预处理的命令
命令:gcc hello.c -E -o hello.