正在上传…重新上传取消

计算机系统

大作业

题 目 程序人生-Hello’s P2P

专 业 计算机科学与技术

学   号 2021110991

班   级 2103101

学 生 安心

指 导 教 师 刘宏伟

计算机科学与技术学院

2022年5月

摘 要

本文着重从hello程序的预处理、编译、汇编、链接、进程管理等过程入手,深入探究了hello程序从开始执行加载到内存,再到经过一系列操作与过程完成使命任务,最后结束生命周期的整个历程,展示了较为完整的计算机系统知识。

关键词:hello程序 预处理汇编 链接 进程管理 生命周期

计算机系统 程序编译过程

目 录

第1章 概述………………………………………………………………………………………………. – 4 –

1.1 Hello简介………………………………………………………………………………………… – 4 –

1.2 环境与工具……………………………………………………………………………………….. – 4 –

1.3 中间结果…………………………………………………………………………………………… – 4 –

1.4 本章小结…………………………………………………………………………………………… – 4 –

第2章 预处理…………………………………………………………………………………………… – 5 –

2.1 预处理的概念与作用…………………………………………………………………………. – 5 –

2.2在Ubuntu下预处理的命令……………………………………………………………….. – 5 –

2.3 Hello的预处理结果解析…………………………………………………………………… – 5 –

2.4 本章小结…………………………………………………………………………………………… – 5 –

第3章 编译………………………………………………………………………………………………. – 6 –

3.1 编译的概念与作用…………………………………………………………………………….. – 6 –

3.2 在Ubuntu下编译的命令………………………………………………………………….. – 6 –

3.3 Hello的编译结果解析………………………………………………………………………. – 6 –

3.4 本章小结…………………………………………………………………………………………… – 6 –

第4章 汇编………………………………………………………………………………………………. – 7 –

4.1 汇编的概念与作用…………………………………………………………………………….. – 7 –

4.2 在Ubuntu下汇编的命令………………………………………………………………….. – 7 –

4.3 可重定位目标elf格式……………………………………………………………………… – 7 –

4.4 Hello.o的结果解析………………………………………………………………………….. – 7 –

4.5 本章小结…………………………………………………………………………………………… – 7 –

第5章 链接………………………………………………………………………………………………. – 8 –

5.1 链接的概念与作用…………………………………………………………………………….. – 8 –

5.2 在Ubuntu下链接的命令………………………………………………………………….. – 8 –

5.3 可执行目标文件hello的格式………………………………………………………….. – 8 –

5.4 hello的虚拟地址空间………………………………………………………………………. – 8 –

5.5 链接的重定位过程分析……………………………………………………………………… – 8 –

5.6 hello的执行流程……………………………………………………………………………… – 8 –

5.7 Hello的动态链接分析………………………………………………………………………. – 8 –

5.8 本章小结…………………………………………………………………………………………… – 9 –

第6章 hello进程管理……………………………………………………………………….. – 10 –

6.1 进程的概念与作用…………………………………………………………………………… – 10 –

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

6.3 Hello的fork进程创建过程…………………………………………………………… – 10 –

6.4 Hello的execve过程……………………………………………………………………… – 10 –

6.5 Hello的进程执行……………………………………………………………………………. – 10 –

6.6 hello的异常与信号处理…………………………………………………………………. – 10 –

6.7本章小结…………………………………………………………………………………………. – 10 –

第7章 hello的存储管理…………………………………………………………………….. – 11 –

7.1 hello的存储器地址空间…………………………………………………………………. – 11 –

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

7.3 Hello的线性地址到物理地址的变换-页式管理………………………………… – 11 –

7.4 TLB与四级页表支持下的VA到PA的变换……………………………………… – 11 –

7.5 三级Cache支持下的物理内存访问…………………………………………………. – 11 –

7.6 hello进程fork时的内存映射………………………………………………………… – 11 –

7.7 hello进程execve时的内存映射…………………………………………………….. – 11 –

