程序人生-Hello's P2P

概述

Hello简介

根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。
P2P : From Program to Process. hello.c经过预处理器cpp预处理成hello.i,再经过编译器ccl变成hello.s,再经过汇编器as变成hello.o,最后经过链接器ld与C library进行链接,最终变成hello。此时的hello成为了一个program。shell通过键盘键入”./hello”,此时hello变成了一个process,shell为它fork一个子进程,并excve hello这个进程。这就是P2P的过程。
020 : From Zero-0 to Zero-0. Shell执行可执行目标文件hello,并创建一组新的代码、数据、堆和栈段。新的栈和堆段被初始化为零。执行hello的过程中,堆、栈段大小发生变化。在hello执行完成后,父进程shell回收子进程hello,IO管理与信号处理通过软硬结合,将其输出显示到屏幕。堆栈信息恢复到执行hello之前的状态,也就是执行hello前后堆栈信息没有改变,这就是020的过程。

环境与工具

硬件环境:X64CPU; 2.60GHz; 8GRAM;
软件环境:Windows10 64位;Vmware 14;Ubuntu 18.04 LTS 64位
开发与调试工具:gedit; vi; gcc; as; ld; gdb; readelf; hexedit

中间结果

列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。

文件 内容
hello.i 预处理过的源程序
hello.s 汇编程序
hello.o 可重定位目标程序
hello 可执行程序
hello_o.elf hello.o通过readelf查看的elf结构文本
hello.elf hello通过readelf查看的elf结构文本
hello_o.asm hello.o通过objdump查看的反汇编文本
hello.asm hello通过objdump查看的反汇编文本

本章小结

hello.c经过预处理、编译、汇编、链接四个阶段变成可执行文件hello,再通过shell执行可执行文件hello,然后再被回收,体现了程序从无到有的过程。

预处理

预处理的概念与作用

预处理器(cpp)根据以字符#开头的命令(directives),修改原始的C程序。如hello.c中#include 指令告诉预处理器读系统头文件stdio.h的内容,并把它直接插入到程序文本中去。结果就得到另外一个C程序,通常是以.i作为文件扩展名的。

预处理的作用有:

  1. 将头文件的内容,直接插入到程序文本中。
  2. 将符号常量替换为后边的文本,常见的有宏定义常数、宏定义符号、宏定义函数等等。
  3. 删除所有注释。
  4. 添加行号和文件标识符。用于显示调试信息:错误或警告的位置。
  5. 处理条件预编译 #if, #ifdef, #if, #elif,#endif
  6. 保留#pragma编译器指令。(1)设定编译器状态,(2)指示编译器完成一些特定的动作。

在Ubuntu下预处理的命令

gcc -E hello.c -o hello.i
在Ubuntu下预处理的命令

Hello的预处理结果解析

预处理结果hello.i文件(部分)
我们发现

  1. 注释被删除了
  2. 头文件信息已经被插入到了hello.i中,而且文件变成了3118行(由于插入了头文件的代码)。
    gcc先打开stdio.h然后发现里面还有#define,就继续打开,直到最后的文件中没有#difine为止。在这之间会有大量的typedef重命名,以及定义大量文件输入输出指针等等。

Read More