C语言之编译和链接

news2024/9/24 9:25:29

C语言之编译和链接

文章目录

  • C语言之编译和链接
    • 翻译环境和运行环境
    • 1 翻译环境
      • 编译
        • 1.1.1 预处理(预编译)
        • 1.1.2 编译
          • 第一步:词法分析
          • 第二步:语法分析
          • 第三步:语义分析
        • 1.1.3 汇编
      • 链接
    • 2. 运行环境

翻译环境和运行环境

在ANSI C的任何一种实现中,都存在两个不同的环境
1. 翻译环境,在这个环境中将源代码转换成可执行的机器指令
2. 运行环境,在这个环境中用于实际实行代码

1 翻译环境

翻译环境又被分成两个部分编译链接
其中编译又被分为了三个部分预处理(预编译)编译汇编

在这里插入图片描述

  1. 每个.c文件都单独经过编译器编译处理产生对应的目标文件(.obj

TIPS:在windwos环境下的目标文件为.obj,Linux环境下的目标文件为.o

2.多个目标文件和链接库一起通过链接器处理生成最终的可执行程序

TIPS:链接库为运⾏时库(它是⽀持程序运⾏的基本函数集合)或者第三⽅库

编译

1.1.1 预处理(预编译)

在预处理阶段,会将源文件和头文件转换成.i为后缀的文件

预处理主要处理源文件中#开始的预编译指令

  1. 将所有的 #define 删除,并展开所有的宏定义
  2. 处理所有的条件编译指令 例如:#if #ifdef #elif #else #endif
  3. 处理#include 预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进
    ⾏的,也就是说被包含的头⽂件也可能包含其他⽂件
  4. 删除所有注释
  5. 添加⾏号和⽂件名标识,⽅便后续编译器⽣成调试信息等
  6. 或保留所有的#pragma的编译器指令,编译器后续会使⽤

简单来说在预处理阶段只是一些文本操作,并未将源代码转换二进制指令,生成.i文件

1.1.2 编译

编译阶段就是将预处理后的文件进行:词法分析、语法分析、语义分析及优化,生成对应的汇编代码文件(.s

假设有如下代码:

arr[index] = ( index + 4 ) * ( 2 + 6);
第一步:词法分析

将代码输入扫描器,扫描器的任务就是对代码进行简单的词法分析,将代码分割成一个个记号(关键字、标识符、字面量、特殊符号等)
上述代码就被分割成了16个记号

记号类型
arr标识符
[左方括号
index标识符
]右方括号
=赋值
(左圆括号
index标识符
+加号
4数字
右圆括号
*乘法
(左圆括号
2数字
+加法
6数字
右圆括号
第二步:语法分析

由语法分析器,对扫描出来的符号进行语法分析,从而生成以表达式为节点的语法树
在这里插入图片描述

第三步:语义分析

由语义分析器来完成语义分析,对表达式的语法层面分析,编译器所能做的分析是语义的静态分
析。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息
在这里插入图片描述

简单来说在编译阶段将源代码转换成汇编代码,生成.s文件

1.1.3 汇编

汇编器是将汇编代码转转变成机器可执⾏的指令,每⼀个汇编语句⼏乎都对应⼀条机器指令。就是根
据汇编指令和机器指令的对照表⼀⼀的进⾏翻译,也不做指令优化

简单来说在汇编阶段就是将编译阶段产生的汇编代码进一步转换成二进制指令,生成.o文件

链接

链接是⼀个复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才⽣成可执⾏程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤
链接解决的是⼀个项⽬中多⽂件、多模块之间互相调⽤的问题

在编译的过程中,会将出现的函数进行一个符号汇总

例如:
在add.c中定义了函数 Add函数 假设地址为0x100
在test.c中使用了函数 Add函数 假设地址为0x000 以及mian函数 假设地址为0x200
那么就会汇总ADD ADD main这三个符号

在汇编过程中,会将汇总的符号制成符号表

Add0x100
Add0x000
main0x200

在链接过程中,会符号表进行符号决议和重定位
由于Add是在add.c中定义的,所以会选择0x100这个地址作为函数的地址

Add0x100
main0x200

2. 运行环境

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

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

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

相关文章

Autosar信息安全入门系列01-SecOC基础介绍

本文框架 1. 概述2. SecOC基本概念2.1 SecOC是什么?2.2 新鲜度值与MAC值2.3 SecOC报文格式 3. SecOC报文发送及接收逻辑3.1 SecOC报文的发送3.2 SecOC报文的接收 1. 概述 本文为Autosar通信入门系列介绍,如您对AutosarMCAL配置,通信&#xf…

Vue中的日历组件 Calendar 实现 考勤打卡记录

日历组件 Calendar 可以自定义在页面添加内容。 实现效果图 1.由于Calendar没有右上角月份切换的API事件,可以给组件源码添加自定义添加一个事件 2.也可以通过自带的input事件来获取日历 3.vue页面完整代码 注释:this.$m(this.beginTime).format(…

linux C语言socket函数recv

recv 函数是在 Linux C 语言网络编程中用于从已连接的套接字接收数据的函数。它通常与 TCP 连接一起使用,但也可以用于 UDP(尽管对于 UDP,更常使用 recvfrom,因为它还可以接收发送方的地址信息)。 函数原型 recv 函数…

【漏洞复现】Hikvision SPON IP网络对讲广播系统命令执行漏洞(CVE-2023-6895)

文章目录 前言声明一、系统简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 Hikvision Intercom Broadcasting System是中国海康威视(Hikvision)公司的一个对讲广播系统。 声明 请勿利用文章内的相关技术从事非法测试,由于传播…

在 wsl-ubuntu 里通过 docker 启动 gpu-jupyter

在 wsl-ubuntu 里通过 docker 启动 gpu-jupyter 0. 背景1. 安装 docker-ce2. 安装 NVIDIA Container Toolkit3. 使用 nvidia-ctk 命令配置容器运行4. 通过 docker 运行 nvidia-smi5. 运行 gpu-jupyter6. 访问 gpu-jupyter7. 测试 gpu-jupyter 是否可以访问 cuda 0. 背景 今天突…

每日OJ题_算法_滑动窗口⑤_力扣904水果成篮

目录 力扣904. 水果成篮 解析及代码1(使用容器) 解析及代码2(开数组) 力扣904. 水果成篮 904. 水果成篮 - 力扣(LeetCode) 难度 中等 你正在探访一家农场,农场从左到右种植了一排果树。这…

stable-diffusion-webui 安装与运行

大家好,我是水滴~~ 本文主要介绍在各种显卡环境中,如何安装和运行 stable-diffusion-webui,包括:在 NVIDIA 显卡环境上安装、在 AMD 显卡环境上安装、在集显或小于 4G 显卡环境上安装。 文章目录 在 NVIDIA 显卡环境上安装下载配…

如何在业务代码中优雅使用责任链模式

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者…

LLM:RoPE位置编码

论文:https://arxiv.org/pdf/2104.09864.pdf 代码:https://github.com/ZhuiyiTechnology/roformer 发表:2021 绝对位置编码:其常规做法是将位置信息直接加入到输入中(在x中注入绝对位置信息)。即在计算 q…

mysql原理--锁

1.解决并发事务带来问题的两种基本方式 上一章唠叨了事务并发执行时可能带来的各种问题,并发事务访问相同记录的情况大致可以划分为3种: (1). 读-读 情况:即并发事务相继读取相同的记录。 读取操作本身不会对记录有一毛钱影响,并不…

爬虫笔记(一):实战登录古诗文网站

需求:登录古诗文网站,账号+密码+图形验证码 第一:自己注册一个账号+密码哈 第二:图形验证码,需要一个打码平台(充钱,超能力power!)或…

“GPC爬虫池有用吗?

作为光算科技的独有技术,在深入研究谷歌爬虫推出的一种吸引谷歌爬虫的手段 要知道GPC爬虫池是否有用,就要知道谷歌爬虫这一概念,谷歌作为一个搜索引擎,里面有成百上千亿个网站,对于里面的网站内容,自然不可…

网络爬虫采集工具

在当今数字化的时代,获取海量数据对于企业、学术界和个人都至关重要。网络爬虫成为一种强大的工具,能够从互联网上抓取并提取所需的信息。本文将专心分享关于网络爬虫采集数据的全面指南,深入探讨其原理、应用场景以及使用过程中可能遇到的挑…

php array_diff 比较两个数组bug避坑 深入了解

今天实用array_diff出现的异常问题,预想的结果应该是返回 "integral_initiate">"0",实际没有 先看测试代码: $a ["user_name">"测","see_num">0,"integral_initiate&quo…

leetCode-42.接雨水

📑前言 本文主要是【算法】——算法模拟的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一句&#xff…

Go语言基础快速上手

1、Go语言关键字 2、Go数据类型 3、特殊的操作 3.1、iota关键字 Go中没有明确意思上的enum(枚举)定义,不过可以借用iota标识符实现一组自增常亮值来实现枚举类型。 const (a iota // 0b // 1c 100 // 100d // 100 (与上一…

H - Least Common Multiple H - 最小公倍数

题目 The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. For example, the LCM of 5, 7 and 15 is 105. 一组正整数的最小公倍数 (LCM) 是最小的正整…

rabbitmq的介绍、使用、案例

1.介绍 rabbitmq简单来说就是个消息中间件,可以让不同的应用程序之间进行异步的通信,通过消息传递来实现解耦和分布式处理。 消息队列:允许将消息发到队列,然后进行取出、处理等操作,使得生产者和消费者之间能够解耦&…

使用 Kali Linux Hydra 工具进行攻击测试和警报生成

一、Hydra 工具和 Kali Linux 简介 在网络安全领域中,渗透测试是评估系统密码强度的重要组成部分。Hydra 是一款由黑客组织“The Hackers Choice”开发的开源登录破解工具,支持50多种协议。本教程将探索如何将 Hydra 与 Kali Linux 结合使用&#xff0c…

快快销ShopMatrix 分销商城多端uniapp可编译5端 - 升级申请(可自定义申请表单)

在企业或组织中,升级申请通常涉及到员工职位、权限、设备或者其他资源的提升或更新。创建一个可自定义的升级申请表单可以帮助更高效地收集和处理这类申请信息。以下是一个基本的步骤: 确定表单字段: 申请人信息:姓名、部门、职位…