编译链接原理

2023-05-16

编译链接原理

编译阶段一共分为3部:预编译阶段,编译阶段,和汇编阶段。

我们先来看第一阶段:

预编译:

将源代码文件.c和相关的头文件.h等 预编译成一个.i文件

gcc -E hello.c -o hello.i (-E表示只预编译)

预编译阶段主要处理以”#”开始的预编译指令

主要处理规则如下:

①:将所有的”define”删除,展开所有的宏定义

②:处理所有条件预编译指令,比如“if”,“ifdef”,“ifndef”,“endif”,“else”

③:处理”#include”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,因为被包含的文件中可能还包含着其他文件。

④:删除所有的注释,比如“//”,“/**/”

⑤:添加行号和文件名标识,比如#2,“hello.c” 2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够产生行号。

⑥:保留所有的#pragma编译器指令,因为编译器要使用它们。

再来看第二阶段:

编译:

将预编译后的文件进行一系列词法分析,语法分析,语义分析及优化后生成相应的汇编代码文件

gcc -S hello.i -o hello.s (-S表示只编译)

gcc这个命令只是后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1, 汇编器as,链接器ld。

编译过程一般可以分为6步,扫描并词法分析,语法分析,语义分析,源代码优化,中间代码生成,和目标代码生成和优化。

①:词法分析

根据类似于有限状态机的算法可以轻松地将源代码的字符序列分割成一系列的记号。词法分析产生的记号一般分为如下几类:关键字,标识符,字面量(包含数字,字符串等),和特殊符号(如加号,等号)。

②:语法分析

语法分析器将由词法分析产生的记号进行语法分析,从而产生语法树(Syntax Tree)。

语法分析仅仅完成了对表达式的语法层面的分析,它并不了解这个语句是否真正有意义。

③:语义分析

对表达式所包含的真正意义进行确定,隐式类型转换会在这里进行,若转换不了,则进行报错。

由语义分析器来完成,经过语义分析阶段后,整个语法树的表达式都被标记了类型,如果有些类型需要做隐式类型转换,语义分析程序会在语法树中插入相应的转换节点。

④:中间代码生成

中间代码使得编译器可以被分为前端和后端。编译器前端负责生产机器无关的中间代码,

编译器后端将中间代码转换成目标机器代码。对于一些跨平台的编译器而言,可以根据不同的平台使用同一个前端和针对不同机器平台的数个后端。

现在的编译器往往在源代码级别会有一个优化过程,一般,像(2+6)这个表达式会被优化掉,直接优化成8。

源代码优化器往往会将整个语法树转换成中间代码,它是语法树的顺序表示,其实它已经非常接近目标代码了。

我们拿最常见的中间代码(三地址码)作为例子,最基本的三地址码是这样的:

x = y op z

这个三地址码表示将变量y和z进行op操作后,赋值给x。

⑤:目标代码生成和优化

编译器后端主要包括代码生成器,和目标代码优化器。

首先代码生成器将中间代码转换成目标机器代码

最后目标代码优化器对上述的目标代码进行优化,比如选择合适的寻址方式,使用位移来代替乘法运算,删除多余的指令等。

最后看第三阶段:

汇编:

汇编器是将汇编代码转换成机器可执行的二进制指令。按照汇编指令和机器指令的对照表一一翻译就可以了。

上面的汇编过程我们可以调用汇编器as来完成

as hello.s -o hello.o

或者

gcc -c hello.s -o hello.o

编译整个过程:使用gcc命令从.c文件一步生成.o文件

gcc -c hello.c -o hello.o

链接阶段:

链接过程主要包括了地址和空间分配,符号决议,和重定位等这些步骤。

