C语言程序编译与链接(拓宽视野的不二之选)

news2024/10/6 3:41:07

文章目录

  • 翻译环境和运行环境
    • 翻译环境
    • 预处理
    • 编译
    • 汇编
    • 链接
  • 运行环境

翻译环境和运行环境

1,在ANSI C的任何⼀种实现中,存在两个不同的环境。

第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指					令(⼆进制指令)。
第2种是执⾏环境,它⽤于实际执⾏代码。

在这里插入图片描述

翻译环境

那翻译环境是怎么将源代码转换为可执⾏的机器指令的呢?这⾥我们就得展开开讲解⼀下翻译环境所做的事情。

其实翻译环境是由编译和链接两个⼤的过程组成的,⽽编译⼜可以分解成:预处理(有些书也叫预编译)、编译、汇编三个过程。

在这里插入图片描述

⼀个C语⾔的项⽬中可能有多个 .c ⽂件⼀起构建,那多个 .c ⽂件如何⽣成可执⾏程序呢?

  • 多个.c⽂件单独经过编译器,编译处理⽣成对应的⽬标⽂件。
  • 注:在Windows环境下的⽬标⽂件的后缀是 .obj ,Linux环境下⽬标⽂件的后缀是 .o
  • 多个⽬标⽂件和链接库⼀起经过链接器处理⽣成最终的可执⾏程序。
  • 链接库是指运⾏时库(它是⽀持程序运⾏的基本函数集合)或者第三⽅库。

在这里插入图片描述

预处理

在C语言中,预处理阶段是编译过程中的第一步,主要是通过预处理器对源代码进行处理,包括宏替换、头文件包含、条件编译等操作。下面详细解释一下预处理阶段的几个重要概念和操作:

  1. 头文件包含(Include Directives):
    #include 指令:用于包含其他文件的内容,分为尖括号包含系统头文件(如#include <stdio.h>)和双引号包含用户定义的头文件(如#include “myheader.h”)。

  2. 宏替换(Macro Replacement):
    宏定义:使用#define指令定义一个宏,如#define PI 3.14159。
    宏替换:预处理器会在编译前将代码中出现的宏名称替换为对应的值,比如将代码中的PI替换为3.14159。

  3. 条件编译(Conditional Compilation):
    条件编译指令:如#if、#ifdef、#ifndef、#elif、#else、#endif等,用于根据条件选择性地编译代码块。

  4. 其他预处理指令
    #undef:取消已定义的宏。
    #ifdef 和 #ifndef:判断某个宏是否已经定义。
    #error:在预处理时生成一个错误信息。
    #pragma:向编译器发出特定指令。

预处理器工作流程
1,将源文件中的头文件包含进来。
2,对源文件进行宏替换。
3,处理条件编译指令,根据条件编译部分代码。
4,生成一个经过预处理的中间文件,后缀为.i,供后续编译阶段使用。
5,删除所有的注释
6, 添加⾏号和⽂件名标识,⽅便后续编译器⽣成调试信息等

经过预处理后的.i⽂件中不再包含宏定义,因为宏已经被展开。并且包含的头⽂件都被插⼊到.i⽂件
中。所以当我们无法知道宏定义或者头⽂件是否包含正确的时候,可以查看预处理后的.i⽂件来确认。

编译

  1. 词法分析(Lexical Analysis):
    目的
    将源代码按照词法规则分割成单词(Token)序列。

    工作内容
    识别关键字、标识符、常量、运算符等单词,并生成对应的标记(Token)。生成标记流(Token Stream)作为下一步的输入。
    请添加图片描述

  2. 语法分析(Syntax Analysis):
    目的:
    将标记流转换成抽象语法树(Abstract Syntax Tree,AST)或语法分析树。

    工作内容:
    根据语法规则检查标记流是否符合语言语法规范。
    构建抽象语法树,表示源代码的结构和语法。

请添加图片描述

  1. 语义分析(Semantic Analysis):
    目的:
    进行语义检查,确保程序的语义正确。

    工作内容:
    检查类型匹配、变量的定义和使用是否正确。
    解析表达式,计算常量表达式的值。
    检查函数调用、返回值等语义正确性。

