C/C++——代码的编译和运行

2023-05-16

1. 编译过程

每种高级语言都有对应的编译器,而且针对不同指令集架构的CPU会提供不同的编译器。本文以C语言为例,CPU指令集架构不做前提约束,实际上同一种语言也只有在狭义的编译阶段有所区别,其他阶段的处理,如二进制文件处理等待均类似。

C语言的编译有两种方式,一种是本地编译(在一个平台上编译该平台运行的程序),另一种是交叉编译(在一个平台上编译供另一个平台运行的程序)

  • 编译的功能
  1. 将高级语言转换为处理器能够执行的二进制代码。
  2. 对编程语言进行语法检查核逻辑检查
  3. 分配寄存器和内存地址(存储器)
  4. 代码优化
  • 编译过程
    C语言的翻译可以分为四个阶段:预编译阶段编译阶段,汇编阶段,链接阶段
  1. 预编译阶段
    主要处理文件中宏定义,注释,以及将头文件插入到主代码中,生成扩展名为“.i”的文件,替换原来的.c文件(原文件保留)。
  2. 编译阶段
    将代码转化成汇编语言或某种中间代码。编译器首先会检查代码的规范性,是否有语法错误等,以确定代码实际要做的工作;检查完毕后转换为底层机器可处理的汇编语言,即生成.s文件替换.i文件。

    该阶段会进行优化处理,除了对中间代码的结构进行优化外,还会充分利用硬件寄存器中存储的变量值,减少内存访问次数;根据指令执行特点(RSIC,CSIC,流水线等)对指令进行调整
  3. 汇编阶段
    将汇编语言直接映射为二进制码,以二进制码格式的指令将会被打包封存成可重定位的目标程序的格式,生成.o文件替代原来的.s文件。.o文件由段组成,且至少有两个段:代码段和数据段。代码段主要包含程序的指令,数据段主要是各种全局变量或静态数据。

    UNIX环境下会生成三个目标文件:
    1) 可重定位文件:其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
    2) 共享的目标文件:这种文件存放了适合于在上下文里链接的代码和数据。
    3) 可执行文件:包含了一个可以被操作系统创建一个进程来执行之的文件。
     
  4. 链接阶段
    将多个.o文件合并整合成一个可执行文件。上图表现的是一个动态链接过程。

    该阶段的三个步骤:
    1)将代码和数据模块象征性地放入内存
    2)决定数据和指令标签的地址
    3)修补内部和外部引用

编译后生成的elf后续处理参考:C/C++——elf文件分析_KGback的博客-CSDN博客

  • 2. 运行库和标准库

参考:glibc是什么_runtime是什么_喜欢数学一辈子的博客-CSDN博客

查询动态链接库参考链接:nm命令详解 - 二狗啸地 - 博客园

2. GCC编译

1 选项

参考:

  • 编译选项
  • 链接选项
  1. -nostdlib
    链接时,请勿使用标准的系统启动文件或库。没有启动文件,只有指定的库才传递给链接器,选项指定系统库的链接,例如 -static-libgcc 或-shared-libgcc,否则也将被忽略。
  2. -lm
    链接数学函数库
  • 一些特殊写法
  1. 缺省的写法,例如某字符串前加weak
    指如果定义了该字符串(可能是函数或者变量),则使用新的字符串,如果没有,则用weak后面的字符串

