【C语言】程序编译链接详解

目录

一、程序的翻译环境和执行环境

二、编译链接过程

2.1、程序编译过程

2.2、程序编译链接的阶段

2.2.1、预处理

2.2.2、编译

2.2.3、汇编

2.2.4、链接

2.2.5、整体过程

三、运行环境


一、程序的翻译环境和执行环境

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

第一种是翻译环境(由编译器完成),在这个环境中源代码转换为可执行的机器指令。

第二种是执行环境,它用于执行代码

二、编译链接过程

2.1、程序编译过程

一个源文件要经过编译,链接才能形成可执行程序。因此每个源文件经过编译器处理生成目标文件,多个生成的目标文件和链接库经过连接器处理生成可执行程序。

在vs2019下编译器是cl.exe,链接器是link.exe

连接器同时也会引入标准C函数库中任何被该程序所用到的函数

2.2、程序编译链接的阶段

2.2.1、预处理

1、进行头文件的包含,将头文件的相关内容包含进test.i文件中。(#include预处理指令)

在Linux环境下,头文件放在/usr/include目录下。

2、define定义符号的替换(#define预处理指令)

3、去注释

[hx@VM-24-7-centos 20240120-编译链接]$ vim test.c
                                                                                             
    1 #include<stdio.h>
    2 
    3 extern int Add(int,int);
    4 
    5 //定义MAX的值
    6 #define MAX 1000
    7 
    8 int main()
    9 {
   10     int x=MAX;                                                                                                     
   11     int a=10;
   12     int b=20;
   13     int c=Add(a,b);
   14     printf("%d\n",c);
   15 
   16     return 0;
   17 }
[hx@VM-24-7-centos 20240120-编译链接]$ gcc add.c -E -o add.i
[hx@VM-24-7-centos 20240120-编译链接]$ gcc test.c -E -o test.i
[hx@VM-24-7-centos 20240120-编译链接]$ ls
add.c  add.i  test.c  test.i

###  -E选项,让预编译后停下来
###  -o选项  编译结束后把结果放到test.i文件中

2.2.2、编译

把C语言代码翻译成汇编代码,进行词法分析,语法分析,语义分析,符号汇总

符号汇总一般是全局符号,全局变量,局部变量不会汇总进来(局部变量只能在函数内部使用)

本程序中,全局符号是Add,main

[hx@VM-24-7-centos 20240120-编译链接]$ gcc add.i -S
[hx@VM-24-7-centos 20240120-编译链接]$ gcc test.i -S
[hx@VM-24-7-centos 20240120-编译链接]$ ls
add.c  add.i  add.s  test.c  test.i  test.s
[hx@VM-24-7-centos 20240120-编译链接]$ vim test.s

### -S选项 编译结束后让程序停下来,结果保存在test.s中,不再往后走
    

2.2.3、汇编

符号汇总,形成符号表,并且将汇编指令转换成二进制指令最后生成test.o文件,汇编完成生成的目标文件经过连接器处理生成可执行程序。

[hx@VM-24-7-centos 20240120-编译链接]$ gcc add.i -c
[hx@VM-24-7-centos 20240120-编译链接]$ gcc test.i -c
[hx@VM-24-7-centos 20240120-编译链接]$ ls
add.c  add.i  add.o  add.s  test.c  test.i  test.o  test.s


### -c选项 汇编完成之后就停下来,结果保存在test.o中
2.2.4、链接

合并段表,合并符号表以及符号表的重定位(解决找到外部符号问题)

         符号表的合并和重定位,当最终生成可执行程序时,符号表也需要合并,main函数有确定的地址,Add出现了两个符号,要合并时需要重定位,但是知道test.o文件中Add的地址不是有效地址,是状态值,没有用处,但是add.o文件中符号表里的Add是有效地址,符号名一样就合并符号

        两个符号表合并就可以通过地址找到函数,解决的是如何跨文件找外部符号问题,可以链接其它文件的函数,当然外部符号没有定义的时候,就会出现链接报错。

在Linux环境下 test.o的可执行程序的格式是.elf,通过readelf工具可以看懂elf文件

通过加选项-s来查看test.o,add.o形成的符号表。

add.o test.o文件,按照elf文件格式组织的时候把文件分成各种各样的段,把相同段上的内容合并在一起,成为合并段表

[hx@VM-24-7-centos 20240120-编译链接]$ readelf test.o
Usage: readelf <option(s)> elf-file(s)
 Display information about the contents of ELF format files
 Options are:
  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I
  -h --file-header       Display the ELF file header
  -l --program-headers   Display the program headers
     --segments          An alias for --program-headers
  -S --section-headers   Display the sections' header
     --sections          An alias for --section-headers
  -g --section-groups    Display the section groups
  -t --section-details   Display the section details
  -e --headers           Equivalent to: -h -l -S
  -s --syms              Display the symbol table
     --symbols           An alias for --syms
[hx@VM-24-7-centos 20240120-编译链接]$ readelf test.o -s

Symbol table '.symtab' contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     9: 0000000000000000    74 FUNC    GLOBAL DEFAULT    1 main
    10: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND Add
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
[hx@VM-24-7-centos 20240120-编译链接]$ readelf add.o -s

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS add.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     8: 0000000000000000    20 FUNC    GLOBAL DEFAULT    1 Add

2.2.5、整体过程

        源文件要通过编译链接形成可执行程序,其中编译阶段就包括预处理,编译,汇编阶段生成目标源文件,链接是通过链接器将链接库和多个目标源文件链接在一起生成可执行程序,其中编译阶段的预处理过程是头文件包含,宏替换,去注释,编译阶段将C语言代码通过语法分析,词法分析,语义分析,符号汇总,最后生成汇编代码,汇编阶段就是将汇编代码翻译成二进制指令,生成符号表。链接阶段进行合并段表以及合并符号表和符号表的重定位。

        因此源文件经过编译链接,汇总符号,形成符号表,链接期间会把跨多个文件的符号进行链接,如果链接时有符号没有有效地址,就会有链接错误报错

三、运行环境

程序执行的过程:
1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序 的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2. 程序的执行便开始。接着便调用 main 函数。
3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈( stack ),存储函数的局部变量和返回 地址。程序同时也可以使用静态(static )内存,存储于静态内存中的变量在程序的整个执行过程 一直保留他们的值。
4. 终止程序。正常终止 main 函数;也有可能是意外终止。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

odoo16-API(Controller)带有验证访问的接口

odoo16-API&#xff08;Controller&#xff09;带有验证访问的接口 目前我使用odoo原生的登录token来验证登陆的有效性 废话不多说直接上代码 # 测试获取session_id import requests class GetOdooData(http.Controller):def getOdooToken(self):# http://localhost:8123访问…

要赢,且不止一次,2024创维汽车势不可挡!

随着除夕钟声的敲响&#xff0c;创维汽车迎来了全新的一年。过往取得的成绩已成为了历史&#xff0c;全新的未来还有待奋斗者们去开创。为辞旧迎新&#xff0c;创维汽车于2月22日及2月23日召开了“新春启航&#xff0c;共谋发展”营销会议&#xff0c;为2024做下全新布局。 创维…

【xss跨站漏洞】xss漏洞利用工具beef的安装

安装环境 阿里云服务器&#xff0c;centos8.2系统&#xff0c;docker docker安装 前提用root用户 安装docker yum install docker 重启docker systemctl restart docker beef安装 安装beef docker pull janes/beef 绑定到3000端口 docker run --rm -p 3000:3000 janes/beef …

【若依(ruoyi)】Java---如何在Apifox上传params参数--延伸--如何在Apifox上传Map类型参数

在使用若依开发过程中写接口的时候想在params中添加参数,但是使用params.key这种形式在后端是接收不到传过来的参数的,于是百般调研(百度),终于找到一个解决办法,就是在参数前后加上%5B和%5D,这两个参数会被编译为"["和"]",于是就对得上了,后端成功接受到参…

基于Java在线宠物店商城系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

【工具】阿莫智能设备之脱机烧录器K202C-1

注意&#xff0c;本文档仅仅是介绍烧录器的资料构成&#xff0c;并非烧录器的说明书&#xff0c;详细请看各对说明书及视频。 1. 资料图解 首先需要下载资料&#xff0c;通常稳定发布版本可以从 www.amomcu.cn 下载&#xff0c; 也可以向我们客服获取最新版本&#xff0c; 获…

学习负载均衡的算法

什么负载均衡 负载均衡是一种计算机技术&#xff0c;用于在多个系统、网络链接、硬盘驱动器、CPU等之间分配工作负载&#xff0c;以优化资源使用、最大化吞吐量、最小化响应时间、并避免任何单一资源的过载。在网络负载均衡的情况下&#xff0c;它可以帮助将网络流量有效地分配…

WebAPI [Swagger] 发布ISS不能生成xml文件问题记录

因为Swagger文件的注释是读取项目xml的。 除了Debug要输出xml&#xff0c;正式发布release时也要输出xml

Camtasia2024试用版最新核心功能介绍

Camtasia的试用版通常提供与正式版本相同的核心功能&#xff0c;但可能会有一些限制或水印。以下是试用版中可能包含的一些功能&#xff1a; 屏幕录制&#xff1a;试用版允许用户录制电脑屏幕上的活动&#xff0c;无论是全屏、特定区域还是特定窗口。用户可以选择录制光标、添加…

LeetCode LCR 055.二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在…

基于PID-bang-bang控制算法的卫星姿态控制matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于PID-bang-bang控制算法的卫星姿态控制。仿真输出控制器的控制收敛曲线&#xff0c;卫星姿态调整过程的动画。 2.系统仿真结果 3.核心程序与模型 版本&#xff1a;MATLAB…

c语言经典测试题3

1.题1 int a 248, b 4; int const *c 21; const int *d &a; int *const e &b; int const * const f &a; 请问下列表达式哪些会被编译器禁止&#xff1f; A: *c 32; B: *d 43 C: e&a D: f0x321f 我们来分析一下&#xff1a;const用来修饰变量是想其…

Kotlin filterIsInstance filterNotNull forEach

Kotlin filterIsInstance filterNotNull forEach fun main(args: Array<String>) {val i1 MyItem(1, 1)val i2: MyItem? nullval i3: Int 3val i4 "4"val i5 nullval i6 MyItem(6, 6)val list mutableListOf<Any?>(i1, i2, i3, i4, i5, i6)lis…

百度地图海量点方案趟坑记录(百度地图GL版 + MapVGL + vue3 + ts)

核心需求描述 不同层级有不同的海量图标展示底层海量图标需要展示文字拖动、放大缩小都需要重新请求数据并展示固定地图中心点&#xff08;拖动、放大缩小&#xff0c;中心点始终在地图中心&#xff09; 示例图片&#xff1a;&#xff08;某些图片涉及公司数据&#xff0c;就未…

靡语IT:Vue精讲(一)

Vue简介 发端于2013年的个人项目&#xff0c;已然成为全世界三大前端框架之一&#xff0c;在中国大陆更是前端首选。 它的设计思想、编码技巧也被众多的框架借鉴、模仿。 纪略 2013年&#xff0c;在Google工作的尤雨溪&#xff0c;受到Angular的启发&#xff0c;从中提取自…

unity学习(30)——跳转到角色选择界面(跳转新场景)

1.在scene文件夹中&#xff08;[siːn]&#xff09;&#xff0c;右键->create->scene&#xff0c;名字叫SelectMenu&#xff08;选择角色场景&#xff09;。 2.把新建场景拖拽到hierarchy[ˈhaɪərɑːki]中。 3.此时才能在file->build setting中Add open scene&…

图解李白的“朋友圈”

《长安三万里》作为2023年票房第一的国漫电影&#xff0c;以安史之乱为背景&#xff0c;从诗人高适的视角铺设了一幅绚丽的历史长卷&#xff0c;细细讲述“诗仙”李白跌宕起伏的一生&#xff0c;以及大唐盛世一路荣耀幻灭的唏嘘。同时&#xff0c;在这部动画电影中出现了多位大…

【了解机器学习的定义与发展历程】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱 简述概要 了解机器学习的定义与发展历程 知识图谱 机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09;是一门跨学科的学科&#xff0c;它使用计算机模拟或实现人类学习行为&#xff0c;通…

HTML5新婚、年会、各种聚会的现场抽奖活动(附源码)

文章目录 1.抽奖平台设计来源1.1 主界面效果1.2 抽奖效果1.3 中奖效果 2.效果和源码配置2.1 动态效果2.2 人员信息配置2.3 奖品信息配置2.4 抽奖音效配置2.5 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/deta…

UnityWebGL 设置全屏

这是Unity导出Web默认打开的页面尺寸 修改后效果 修改 index.html 文件 1.div元素的id属性值为"unity-container"&#xff0c;宽度和高度都设置为100%&#xff0c;意味着该div元素将占据整个父容器的空间。canvas元素的id属性值为"unity-canvas"&#xff…
最新文章