7.8 缺页故障与缺页中断处理………………………………………………………………… – 11 –

7.9动态存储分配管理…………………………………………………………………………… – 11 –

7.10本章小结……………………………………………………………………………………….. – 12 –

第8章 hello的IO管理……………………………………………………………………… – 13 –

8.1 Linux的IO设备管理方法……………………………………………………………….. – 13 –

8.2 简述Unix IO接口及其函数…………………………………………………………….. – 13 –

8.3 printf的实现分析……………………………………………………………………………. – 13 –

8.4 getchar的实现分析………………………………………………………………………… – 13 –

8.5本章小结…………………………………………………………………………………………. – 13 –

结论…………………………………………………………………………………………………………. – 14 –

附件…………………………………………………………………………………………………………. – 15 –

参考文献………………………………………………………………………………………………….. – 16 –

第1章 概述

1.1 Hello简介

(一)P2P(From Program to Process):在运行hello程序过程中,hello.c源程序首先被预处理为hello.i文件,再经过编译器编译为hello.s文件,接着由汇编器汇编为hello.o可重定位目标文件,最后经过链接器链接为可执行文件hello。在完成这个过程后,壳(Shell)为hello创建了一个子进程(process),这个子进程通过execve进行程序执行,就完成了完整的P2P过程。

(二)020(From Zero to Zero):是指一个程序从无到有,在结束生命周期后由父进程为其回收进程的全过程。对于hello程序来说,在通过execve执行之后,系统会把程序加载到内存,待进程结束后,父进程会将其回收,内核会清理它的内存,这个过程就是020。

1.2 环境与工具

软件环境:windows10 ubuntu22.04

硬件环境:X64 CPU 2GHz2G RAM 256GHD Disk

开发工具:gccvim objdump edb

    1. 中间结果

hello.i:预处理生成的文本文件

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

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

hello_objdump.s:*.o经过链接反汇编的汇编语言文件

re_hello.s:*.o经过反汇编生成的汇编语言文件

elf.txt:*.o的elf文本文件

hello:*.o经过链接生成的可执行目标文件

elf_1.txt:hello的elf文件

1.4 本章小结

本章介绍了hello程序的生命周期,并介绍了执行过程中生成的中间文件的项目和作用。

第2章 预处理

2.1 预处理的概念与作用

概念:预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。

作用:

  1. 将所有的#define删除,展开所有的宏定义;
  2. 处理所有的预编译指令;
  3. 将#include包含的文件插入到预编译指令的位置;
  4. 添加行号信息和文件名信息;
  5. 删除所有的注释;
  6. 生成*.i文件。

2.2在Ubuntu下预处理的命令

指令:gcc -E hello.c -o hello.i

正在上传…重新上传取消

图2.2 在Ubuntu下预处理的命令

2.3 Hello的预处理结果解析

正在上传…重新上传取消

图2.3 hello的预处理结果

从图中我们可以看到,hello.i的文件内容比hello.c的文件内容多得多,行数甚至达到了3000多行。这是因为hello.c在进行预处理时插入了一些#include包含的内容。比如,hello.c中第一行的#include 命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中,结果就得到了另一个C程序,通常是以.i作为文件扩展名(即预处理文件)。

2.4 本章小结

本章介绍了hello程序的预处理指令以及生成的预处理文件,分析了hello的预处理结果,重点探究了hello.i的内容比hello.c源程序的内容多得多的原因,展示了预处理的功能。

第3章 编译

3.1 编译的概念与作用

概念: 编译器对预处理器的输出进行编译,生成汇编语言(assemble language)的代码。本质就是利用编译程序从源语言编写的源程序产生目标程序的过程,其中的五个阶段分别是词法分析、语法分析、语义检查和中间代码生成、代码优化、目标代码生成。

作用:主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现有语法错误,给出提示信息。

3.2 在Ubuntu下编译的命令

指令:gcc -S hello.i -o hello.s

正在上传…重新上传取消

图3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果解析