2 error

  1. undefined reference to 'xxxx'
    缺少某个库,用 -l参数将库加入。Linux的库命名是一致的,一般为libxxx.so,或libxxx.a,libxxx.la,那么如要链接某个库就用-lxxx,去掉头lib及"."后面的so,la,a等即可。  因为数学函数位于libm.so库文件中(通常在/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找.
  2. error: confilicting types for ""
    这种情况往往出现在函数实现文件中,未在头部声明或声明的位置位于函数使用的位置之后;
    解决办法:将函数声明放到文件靠前位置;

3. 函数调用时资源分配和进程调度

  1.  发生函数调用时,在执行该函数前,先将这次调用中需要用到的参数保存,方便取用
  2. 将控制权移交给这次调用的功能函数
  3. 根据情况为函数申请一定的本地存储空间,满足函数存储过程中的存储需求
  4. 执行该函数的功能调用
  5. 执行完成后,将结果数据保存好,便于主进程获取,同时还原函数执行过程中使用过的寄存器值,恢复先前分配的存储空间。
  6. 将控制权转移给主进程
  • 变量的要素
  1. 名字
  2. 类型
  3. 地址
  4. 作用域
  5. 生存期
  • 堆栈

假设一个过程,编译器需要使用多于4个参数寄存器和两个返回值寄存器。由于任务完成后必须消除踪迹,因此调用者使用的任何寄存器都必须恢复到过程调用前所存储的值。这种情况可以看成是需要将寄存器换出到存储器的一个例子。

换出寄存器的最理想的数据结构是栈——一种后进先出的队列,栈需要一个指针指向栈中最新分配的地址,以指示下一个过程放置换出寄存器的位置,或是寄存器旧值的存放位置。在每次寄存器进行保存或恢复时,栈指针以字为单位进行调整,由此将数据放入栈中称为压栈,从栈中移除数据称为出栈

栈:被组织成后进先出队列形式并用于寄存器换出的数据结构
栈指针:指示栈中最近分配的地址的值,它指示寄存器被换出的位置,或寄存器旧值的存放位置
压栈:向栈中增加元素
出栈:向栈中移除元素

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

C/C++——代码的编译和运行 的相关文章

随机推荐

  • 【图像处理】特征点算法整理总结

    特征点检测 1 Susan SUSA xff08 Smallest Univalue Segment Assimilating Nucleus xff09 算子是一种高效的边缘和角点检测算子 xff0c 并且具有结构保留的降噪功能 原理 用
  • 图像特征点匹配算法

    sift https blog csdn net weixin 38404120 article details 73740612 https blog csdn net abcjennifer article details 763968
  • 算法目标检测面经

    1 自我介绍 2 简历上的项目 网易雷火 AI研究员 1 ResNet FCN Fasterrcnn 2 膨胀腐蚀的原理 3 均值滤波的原理 时间复杂度 怎么优化 4 第k大的数 topK个数 网易互娱预研 深度学习计算机视觉 1 语义分割
  • 图像配准(Image Registration)简介

    图像配准在目标检测 模型重建 运动估计 特征匹配 xff0c 肿瘤检测 病变定位 血管造影 地质勘探 航空侦察等领域都有广泛的应用 每一种配准方法通常都针对某个具体问题而设计的 xff0c 众多方法中 xff0c 唯一的共性就是每个配准问题
  • SSD算法详解

    转载 xff1a https blog csdn net ytusdc article details 86577939 SSD github https github com weiliu89 caffe tree ssd SSD pap
  • 深度学习-目标检测评估指标P-R曲线、AP、mAP

    基本概念 P R曲线中 xff0c P为图中precision xff0c 即精准度 xff0c R为图中recall xff0c 即召回率 Example 下面通过具体例子说明 首先用训练好的模型得到所有测试样本的confidence s
  • 使用gitlab初次上传代码

    提要 项目开发中需要使用gitlab来管理代码 xff0c 将自己开发的模块上传到gitlab 第一次使用这个代码管理仓库 xff0c 记录一下 方法 1 首先注册gitlab的账号 这个在百度上搜一下gitlab的官网 xff0c 进去后
  • Keil5添加.c文件与.h文件的方法-导入支持库-新大陆物联网竞赛-Lora模块&NBIOT模块例程-添加导入文件

    一 概述 在某些情况下 xff0c 我们使用现用的物联网开发例程 xff0c 例如新大陆物联网的Lora与NBIOT的例程 xff0c 我们对其例程内目前所有的库不满意 xff0c 不足以实现开发需要的功能 xff0c 我们需要在原有工程上
  • 初探DSO-SLAM并运行dso_ros

    最近在做SLAM相关的工作 xff0c 用思岚的A2激光雷达在turtlebot3上测试SLAM建图效果 xff0c 感觉还是不错的 由于项目在方案上还没有确定选择哪种作为SLAM的最终方案 xff0c 在我测试奥比中光ASTRA mini
  • 虚拟机中安装CMake工具

    https www cnblogs com yanqingyang p 12731855 html
  • 寻路系统:动态障碍物

    寻路的相关参数 需要先勾选 游戏场景中所有需要烘焙路径信息的游戏对象状态为 static 然后点开windos菜单下的navigation窗口进行烘培 Navigation Static xff1b 表示该游戏对象是否参与导航网格的烘培 G
  • Ubuntu18.04下使用cmake编译一个OpenCV程序(编写CMakeLists.txt文件)

    导航 1 安装OpenCV1 1首先安装OpenCV 1 2定位OpenCV 2 创建一个项目3 编写一个基础OpenCV程序4 编写CMakeLists txt文件 为了记录以及防止遗忘 xff0c 备份一个大致能满足运行的CMakeLi
  • linux下最全curl命令使用方式学习和拓展

    为什么要使用curl命令 xff1f curl命令可以帮助我们在linux服务内部通讯 xff0c 排查接口是否能够正确调用 xff0c 外网的接口是否有防火墙限制 xff0c 内网的请求可以快速帮我们获取接口参数返回 xff0c 并且调试
  • 【传感器标定】kalibr 标定工具箱问题汇总

    文章目录 写在前面一 运行一段时间报错 96 Spline Coefficient Buffer Exceeded Set larger buffer margins 96 的解决方法1 问题描述2 解决方法参考链接 写在前面 kalibr
  • C++中的Vector存放指针的清空问题

    C 43 43 中的Vector存放指针的清空问题 一 写在前面二 参考做法参考链接 这两个链接写得挺好 xff0c 可以参考下 一 写在前面 C 43 43 很难的一个重要原因就是内存管理的问题 xff0c 因为你既要管理申请内存 xff
  • find_package(xxxx REQUIRED)找不到路径的全平台通用解决办法

    相信刚学cmake c 43 43 的朋友们在编译的时候一定被这个问题折磨许久哈 然后怎么搜怎么添加都有问题 xff0c 仔细研究了我才发现这个地方不同的索引机制 xff0c 但是表面上都是 find package xxxx REQUIR
  • STC51-串口通信

    1 并行与串行基本通信方式 随着单片机系统的广泛应用和计算机网络技术的普及 xff0c 单片机的通信功能愈来愈显得重要 单片机通信是指单片机与计算机或单片机与单片机之间的信息交换 xff0c 通常单片机与计算机之间的通信我们用的较多 通信有
  • qt种实现搜索栏功能

    引言 在搜索栏种输入要搜索的文本 xff0c 就会出现相关联的文本提示 xff0c 这是可以通过鼠标选中要搜索的文本 xff0c 或者通过上下键选中要搜索的文本 效果 效果图如下所示 xff1a 实现 下面是相关的代码实现 xff0c 读者
  • orangePi3 TLS烧录启动、wifi配置和ssh登录、烧录进内置emmc flash

    orangePi3 TLS烧录启动 wifi配置和ssh登录 烧录进内置emmc flash 烧录镜像到TF卡启动 镜像下载 官方镜像地址 xff1a http www orangepi cn html hardWare computerA
  • C/C++——代码的编译和运行

    1 编译过程 每种高级语言都有对应的编译器 xff0c 而且针对不同指令集架构的CPU会提供不同的编译器 本文以C语言为例 xff0c CPU指令集架构不做前提约束 xff0c 实际上同一种语言也只有在狭义的编译阶段有所区别 xff0c 其