其中包括合并各个section,调整段的起始位置以及段大小,进行符号解析,符号重定位。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译链接原理 的相关文章

  • EPICS的学习过程

    在此之前 xff0c 最好先学习下Linux系统的基本操作 一 了解什么是EPICS 了解EPICS base Channel Access IOC OPI 的概念 高能所内网可参考这些材料 xff1b 打开USPAS xff0c 熟悉其大
  • CentOS 7下ArchiveViewer的安装与使用

    1 下载 安装jdk 下载安装包https www oracle com java technologies downloads java8 xff1b 解压 xff1b 将 JAVA HOME bin路径添加到 PATH中 注意 xff1
  • CentOS7 安装 Archiver Appliance 的 Grafana服务

    1 安装 Grafana 7 采用rpm的安装方式 xff1a span class token function wget span https dl grafana com enterprise release grafana ente
  • AA中策略文件的使用

    一 AA策略文件 AA中关于存储策略设置的文件主要有两个 xff1a policies py archappl properties 每个appliance只有一个archappl properties和policies py文件 xff0
  • AA的管理

    1 AA的整体代码结构 AA代码的设计遵循了MVC模式 xff0c 将模型层 xff08 数据端 xff09 视图层 xff08 web客户端 xff09 控制层分离 数据端 xff08 M xff09 利用StoragePlugin接口建
  • CentOS 7下 VNC 服务的配置和开启、常见问题

    文章目录 1 X server Xvnc 和 VNC serverX Window SystemX ServerX ClientX Window ManagerDisplay ManagerX Window启动方式方式一 xff1a sta
  • AA部署中,修改Context属性造成的问题

    此处利用了https github com jeonghanlee epicsarchiverap env将AA安装在 opt epicsarchiverap 下 xff0c 并以系统服务的方式启停 问题产生原因 地球人都知道 xff0c
  • CentOS 7 下安装 Olog-es(Phoebus-olog)

    介绍报告 Olog es 服务端安装包 GitHub Olog phoebus olog Online logbook for experimental and industrial logging web服务端安装包 GitHub Olo
  • 视频监控系统安装和使用过程中的常见问题

    1 视频卡顿 花屏 当已确定POE供电距离在何时范围内时 xff0c 有可能是网线接线不规范或是网线损坏导致 对于POE供电距离较远 网络带宽较大的 xff0c 尽量连接在POE交换机的红口 xff08 红口保障 xff09 2 NVR的初
  • 关于CIDR地址的计算方法

    CIDR无类域间路由 xff0c 打破了原本的ABC类地址的规划限定 xff0c 使用地址段分配更加灵活 xff0c 日常工作中也经常使用 xff0c 也正是因为其灵活的特点使我们无法一眼辨认出网络号 广播地址 网络中的第一台主机等信息 x
  • EPICS CA请求能否成功的影响因素

    1 子网和广播域 子网掩码和广播域互为互补的网段 例如 xff1a 10 0 2 235的掩码为255 255 0 0 xff0c 则它所在的子网为10 0 0 0 xff0c 广播域为10 0 255 255 xff1b 192 168
  • 服务器采购和选型

    1 CPU 双路CPU xff0c 0号位和1号位 xff0c 只要0号位CPU正常 xff0c 服务器就能工作 xff0c 若1号位CPU故障 xff0c 服务器会报警 若0号位CPU故障 xff0c 1号位CPU正常 xff0c 服务器
  • CentOS 7自定义系统服务(以Phoebus-Olog为例)

    需要开启的服务 xff1a MongoDBElasticSearchPhoebus Olog后端服务Phoebus Olog web client前端服务 配置系统服务的方式 xff1a systemd 把spring boot项目配置为L
  • 在未联网的计算机中部署 yum 源和 EPICS 环境

    1 基本背景 EPICS 软件仓库 xff1a 192 168 206 234 8888 安装方式 xff1a yum 2 配置跳板机 跳板机功能 xff1a 借助ssh 隧道服务进行端口转发 xff0c 使未联网的计算机能够访问软件仓库
  • 在未联网计算机中部署Archiver Appliance(以Rocky Linux 8系统为例)

    由于计算机未联网 xff0c 而利用 epicsarchiverap env 工具进行安装的过程中需要一些联网下载安装包的操作步骤 xff0c 因此以下会给出相应的解决方法 总体思路就是 xff1a 对于一般性网址如 GitHub 等 xf
  • CentOS 7 / Rocky Linux 8 / Windows 10 系统启动 Chrony/NTP 服务

    本文内容 背景介绍1 Chrony NTP 的联系与区别2 关于 Chrony NTP 服务端 客户端的概念3 Chrony 核心组件 CentOS 7 Rocky Linux 8 系统启动 Chrony 服务1 服务状态查询2 服务配置3
  • 前端基础知识——CSS

    CSS CSS 基于 HTML 中的父子元素思想 CSS 有很多类似 Word 的排版功能 xff08 颜色 字体 文字环绕等 xff09 的属性 相关语法说明 xff1a 基本语法 xff1a 选择器 span class token p
  • GitLab的使用

    简介 xff1a Git xff0c GitHub与GitLab有什么区别 xff1f 官方网站 xff1a https docs gitlab com ee topics git 常用命令和使用方式 xff1a 看完这篇还不会用Git x
  • Archiver Appliance 事务处理流程

    当 Archiver Appliance 开始运行后发生了什么 xff1a mgmt服务 xff1a config DefaultConfigService java span class token function initialize
  • Archiver Appliance 建立集群时可能出现的问题

    0 背景知识 AA 集群中的各个节点 xff0c 完全是分布式结构 xff0c 并不存在主从关系 各个节点共享完全相同的 xff1a PVTypeInfo 数据库表PV查询权限和结果 xff08 在某一节点上查询所有 PV xff0c 也能