3.3.1 术语解释

正在上传…重新上传取消源文件字段

正在上传…重新上传取消代码段

正在上传…重新上传取消 只读数据段

正在上传…重新上传取消 对齐方式

正在上传…重新上传取消 类型

正在上传…重新上传取消 long类型

正在上传…重新上传取消 string类型

3.3.2 数据类型分析

(一)字符串类型

正在上传…重新上传取消

分别对应代码段中的字符串正在上传…重新上传取消和。

(二)循环变量i

正在上传…重新上传取消

正在上传…重新上传取消

正在上传…重新上传取消

编译器对%rbp进行处理,将变量i通过压栈存储在栈中,在每次循环之后对i进行加一操作,并判断是否满足循环条件(i < 9),然后通过跳转表进行跳转。

(三)main函数参数

正在上传…重新上传取消

%rdi用于存放第一个参数,%rsi用于存放第二个参数,因此这里先通过将%rsp的值减去32开辟main函数栈帧,然后用%edi存放第一个参数(int型参数argc),用%rsi存放第二个参数(char型数组argv[])。

3.3.3 操作类型分析

(一)赋值操作

正在上传…重新上传取消

将立即数0通过压栈方式压入M[%rbp – 4]内存空间中,即将i赋值为0。

(二)位置偏移

正在上传…重新上传取消

分别移动8位和16位。

(三)加法运算

正在上传…重新上传取消

将%rax中的值加8。

(四)跳转操作

正在上传…重新上传取消 相等则跳转

正在上传…重新上传取消 无条件跳转

正在上传…重新上传取消 小于等于则跳转

(五)比较操作

正在上传…重新上传取消 对4进行比较,若小于则继续运算

(六)函数调用

正在上传…重新上传取消 调用puts()函数

正在上传…重新上传取消 调用exit()函数

正在上传…重新上传取消 调用printf()函数

正在上传…重新上传取消 调用sleep()函数

3.4 本章小结

本章首先介绍了编译的概念与作用,接着通过在Ubuntu操作系统上运行编译hello.c文件指令生成hello.s文件,通过分析其中的汇编代码介绍了汇编语言实现的术语解释、数据类型以及操作类型的代码实现。展示了能够读懂汇编代码的重要性。

第4章 汇编

4.1 汇编的概念与作用

概念:从.s到.o,即编译后的文件通过汇编器到生成机器语言二进制程序的过程。

作用:汇编器(as)将hello.s文件翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序(relocatable object program)的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它包含着hello的指令编码。如果我们在文本编辑器中打卡hello.o文件,将会看到一堆乱码。

4.2 在Ubuntu下汇编的命令

指令:gcc hello.s -c -o hello.o

正在上传…重新上传取消

图4.2 在Ubuntu下汇编的命令

应该注意,生成的.o文件为二进制文件,无法直接通过文本编辑器打开,我们需要输入readelf -a hello.o > ./elf.txt重定向将其转换为ELF文件后再进行查看。

正在上传…重新上传取消

图4.2 重定向生成的ELF文件

4.3 可重定位目标elf格式

(一)ELF头

正在上传…重新上传取消

  1. 魔数

正在上传…重新上传取消

文件开头的几个字节称为魔数字,通常用来确定文件的类型或者格式。在加载或读取文件时,可用魔数来确认文件类型是否正确。

  1. 节头部表起始

正在上传…重新上传取消

  1. ELF头的大小

正在上传…重新上传取消

  1. 节头部表表项

正在上传…重新上传取消

  1. 每一节头部表表项的大小

正在上传…重新上传取消

(二)节头表

正在上传…重新上传取消

节头表由若干个表项构成,每个表项描述相应的一个节的节名、在文件中的偏移、大小、访问属性、对齐方式等,目标文件中的每个节都有一个表项与之对应。

从上述解析结果可以看出,该hello.o文件共有13个节。其中编号为0的节是占位符,不具有实际意义;.text、.data、.bss和.rodata节需要在存储器中分配空间,.text节是可执行的,.data和.bss节是可读写的,而.rodata节是只读不可写的。

