【C++】预编译、编译、汇编、链接

    首先思考下面的问题:为什么要有编译链接呢?

    有两点原因:1.编译器无法直接运行.c和.cpp文件,因此需要将源文件转化为计算机可以识别的二进制文件;2.如果想要运行一段代码,就会产生进程,进程是在内存中,而源文件存放在内存中,因此需要编译链接,将文件加载到内存中,CPU才能执行。

    编译链接分为4个阶段,接下来具体看每个阶段做了什么事情。

    1.预编译-->.i文件

    (1)删除#define并做文本替换;

    (2)处理预编译指令,如#ifndef、#if 0、#endif等;

    (3)递归展开头文件;

    (4)删除注释;

    (5)添加行号和文本标识;

    (6)保留#pargma编译器处理。

    2.编译-->.s文件

    (1)词法分析(如变量名不能以数字开头等);

    (2)语法分析(如int a=10;delete a;);

    (3)语义分析(结合上下文分析);

    (4)代码优化(调整指令);

    (5)生成汇编指令。

    3.汇编-->.o文件(可重定位的二进制文件)

    将汇编代码翻译为机器指令

    4.链接-->.exe文件

    (1)合并段和符号表;相同的段进行合并,一个段映射一个页面。合并符号表:同名查找替换。

    强符号:已初始化的全局变量。

    弱符号:未初始化的全局变量。(C++中无强弱符号之分)

    强弱符号规则:两强会报重定义错误;一强一弱选择强符号;两弱选字节数大的。

    (2)符号解析;

    (3)分配地址和空间;

    (4)符号重定位。

    运行阶段:

    1.创建虚拟地址空间和内存的映射(创建虚拟结构体--PCB),创建页目录、页表;

    2.加载指令和数据;

    3.入口地址写入下一行指令寄存器。

 

    Linux中编译链接命令:

    假设编译源程序main.c,生成可执行程序main。

    预编译:gcc -E main.c -o main.i

                  -E:指定预编译

                  -o:output,后加输出文件名称。若无此参数则将预编译结果直接输出到终端界面,不保存到文件。

    编译:gcc -S main.i

               编译后默认生成.s文件,存放汇编指令

    汇编:gcc -c main.s

    链接:gcc main.o -o main

               链接过程在不指定生成文件名的情况下,默认均生成a.out文件。

    一般的编译链接过程直接用命令gcc -o main main.c生成,包含上述全过程。

 

此处可能会用到的命令:objdump readelf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值