美文网首页
2 编译和链接

2 编译和链接

作者: 令狐冲_ | 来源:发表于2023-01-31 10:19 被阅读0次

第二章 编译和链接词法分析语法分析语义分析中间语言生成目标代码生成与优化链接器

第二章 编译和链接

平时我们使用的IDE把编译链接的过程都合并在一起了,这个称之为构建(Build),但实际上是分为两个过程 的

对于代码

#include <stdio.h>

int main()
{
 /* code */
 printf("Hello World\n");
 return 0;
}

我们执行

$ gcc hello.c

通常有4个步骤 预处理(Prepressing)、编译(Compilation)、汇编(Assembly) 和链接(Linking)

wecom-temp-130728-0d1255b00883cc04e48b058ee2cd1ad8.jpg
  1. 预处理
$ gcc -E hello.c -o hello.i
  • 预处理会删除“#define”,展开宏定义
  • 处理预编译指令 "#if"等
  • 处理""#include",把包含的文件拷贝过来
  • 删除注释"//"等
  • 添加行号和文件名标识,方便编译时能够对应行号
  • 保留#pragma
  1. 编译
$ gcc -S hello.i -o hello.s

进行此法分析、语法分析、语义分析及优化产生汇编代码文件。

  1. 汇编
gcc -c hello.s -o hello.o

把汇编代码转变成机器码

  1. 链接

    需要链接很多.o文件才能让最终产物跑起来

wecom-temp-122385-37badb387440ef9eb93d7311eb7e0c1c.jpg

对于代码

array[index] = (index + 4) * (2 + 6);

词法分析

通过扫描器(Scanner)扫描,切割代码的字符序列为一列的记号(Token)

语法分析

通过词法分析器生成以表达式为节点的语法树

wecom-temp-158595-d844033672278ea9664e89fc3a269ec7.jpg

语义分析

这一步的目的是弄懂语句是否是合法的,比如两个指针做乘法就没什么意义。分为静态语义(在编译期确定)和动态语义,在运行期才能确定的语义。

wecom-temp-209450-55d385a6e27afb02bb5c0ed7b0e2d692.jpg

中间语言生成

将语法树转成中间代码,并进行优化,比如把一些可以编译器确定的计算入2+6=8这种给提前计算出来。

wecom-temp-144979-3c8743f596307066f0140be22a034fe2.jpg

目标代码生成与优化

编译器后端主要包括代码生成器和目标代码优化器,这两步会对目标代码进行优化,删除多余的指令,但是还没有确定变量的地址,这就需要用到链接器。

链接器

重定位 重新计算各个目标的地址的过程,因为修改过一次代码后,一些符号的目标地址肯定要发生改变。

符号 这个是从机器码到汇编的过程产生的,就是用来替代一些地址,它就是用来表示一个地址,可能是一段子程序(比如说函数)的起始地址,也可以是一个变量的起始地址

一个文件用到另外一个文件的函数或者变量,但是一开始又不知道这个函数的具体地址,链接要做的事就是把一些指令对其他符号地址的引用加以修正,让文件和文件之间的跳转可以有具体的地址。

链接过程包括 地址和空间分配、符号决议、重定位

wecom-temp-199089-d743498e8c787df436ab2312f91a29ec.jpg

比如目标文件B中有如下指令

movl $0x2a, var

这句相当于var = 42,假设var在目标文件A中,那么编译器编译B的时候一开始不知道var的目标地址,所以就在var那里打个补丁,叫做重定位入口(Relocation Entry),直到链接器去修正这个地址

wecom-temp-157629-1bd6cb911ce47e9f03d89ecbe23e9d71.jpg

相关文章

  • 2 编译和链接

    第二章 编译和链接词法分析语法分析语义分析中间语言生成目标代码生成与优化链接器 第二章 编译和链接 平时我们使用的...

  • 2章 编译和链接

    1. 从源码到可执行件: 4 步 2. 编译器 做了什么 3. 链接器 比 编译器 早出现 (1) 机器指令 + ...

  • 程序员的自我修养: 链接 装载 库

    第2部分 静态链接 第2章 编译和链接 禁止转载

  • 编译和链接

    编译和链接 预处理 编译 汇编 链接 预处理(prepress) 处理#开头的预编译指令。 #include:包含...

  • 编译和链接

    作为刚毕业没多久的非计算机学院出身的工科生,误打误撞的变成一个程序猿,因基础知识很薄弱,在此记录一些学习的过程。...

  • 编译和链接

    (摘自《程序员的自我修养》) 1. 被隐藏了的过程   当我们使用gcc来编译一个程序时,例如   运行结束后会生...

  • 编译和链接

    摘自《程序员自我修养》 对于平时的应用程序开发,我们很少关注编译和连接过程,因为通常的开发环境都是流行的集成开发环...

  • iOS常用面试题一

    200道常用的iOS题目 1、swift和oc的区别 没啥意义的题 2、编译链接 a) 编译 什么叫编译? ...

  • 《程序员的自我修养》第二部分

    第2章 编译和链接 流行的IDE把编译和链接合并到一起,这个过程叫构建(Build)IDE会提供默认配置,隐藏大量...

  • Linux 编译和链接程序

    Linux 编译和链接程序 使用编译器gcc g++Linux可执行程序编译步骤1、编译c/cpp文件 ->.o2...

网友评论

      本文标题:2 编译和链接

      本文链接:https://www.haomeiwen.com/subject/fkgvhdtx.html