以hello world为例,详细分析程序的编译过程

以hello world为例,详细分析程序的编译过程

以C++为编写语言,编写hello_world.cpp

  1. 编写源代码(hello_world.cpp)
#include<iostream>
using namespace std; 
int main()
{
    printf("hello world");
    return 0;
}
  1. 预编译
    • 处理源代码文件中“#”开始的预编译指令。(如#include,#define等)
    • 处理“#include”预编译指令,将被包含的头文件插入到预编译指令的位置。
    • 删除所有注释
    • 添加行号和文件标识
    • 打开命令行->输入g++ -E hello_world.cpp -o hello_world.i 进行预处理
    • 生成预处理文件 “hello_world.i”

  1. 编译
    • 词法分析:源代码经过扫描器,将源代码的字符序列分割成一系列的记号,将标识符存到符号表,数字、字符串存到文字表。
    • 语法分析:语法分析器对扫描器记号进行语法分析,生成语法树。
    • 语义分析:对静态语义进行分析(如声明、类型匹配、类型转换)
    • 代码优化:源代码优化器进行优化。
    • 打开命令行->输入g++ -S hello_world.cpp进行编译
    • 生成汇编语言文件 “hello_world.s”

  1. 汇编

    • 汇编器将汇编代码变成机器可执行的指令,计算机根据汇编命令和机器指令的对照表进行翻译生成可重定位的二进制目标文件
    • 打开命令行->输入g++ -c hello_world.cpp
    • 生成目标文件“hello_world.o”或“hello_world.obj”

      (.o文件不可读,没有程序截图)

  2. 链接

    • 合并段和符号表、分配地址和空间:扫描所有的输入目标文件,获得各段的长度、属性和位置,并且将输入目标文件中的符号定义和符号引用收集放到一个全局符号表。链接器计算输出文件中各段合并后的长度和位置,建立映射关系。
    • 符号解析与重定位:使用合并后的地址和空间,进行符号解析与重定位,调整代码中的地址(虚拟地址映射物理地址)。
    • 打开命令行->输入g++ -o hello_world hello_world.cpp
    • 生成可执行文件“hello_world.exe”

  1. 执行
    • 建立虚拟地址空间到物理内存的映射,创建页目录和页表
    • 加载指令和数据
    • 将程序入口地址写入PC寄存器

命令行指令示意

posted @ 2020-03-22 13:30  黄金弧线  阅读(798)  评论(0)    收藏  举报