在这里插入图片描述

  1. 中间代码生成(Intermediate Code Generation):
    目的:
    将抽象语法树转换成中间代码表示。

    工作内容:
    生成一种中间表示形式,如三地址码、四元式等。
    将高级语言的结构转换成更加容易进行优化的形式。

  2. 优化(Optimization):
    目的:
    对中间代码进行优化,提高程序的执行效率。

    工作内容:
    利用各种优化技术,如常量传播、死代码删除、循环优化等,提高程序性能。
    生成更加高效的中间代码表示,以便后续的代码生成阶段使用。

  3. 代码生成(Code Generation):
    目的:
    将优化后的中间代码转换成目标机器代码。

    工作内容:
    根据目标机器的特性和指令集,将中间代码转换为机器指令。
    处理寄存器分配、指令选择等问题,生成最终的目标代码。

汇编

当将C语言代码转换为汇编语言时,主要涉及到编译器将高级语言代码翻译成等效的汇编语言代码。以下是详细介绍汇编语言的步骤:

  1. 指令表示
    汇编语言使用助记符(Mnemonics)来代表特定的机器指令,如mov用于数据传送、add用于加法运算等。
  2. 寄存器
    计算机有一组寄存器用于存储数据和执行操作,如通用寄存器(如eax、ebx)、数据寄存器(如edx)、地址寄存器(如esi、edi)等。
  3. 内存访问
    使用不同的寻址模式(如立即数偏移、寄存器间接寻址)来访问内存中的数据。
  4. 控制流
    汇编语言提供了跳转指令(如jmp)和条件跳转指令(如je、jne)来控制程序的执行流程。
  5. 过程调用
    使用call来调用函数,使用ret返回函数调用,需要处理函数参数传递和局部变量存储。
  6. 栈操作
    使用栈来保存函数调用过程中的返回地址、参数以及局部变量,通过push和pop指令来操作栈。
  7. 数据处理
    汇编语言提供了各种指令来进行数据处理,如移位指令、逻辑运算指令、算术运算指令等。
  8. 标志寄存器
    标志寄存器记录了运算结果的信息,如进位标志、零标志、符号标志等,影响程序的条件跳转。
    9.宏指令
    汇编语言支持宏定义,可以简化重复代码的书写,提高代码的可读性和维护性。

链接

链接是将多个目标文件(包括库文件)组合成一个可执行文件或动态链接库的过程。以下是链接过程的详细步骤:

  1. 符号解析(Symbol Resolution):
    目的:解析所有目标文件中的符号引用,确定它们对应的实际地址或存储位置。
    工作内容:
    遍历所有目标文件,收集每个符号(如函数名、全局变量名)的定义和引用信息。
    解析外部符号引用,确定这些符号最终在哪个目标文件或库文件中定义。
    2.重定位(Relocation):
    目的:修正目标文件中的相对地址,使其能正确地映射到最终的内存地址。
    工作内容:
    根据符号解析的结果,对所有涉及到的地址进行调整,确保它们能正确地指向符号的实际位置。
    生成包含所有修正地址的重定位表,以便在加载时进行修正。
  2. 地址空间分配(Address Allocation):
    目的:为目标文件中的变量和函数分配内存地址。
    工作内容:
    确定每个全局变量和函数在内存中的起始地址。
    处理重复定义和冲突,确保分配的地址不会发生重叠或冲突。
  3. 符号重命名(Symbol Renaming):
    目的:避免不同目标文件中的符号名字冲突。
    工作内容:
    对于静态链接,可以对不同目标文件中的相同符号进行重命名,以避免冲突。
    对于动态链接,通常使用全局符号表(Global Symbol Table)来管理符号名字,确保唯一性。
  4. 生成可执行文件或动态链接库(Executable/Dynamic Link Library Generation):
    目的:将经过符号解析、重定位等处理后的目标文件转换为最终的可执行文件或动态链接库。
    工作内容:
    将已经修改过的目标文件内容按照特定的格式组合成可执行文件或动态链接库。
    对于可执行文件,可能还需要添加一些运行时所需的信息,如程序入口点等。
  5. 符号表生成(Symbol Table Generation):
    目的:生成最终可执行文件或动态链接库中的符号表,记录符号名字和对应的地址信息。
    工作内容:
    生成包含所有符号信息的符号表,以便在加载时进行符号解析和重定位。

运行环境