(三)重定位节

正在上传…重新上传取消

重定位节中包含了一些本程序中使用的一些外部变量和外部函数等信息,这些信息需要在链接的时候根据重定位节的信息对这些变量符号进行修改。

  1. UND节

正在上传…重新上传取消

这些函数在hello.c中未被定义,需要在链接时在静态库中引用函数定义。

  1. FUNC节

正在上传…重新上传取消

申明函数main为GLOBAL类型的函数。

3、.text节

正在上传…重新上传取消

4、.rodata节

正在上传…重新上传取消

(四)符号表

正在上传…重新上传取消

程序中定义的函数名和全局静态变量名都属于符号,与这些符号相关的信息保存在符号表中。

4.4 Hello.o的结果解析

指令:objdump -d -r hello.o > re_hello.s

正在上传…重新上传取消

图4.4 在Ubuntu下的反汇编指令

  • 跳转指令发生变化

正在上传…重新上传取消

跳转指令由之前的段名称变为实际地址。

  • 函数调用发生变化

正在上传…重新上传取消

在反汇编程序中,call指令后紧跟着下一条指令的地址。但是在.o文件中,地址偏移量正在上传…重新上传取消均为0,且指出链接时填入地址为绝对地址引用。

  • 数据访问发生变化

正在上传…重新上传取消

在反汇编程序中,使用正在上传…重新上传取消来访问rodata,这是因为在未进行链接时,程序无法得知rodata中数据的具体地址,因此用0填充代替。同时指出链接时通过PC相对寻址的方式进行寻址。

4.5 本章小结

本章介绍了汇编的概念与作用,通过在Ubuntu系统下对hello.s文件进行汇编,得到了hello.o可重定位目标文件。通过对hello.o文件进行反汇编,介绍了ELF文件的内容以及各种节的内容和代码实现。最后简要介绍了编译后反汇编得到的代码与源程序的汇编代码的差别。

第5章 链接

5.1 链接的概念与作用

概念:链接是将各种代码和数据片段收集并组合成为一个单文件的过程。

作用:在每个程序模块中,某一个模块中定义的符号可以被另一个模块引用,因而最终必须通过链接将程序包含的所有模块合并起来,合并时需要在符号引用处填入定义处的地址。这就是链接的作用。

5.2 在Ubuntu下链接的命令

指令:ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

正在上传…重新上传取消

图5.2 在Ubuntu下链接的命令

正在上传…重新上传取消

图5.2 重定位生成文本编辑器可打开的文件

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

(一)ELF头

正在上传…重新上传取消

ELF头以Magic(魔数)开始,ELF头大小为正在上传…重新上传取消,获得了入口地址为,同时程序头起点置为非零值。

(二)节头

正在上传…重新上传取消

正在上传…重新上传取消

包括了文件中出现的各个节的定义、类型、位置、偏移量和大小等属性。

(三)程序头表

正在上传…重新上传取消

与可重定位文件相比,可执行文件多了一个程序头表,也称为段头表,它是一个结构数组。包括了各个段的类型、起始位置、偏移量、虚拟地址和物理地址。

  • 重定位节

正在上传…重新上传取消

包括了需要重定位的参数和函数的偏移量、信息、类型、符号值、符号名称和加数等一系列属性。

  • Symbol table

正在上传…重新上传取消

5.4 hello的虚拟地址空间

指令:edb –run hello

通过该指令可以对hello可执行程序进行查看。

(一)地址空间

使用edb打开后可以看到data dump为地址空间栏。

正在上传…重新上传取消

(二)指令装载地址

正在上传…重新上传取消

(三)寄存器

正在上传…重新上传取消

(四)数据堆栈

正在上传…重新上传取消

与5.3节地址相比,5.4节中的地址为重定位后的虚拟地址,因此main函数不是从地址为0x0处开始的,而是有一个偏移量,这个偏移量是ELF头的内容以及一些初始化部分的信息内容。

