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

文章目录

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

翻译环境和运行环境

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.mzph.cn/news/774782.shtml

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

相关文章

WEB DDOS的安全策略

近年来网络攻击的数量和频率急剧上升&#xff0c;针对Web应用程序的DDoS海啸攻击就是其中增长非常迅速的一个种类。过去常见的HTTP/S洪水攻击正在大范围的转变为更难对付的Web DDoS海啸攻击&#xff0c;网络安全空间攻防对抗越演越烈&#xff0c;企业用户面临更加严峻的网络安全…

CCCorelib 点云RANSAC拟合平面(CloudCompare内置算法库)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 点云平面拟合的实质其实就是用一个拟合平面取代近似位于同一平面的点云,使点云中的所有点到拟合平面的距离平方和最小, 达到点云与拟合平面的高度吻合。已有的方法其实已有很多,如最小二乘法、特征值法等,本文将…

Vue 3中ref和reactive的区别

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Floyd算法 【多源最短路】模板

B3647 【模板】Floyd - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N1e210; const int inf0x3f3f3f; int n,m; int g[N][N]; void floyd() {for(int k1;k<n;k){for(int i1;i<n;i){for(int j1;j<n;j){g…

python工具方法 48 基于视觉大模型生成目标检测数据集

1、基本说明 1.1 lang-segment-anything Language Segment-Anything 是一个开源项目,它结合了实例分割和文本提示的强大功能,为图像中的特定对象生成蒙版。它建立在最近发布的 Meta 模型、segment-anything 和 GroundingDINO 检测模型之上,是一款易于使用且有效的对象检测…

取消自动设置的开机自启动(pywin32库)请勿仿照!否则可能对电脑造成损害。

本文使用创作助手。 要取消Python程序的开机自启动&#xff0c;可以通过删除注册表中相应的注册表项来实现。请按照以下步骤进行操作&#xff1a; 打开Windows注册表编辑器&#xff1a;按下 Windows R 键&#xff0c;输入 regedit&#xff0c;然后按下回车键。 导航到注册表…

1.简单使用SmartTable

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;Android Studio 在android上进行统计数据、列表、表格数据等信息展示是常有的需求。 在Github上有一个优秀的控件&#xff1a;smartTable 1.功能介绍 快速配置自动生成表格&#xff1b;自动计算表格宽高&#xff1b;表…

低功耗、低成本 NAS 的可能性

使用现状&#xff1a;多台工作电脑&#xff0c;家里人手一台&#xff0c;还在两个住处 有好几台工作电脑&#xff0c;不同电脑有不同的用途&#xff0c;最大的问题就是各个电脑上文件的同步问题&#xff0c;这里当然就需要局域网里的公共文件夹&#xff0c;在NAS的问题上查了网…

Openwrt下适配Samba

关于Samba samba是Linux和Unix平台的一款实现了SMB协议的软件&#xff0c;可以使得windows平台的主机也可以访问Linux和Unix平台主机共享出来的资源。 SMB协议(Server Message Block)是由微软开发的一种软件程序级的网络传输协议&#xff0c;基于NetBIOS&#xff0c;主要功用…

【Canvas与艺术】模拟八一电影制片厂电影片头效果

【缘起】 八一厂每部电影前都有其专有开头&#xff0c;如&#xff1a;https://www.ixigua.com/6799821997258834440?logTag2eacce76401e13f9efe7 这个片头可以用canvas模拟下来。 【关键点】 线型放射状粒子系统的运作。 立体感五角星的绘制。 【图例】 【代码】 <!D…

开放大学2024年春《幼儿园环境创设 050546》过程性考核作业二:撰写一所幼儿园活动环境创设现状分析评价报告参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 选择一所幼儿园&#xff0c;最好是你所在或者比较熟悉的园所&am…

单页面应用部署到iis上可以正常打开,刷新就404

当您遇到Dumi打包的网站部署到IIS上可以正常打开首页,但刷新页面时出现404错误的情况,这通常与以下几个方面有关: 路由处理: Dumi生成的项目通常基于SPA(Single Page Application)架构,使用前端路由来实现无刷新导航。这意味着大部分页面切换是在浏览器层面完成的,而不…

vc_red.msi 错误

建议将安装的软件解压&#xff0c;再安装&#xff0c;这样可以自动下载vc_red.msi. 不解压就会出现这个错误。

unity学习(73)——服务器异常--无法处理 123类型的数据包

服务器发送回的数据包&#xff0c;客户端根本读不出来&#xff0c;type都读不出来&#xff0c;拖了三天&#xff0c;把客户端翻了个底朝天&#xff0c;发现客户端一点问题都没有&#xff01; 所有的问题不是unity的模型问题&#xff0c;就是socket网络通信中断&#xff01; 1…

C++ 控制语句(一)

一 顺序结构 程序的基本结构有三种&#xff1a; 顺序结构、分支结构、循环结构 大量的实际问题需要通过各种控制流程来解决。 1.1 顺序结构 1.2 简单语句和复合语句 二 循环 2.1 for循环 语句流程图 注意&#xff1a;使用for语句的灵活性 三 while语句 四 do while语句

java springboot mybatisplus vue elementui python django vue 30套源代码 可用于接私活或毕设

java springboot vue elementui python django vue 30套源代码 Springboot vue3 elementplus 后台通用权限系统 代码生成器 (源码教程开发环境) Springboot vue2 elementui 后台通用权限系统 代码生成器(源码教程开发环境) Springboot vue2 elementui 物品出入库管理系统 (源…

【项目技术介绍篇】如何在本地运行若依项目

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

程序员也写歌啦

我的第一首AI原创歌曲《旅途的歌声》 身为 AI 重度患者的我&#xff0c;时刻关注着每天发布的各种 AI 产品。面对这些雨后春笋般的 AI 产品&#xff0c;我也早就没那么敏感了。 但是今天尝试着用 AI 生成了一个音乐&#xff0c;真的震惊到了我&#xff01; 不到一分钟&#…

Java中的序列化

Java中的序列化&#xff08;Serialization&#xff09;是一个将对象转换为字节序列的过程&#xff0c;以便可以在网络上传输或将其写入持久存储&#xff0c;如文件。这样&#xff0c;可以稍后在需要时重新构造这个对象&#xff0c;即反序列化&#xff08;Deserialization&#…

网络瞎复习

七层 应用进程 粘包问题以及如何理解是 TCP 面向字节流协议&#xff1f; 之所以会说 TCP 是面向字节流的协议&#xff0c;UDP 是面向报文的协议&#xff0c;是因为操作系统对 TCP 和 UDP 协议的发送方的机制不同&#xff0c;也就是问题原因在发送方。 先来说说为什么 UDP 是面…