1,程序必须载⼊内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。

2, 程序的执⾏便开始。接着便调⽤main函数。

3,开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程⼀直保留他们的值。

4,终⽌程序。正常终⽌main函数;也有可能是意外终⽌。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1549276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI Agent(LLM Agent)入门解读

1. 什么是AI Agent&#xff1f; AI Agent可以理解为一个智能体&#xff0c;包括感知模块、规划决策模块和行动模块&#xff0c;类似于人类的五官、大脑和肢体。它能帮助人类处理复杂的任务&#xff0c;并能根据环境反馈进行学习和调整。 五官可以理解为感知模块&#xff0c;大…

2024年上半年数学建模竞赛一览表(附赠12场竞赛的优秀论文+格式要求)[电工、妈杯、数维、五一等12场]

为了帮助大家更好地备战今年上半年十二场数学建模竞赛&#xff0c;我们为大家收集到了这十二场相关竞赛的优秀论文以及格式要求&#xff0c;具体内容如下所示。 资料获取 在文末 文中资料来源 名称竞赛官方网站天府杯https://www.tfmssy.org.cn/认证杯http://www.tzmcm.cn/i…

中国土壤厚度空间分布数据

土壤层次分为覆盖层 林溶层 淀积层 母质层&#xff0c;其中在林溶层中的最上面那层就是我们通常说的土壤厚度在这一层中&#xff0c;这一层也被称为腐殖层&#xff0c;是肥力性质最好的一层&#xff0c;植物根系和微生物也集中在这一层。至于覆盖层在森林土壤中比较常见&#x…

零基础学python之高级编程(6)---Python中进程的Queue 和进程锁,以及进程池的创建 (包含详细注释代码)

Python中进程的Queue 和进程锁,以及进程池的创建 文章目录 Python中进程的Queue 和进程锁,以及进程池的创建前言一、进程间同步通信(Queue)二、进程锁&#xff08;Lock&#xff09;三、创建进程池Poorpool 类方法: End! 前言 大家好,上一篇文章,我们初步接触了进程的概念及其应…

matlab实现神经网络

一、原理 人工神经网络是具有适应性的简单神经元组成的广泛并互连的网络&#xff0c;它的组织能够模拟生物神经系统对真实世界物体作出的交互式反应。人工神经网络具有自学习、自组织、较好的容错性和优良的非线性逼近能力 将神经网络的学习能力引入到模糊系统中&#xff0c;…

Zabbix 配置使用

目录 配置流程 添加组机组 添加模板 添加主机 配置图形 配置大屏 Monitoring 配置地图 最新数据 故障 使用IT服务 使用报表 资产管理 全局搜索 导入导出 用户权限 用户组权限 用户 匿名用户 调试模式 与 LDAP 对接 维护模式 故障确认 批量更新 配置流程…

35.HarmonyOS App(ArkUI)使用父组件@Builder装饰的方法初始化子组件@BuilderParam报错

HarmonyOS App(ArkUI)使用父组件Builder装饰的方法初始化子组件BuilderParam报错 Type void is not assignable to type () > void. <tsCheck> 去掉括号()就可以了 装饰器&#xff1a; 用于装饰类、结构、方法以及变量&#xff0c;并赋予其特殊的含义。如上述示例中En…

fastadmin学习01-windows下安装部署

下载源代码 官网 安装 解压&#xff0c;然后使用phpstorm打开 修改配置文件 创建数据库 -- drop database fastadmin01; create database fastadmin01;这样fastadmin就部署好了 访问主页也能看到前台页面

基于OneAPI+ChatGLM3-6B+FastGPT搭建LLM大语言模型知识库问答系统

搭建大语言模型知识库问答系统 部署OneAPI部署一个LLM模型部署嵌入模型部署FastGPT新建FastGPT对话应用新建 FastGPT 知识库应用 部署OneAPI 拉取镜像 docker pull justsong/one-api创建挂载目录 mkdir -p /usr/local/docker/oneapi启动容器 docker run --name one-api -d …

LeetCode讲解算法2-数据结构[栈和队列](Python版)