随机推荐

  • 关于python的新特性函数注释(定义函数时使用“:”及“ ->”符号)

    刷题的时候发现有的题目函数定义格式类型是这样的 xff1a def lengthOfLongestSubstring self s str gt int 这种定义方式完全没明白啥意思 xff0c 于是经过一番查找 xff0c 大体意思如下
  • Rocky Linux 8 安装实时内核

    方法一 xff1a yum 安装 在 etc yum repos d 目录下新建一个Rocky8 rt repo安装rt内核和相关工具 span class token function sudo span yum span class t
  • ununtu docker

    移除老版本 Docker sudo apt get remove docker docker engine docker io containerd runc 1 Tips xff1a 如果第一步你这里报了如下错误 xff1a E Coul
  • 如何确认当前使用的.net 版本 及 C# .net VS 版本之间的对应关系

    如何确认当前使用的 net 版本 及 C net VS 版本之间的对应关系 方法1 打开此电脑 xff0c 在地址栏中输入 systemroot Microsoft Net Framework 现在看到的就是目前使用的 net 版本 方法2
  • nuxt 获取不到localStorage,使用cookie持久化

    nuxt项目中在store和plugins的js文件里使用localStorage会报错 解决方案 xff1a 1 安装 cookie universal nuxt span class token function npm span i
  • 数据库连接报错提示connection is being used

    数据库连接报错 xff1a connection is being used 解决办法 xff1a 1 在已经保存的连接上上编辑 xff0c 测试连接成功 xff0c 但是点击连接就会一直提示 connection is being use
  • VsCode中git路径的设置(window系统)

    VsCode中git路径的设置 xff08 window系统 xff09 首先电脑里已经安装好了git并已经把git添加到环境变量中去了 xff08 这有部分在之前的帖子中有讲过 xff09 找到你的电脑里的git路径 先找到你的git安装
  • Qt报错汇总

    1 DirectShowPlayerService doRender Unresolved error code 0x80040266 IDispatch error 102 使用Qt的MediaPlayer控件时报的错 原因 xff1a
  • ubuntu18.04 ros 安装 gazebo9

    三 Gazebo安装 如果前面安装ros 的时候安装了gazebo 这里进行卸载 xff08 1 xff09 sudo apt get remove gazebo xff08 2 xff09 sudo apt get remove libg
  • CMake 常用总结一:CMake 单个文件目录

    引言 CMake 实践帮助我们对 CMake 有一个系统全面的了解 xff0c 并且有大量示例以供参考 xff0c 至少在实际项目中可以让我们有能力看懂并修改项目中现有的 CMake 阅读完 CMake 实践文档 xff0c 认为自己的任务
  • 面试(opencv)

    作者 xff1a 孙兔子 xff08 本人 xff09 链接 xff1a 面试题 xff08 opencv xff09 讨论帖 牛客网 来源 xff1a 牛客网 12 xff09 形态学梯度 复制代码 1 2 3 4 5 6 7 8 9 1
  • mysql锁系列之MDL元数据锁之一

    基础材料 xff1a centos7 5 mysql 5 7 24 当mysql运行一条SQL语句时 xff0c 在你预期的时间内 xff0c 没有完成时 xff0c 我们都会登陆到mysql数据库上想查看是不是出了什么问题 xff0c 通
  • 【转】TCP 网络状态图详解

    http blog csdn net wenqian1991 article details 40110703 在前面 xff0c 已经介绍了TCP协议的三路握手和四次挥手 如下图所示 xff0c TCP通信过程包括三个步骤 xff1a 建
  • Ubuntu2018安装Gazebo9

    很高兴大家可以阅读我的文章 xff0c 不胜荣幸 xff0c 希望我的经验能够给大家带来些许益处 xff01 Ubuntu2018安装Gazebo9 或许看到这篇文章的你是第一次接触到Gazebo xff0c 我也是 我写这篇文章的目的就是
  • 树莓派串口配置(c++)

    文章目录 前言一 wiringPi库是什么 xff1f 二 使用步骤1 安装库和接口介绍2 C 43 43 串口配置 总结注意点 xff1a 前言 最近做项目 xff0c 在树莓派上用到串口来实现通信功能 所以用c 43 43 写了个串口的
  • 不带头结点的单链表的实现

    不带头结点的单链表的实现 单链表是一种链式存取的数据结构 xff0c 用一组地址任意的存储单元存放线性表中的数据元素 链表中的数据是以结点来表示的 xff0c 每个结点的构成 xff1a 元素 数据元素的映象 43 指针 指示后继元素存储位
  • 顺序队列和链队列

    顺序队列和链队列 队列的定义 xff1a 队列是一种特殊的线性表 xff0c 是一种先进先出 xff08 FIFO xff09 的数据结构 它只允许在表的前端 xff08 front xff09 进行删除操作 xff0c 而在表的后端 xf
  • c++类模板

    类模板 什么是类模板 xff1f 模板的目的就是为了淡化数据类型的要求 xff0c 作出通用数据类型的模板 类中的成员变量和成员函数都牵涉到了数据类型 在成员函数 成员变量以及基类中包含有类型参数的类称为类模板 和函数模板一样 xff0c
  • 4G虚拟地址空间

    虚拟地址空间分布 对于每一个进程都会对应一个虚拟地址空间 xff0c 对于32位的操作系统 xff08 其指令的位数最大为32位 xff0c 因此地址码最多32位 xff09 xff0c 虚拟地址空间的大小为2 32 B即0 4GB的虚拟地
  • 编译链接原理

    编译链接原理 编译阶段一共分为3部 xff1a 预编译阶段 xff0c 编译阶段 xff0c 和汇编阶段 我们先来看第一阶段 xff1a 预编译 将源代码文件 c和相关的头文件 h等 预编译成一个 i文件 gcc E hello c o h