5.5 链接的重定位过程分析

指令:objdump -d -r hello > hello_objdump.s

正在上传…重新上传取消

  • 函数有所增加

正在上传…重新上传取消

增加了start()函数。

  • 增加了外部库的函数

正在上传…重新上传取消

  • 地址变更

正在上传…重新上传取消

对于call指令来说,可重定位目标文件中偏移量为0x0,而可执行目标文件中地址偏移量被填充为正在上传…重新上传取消。

  • 增加了init初始化段

正在上传…重新上传取消

对以上变更进行对比,由此可以得出编译器在链接时对hello.o文件做出的更改:

  • 将call函数调用指令处的地址偏移量填充为实际的地址偏移量。在汇编阶段无法填充的原因是编译器不知道被引用函数在内存中的实际地址,因此在链接时将文件段合并之后编译器可以确定被引用函数的具体位置。
  • 将.rodata节中数据的地址填充为实际的地址。合并之后编译器方可得知数据的实际地址。
  • 插入了外部库中的函数代码实现。在对hello.s文件进行汇编生成hello.o文件时,printf()、puts()等外部库中的函数在hello.c文件中无定义,因此在连接过程中链接器从外部库中查找相关的函数声明,并将其插入到hello文件中。
  • 增加了init段,有助于在执行过程中对hello程序进行初始化。

5.6 hello的执行流程

(一)执行过程:

加载hello:

正在上传…重新上传取消

进入主函数main():

正在上传…重新上传取消

程序终止:

正在上传…重新上传取消

(二)各个子程序名称

1、

2、

3、

4、

5、

6、

7、

8、

9、

10、

11、

12、

13、

14、

5.7 Hello的动态链接分析

正在上传…重新上传取消

在elf文件中找到got pit的开头地址0x404000,然后通过该地址在edb中找到它:

正在上传…重新上传取消

因此0x7f37c863c2e0和0x7f37c8616d30保存的信息为动态链接后函数的最终地址。

5.8 本章小结

本章介绍了链接的概念与作用,重点探究了链接过程中对hello.o文件做出的改变,以及链接之后hello的执行流程。同时介绍了hello可执行文件的ELF文本格式。

第6章 hello进程管理

6.1 进程的概念与作用

概念:进程的经典定义就是一个执行中程序的实例。

作用:进程提供给应用程序两个关键抽象:

一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占地使用处理器。

一个私有的地址空间,它提供一个假象,好像我们的程序独占地使用内存系统。

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

作用:Shell执行一系列的读取解析指令,然后终止。读取步骤读取来自用户的一个命令行,解析步骤将命令行解析,并运行程序。

处理流程:

  1. 在Shell命令行中输入命令:$./hello;
  2. Shell命令行解释器构造argv和envp;
  3. 调用fork()函数创建子进程,其地址空间与Shell父进程完全相同,包括只读代码段、读写数据段、堆以及用户栈等;
  4. 调用execve()函数在当前进程(新创建的子进程)的上下文中加载并运行hello程序。将hello中的.text节、.data节、.bss节等内容加载到当前进程的虚拟地址空间;
  5. 调用hello程序的main()函数,hello程序开始在一个进程的上下文运行。

6.3 Hello的fork进程创建过程

通过fork()函数创建一个新的子进程。新创建的子进程几乎但不完全与父进程相同。子进程得到与父进程用户及虚拟地址空间相同的(但是是独立的)一份副本,包括代码和数据段、堆、共享库以及用户栈。子进程还获得与父进程任何打开文件描述符相同的副本,这就意味着当父进程调用fork()函数时,子进程可以读写父进程中打开的任何文件。Fork()函数调用一次返回两次:一次是在调用进程(父进程)中,一次是在新创建的子进程中。

6.4 Hello的execve过程