文章目录 一、栈1.1 栈的定义1.2 栈的实现分析步骤1.3 栈的应用匹配圆括号匹配符号模2除法&#xff08;十进制转二进制&#xff09;进制转换 二、队列2.1 单向队列2.2 双端队列2.3 队列的应用验证回文串滑动窗口最大值 一、栈 1.1 栈的定义 栈是一种线性数据结构&#xff0c;栈…

STM32的SPI通信介绍

SPI简介 SPI:串行外设接口,与IIC一样都是通用数据总线。四根通信线&#xff1a;SCK&#xff0c;MOSI&#xff08;DO&#xff09;&#xff0c;MISO&#xff08;DI&#xff09;&#xff0c;SS。同步&#xff08;共用一根时钟线&#xff09;&#xff0c;全双工&#xff08;数据发…

js算法记录

> 更多请前往 https://www.passerma.com/article/86 滑动窗口 1 给定一个矩阵&#xff0c;包含N*M个整数&#xff0c;和一个包含K个整数的数组。现在要求在这个矩阵中找一个宽度最小的子矩阵&#xff0c;要求子矩阵包含数组中所有的整数 function minSubmatrixWidth(mat…

Openstack创建和操作实例,实现与外部网络通信

一、熟悉OpenStack图形界面操作 1、了解Horizon项目 Horizon项目 各OpenStack服务的图形界面都是由Horizon提供的。Horizon提供基于Web的模块化用户界面。Horizon为云管理员提供一个整体的视图。Horizon为终端用户提供一个自主服务的门户。Horizon由云管理员进行管理与控制&a…

SpringBoot学习笔记一、SpringBoot应用初创建以及应用

一、创建SpringBoot的两种方式 1.Spring Initializr方式创建 &#xff08;1&#xff09;第一步在IDEA中选择 File-->NEW-->Project &#xff0c;选择 Spring Initializr &#xff0c;指定Maven坐标、包名、指定 JDK 版本 1.8 &#xff0c;然后点击Next 。如下图&#x…

修改Jupyter Notebook的默认路径,以及在PowerShell中自定义其启动路径

修改Jupyter Notebook的默认路径&#xff0c;以及在PowerShell中自定义其启动路径 设置 Jupyter Notebook 配置文件&#xff0c;修改默认路径要在PowerShell中设置自定义的启动脚本&#xff0c;以确保Jupyter Notebook能够自动定位到当前路径设置后的效果 在使用Jupyter Notebo…

遇到了问题,Firepower 2140配置带外IP时报错 commit-buffer failed

onsite we have a cisco firepower 2140 device which run ASA as we try to modify the 2140 OOB mgmt ip by CLI, we got an error why ? 经过查询发现&#xff0c;需要进入ASA里面打上以下这条命令&#xff0c;并重启ASA 1 修改模式并重启 ciscoasa# configure termina…

C语言例4-15:从键盘输入一个整数,求其绝对值并输出。

代码如下&#xff1a; //从键盘输入一个整数&#xff0c;求其绝对值并输出。 #include<stdio.h> int main(void) {int n;printf("输出一个整数&#xff1a; \n");scanf("%d",&n); //从键盘输入一个整数保存至变量nif(n<0) //…

Python爬虫之爬取网页图片

当我们想要下载网页的图片时&#xff0c;发现网页的图片太多了&#xff0c;无从下手&#xff0c;那我们写一个脚本来爬取呗。 这次的脚本是专门针对某个外国网站使用的&#xff0c;因此仅供参考思路。 在测试的过程中&#xff0c;我发现网站使用了发爬虫机制&#xff0c;具体就…

连接数据库(MySQL)的JDBC

目录 JDBC简介快速入门API详解DriverManager&#xff08;驱动管理类&#xff09;注册驱动&#xff1a;获取数据库连接(对象)&#xff1a; Connection&#xff08;数据库连接对象&#xff09;获取执行SQL的对象管理事务 Statement(执行SQL语句)执行DML、DDL语句执行DQL语句 Resu…

【LLM多模态】Cogvlm图生文模型结构和训练流程

note Cogvlm的亮点&#xff1a; 当前主流的浅层对齐方法不佳在于视觉和语言信息之间缺乏深度融合&#xff0c;而cogvlm在attention和FFN layers引入一个可训练的视觉专家模块&#xff0c;将图像特征与文本特征分别处理&#xff0c;并在每一层中使用新的QKV矩阵和MLP层。通过引…