execve()函数加载并运行可执行文件hello,且带参数列表argv和环境变量列表envp。只有当出现错误时,例如找不到文件hello,execve()才会返回到调用程序。所以,execve()函数调用一次并从不返回。

6.5 Hello的进程执行

(一)逻辑控制流:

一系列程序计数器PC的值的序列叫做逻辑控制流,这些值唯一地对应于包含在程序的可执行目标文件中的指令,或是包含在运行时动态链接到程序的共享对象中的指令。各个进程将轮流使用处理器,在同一个处理器核心中,每个进程执行它的流的一部分后被暂时挂起,然后执行其他进程。

(二)用户模式与内核模式:

处理器通过某个控制寄存器中的一个模式位来提供限制一个应用可以执行的指令以及它可以访问的地址空间范围的功能。该寄存器描述了当前进程运行的权限。当设置了模式位时,进程就运行在内核模式中。没有设置模式位时,进程就运行在用户模式中。一个运行在内核模式的进程可以执行指令集中的任何指令,并且可以访问系统中的任何内存;而用户模式的进程不允许和执行特权指令、也不允许用户模式中的进程直接引用地址空间中内核区内的代码和数据。

(三)上下文切换:

内核为每个进程维持一个上下文。上下文就是内核重新启动的一个进程所需的状态。这个状态包括通用目的寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构。

(四)进程时间片:

一个进程执行它的控制流的一部分的每一时间段叫做时间片。

6.6 hello的异常与信号处理

hello执行过程中会出现四类异常:中断、陷阱、故障、终止。

  • 中断

会产生来自I/O设备的信号,且总是返回到下一条指令。

  • 陷阱

会产生有意的异常信号,且总是返回到下一条指令。

  • 故障

会产生潜在的可恢复的错误信号,且可能返回到当前指令。

  • 终止

会产生不可恢复的错误信号,且不会返回。

在hello程序中,使用键盘触发中断,而Shell输出的过程触发陷阱。

  • 正常运行

正在上传…重新上传取消

  • 使用键盘中断

正在上传…重新上传取消

此时进程被挂起,仍处于后台。

输入kill,可将进程杀死。

正在上传…重新上传取消

  • 终止进程

正在上传…重新上传取消

在进程执行过程中按下ctrl+c可直接终止进程。

6.7本章小结

本章介绍了进程的相关概念与作用,着重介绍了hello进程的额创建与执行过程,最后介绍了异常的种类以及信号的发送。

第7章 hello的存储管理

7.1 hello的存储器地址空间

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

结合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动态存储分配管理

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

Printf会调用malloc,请简述动态内存管理的基本方法与策略。

7.10本章小结

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

(第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本章小结

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

(第81分)

结论

经理过程:

(一)预处理器将hello.c文件输出为hello.i文件;

(二)编译器将hello.i文件输出为汇编文件hello.s文件;

(三)汇编器将hello.s文件输出为hello.o可重定位目标文件;

(四)链接器将hello.o文件与库函数文件链接生成hello可执行目标文件;

(五)在Shell命令行中输入命令:$./hello;

(六)Shell命令行解释器构造argv和envp;

(七)调用execve()函数在当前进程(新创建的子进程)的上下文中加载并运行hello程序

(八)调用hello程序的main()函数,hello程序开始在一个进程的上下文运行。

(九)hello程序执行完毕,由父进程将其回收。

感悟:

从大一入学写下第一个hello.c程序,到现在逐步学习了hello程序经历的一系列过程,不由得感叹计算世界的奇妙。今后的学习更应注重底层逻辑的实现,打好数理基础,为将来的计算之路添砖加瓦。

附件

hello.i:预处理生成的文本文件

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

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

hello_objdump.s:*.o经过链接反汇编的汇编语言文件

re_hello.s:*.o经过反汇编生成的汇编语言文件

elf.txt:*.o的elf文本文件

hello:*.o经过链接生成的可执行目标文件

elf_1.txt:hello的elf文件

参考文献

[1] CSAPP大黑书

[2] CSDN网站

[3] 科普中国