程序从编译到运行

news2024/9/21 16:21:19

一、程序的编译流程(以 C 语言为例)

编译一个 C 程序从可以分为四个阶段:预处理 --> 编译(生成汇编代码)--> 汇编 --> 链接。

下面以大家最熟悉的 hello world 程序为例,编译器为 linux 下的 gcc。下面是 hello.c 文件的内容:

#include <stdio.h>

#define HELLO "hello world marco\n"

int main()
{
#ifdef HELLO
        printf(HELLO);
#else
        printf("hello world\n");
#endif
        return 0;
}

使用 gcc 直接编译可以生成一个 a.out 的可执行文件:

gcc hello.c

执行该文件可以打印 hello world: 

 

下面我们把几个步骤分开执行来理解每个步骤所完成的工作。 

1.1 预处理(Preprocessing)

预处理完成的工作:

  1. 头文件包含:将 #include 的内容复制到 .c 文件里面,如果 .h 文件内还有 .h 文件,则进行递归替换。
  2. 宏定义替换:将 #define 的内容进行替换。
  3. 条件宏:如 #ifdef,#ifndef,#else,#elif,#endif等,预处理只保留条件满足的代码。
  4. 去掉注释。

使用 gcc 的 -E 选项可以让 gcc 只执行预处理步骤:

gcc -E hello.c -o hello.i

查看预处理生成的 hello.i 文件可以发现文件的 #include <stdio.h> 被 stdio.h 头文件的内容所替换,#define 的 HELLO 宏也被替换到代码中,并且代码只保留了 #ifdef 条件为真的部分的代码:

1.2 编译(Compile)

编译完成的工作: 

  1. 检查词法和语法规则,如果有问题则报错。
  2. 将预处理生成的代码转换成汇编代码。

使用如下命令执行编译步骤:

gcc -S hello.i -o hello.s

生成的 hello.s 文件内容如下: 

 

1.3 汇编(Assemble) 

汇编过程将编译生成的汇编代码(hello.s)转换成机器码,生成目标文件(hello.o),是二进制格式。

使用如下命令执行汇编步骤: 

gcc -c hello.s -o hello.o

1.4 链接(Link) 

C/C++代码经过汇编之后生成的目标文件(*.o)并不是最终的可执行二进制文件,而仍是一种中间文件(或称临时文件),目标文件仍然需要经过链接 (Link) 才能变成可执行文件

既然目标文件和可执行文件的格式是一样的(都是二进制格式),为什么还要再链接一次呢?
因为编译只是将我们自己写的代码变成了二进制形式,它还需要和系统组件(比如标准库、动态链接库等)结合起来,这些组件都是程序运行所必须的
链接(Link)其实就是一个“打包”的过程,它将所有二进制形式的目标文件(.o)和系统组件组合成一个可执行文件。完成链接的过程也需要一个特殊的软件,叫做链接器(Linker)

使用如下命令完成最后的链接操作:

gcc -o hello hello.o

执行链接生成的可执行文件:

二、C语言存储空间的布局

C 程序编译后生成的目标文件由下面几个部分组成:

  1. 正文段(code segment/text segment,.text 段):也被称为代码段,通常是用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且该内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常量,例如字符串常量等。CPU执行的机器指令部分。( 存放函数体的二进制代码 )
  2.  只读数据段(read only data segment,.rodata 段):只读数据段是程序使用的一些不会被改变的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要修改,因此只需放在只读存储器中。
  3. 已初始化读写数据段(data segment,.data 段):通常用来存放程序中已初始化全局变量(或被 static 修饰的已初始化局部变量)的一块内存区域,数据段属于静态内存分配。已初始化读写数据段(RW data,.data)指的是在程序中声明,并且具有初值的全局变量,或者是被 static 修饰的已初始化局部变量,这些变量需要占用存储器空间,在程序执行时它们需要位于可读写的内存区域,并具有初值,以供程序读写。
  4. BSS 段(bss segment,.bss段):通常用来存放程序中未初始化的全局变量(或被 static 修饰的未初始化局部变量)的一块内存区域。BSS是英文 Block Started by Symbol 的简称,BSS 段属于静态内存分配。未初始化数据是在程序中声明,但是不具有初值的变量,这些变量在程序运行之前不需要占用存储空间。读取BSS段大小,然后在内存中紧跟data段之后分配空间,并且清零(这也是为什么全局表量和static局部变量不初始化会有0值得原因)。 C++中,已经不再严格区分 bss 和 data了,它们共享一块内存区域。静态存储区包括bbs段和data段。
  5. 堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用 free 等函数释放内存时,被释放的内存从堆上被剔除(堆被缩减)。一般由程序员分配释放(new/malloc/calloc delete/free),若程序员不释放,程序结束时可能由 OS 回收。注意:它与数据结构中的堆是两回事,但分配方式倒类似于链表
  6. 栈(stack):栈又称堆栈,是用户存放程序临时创建的局部变量,也就是我们函数大括号 "{}" 中定义的变量(不包括 static 声明的变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且等调用结束后,函数的返回值也会被存放在回栈中。由于栈的先进先出特性,所有栈特别方便用来保存/恢复调用现场。从这个意义上讲,把堆栈看成一个寄存、交换临时数据的内存区。由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

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

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

相关文章

C语言实现斐波那契数列的多种方法

斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为“兔子数列”。对于解决此类问题方法有四&#xff0c;前两…

代码随想录算法训练营第三十九天 | LeetCode 62. 不同路径、63. 不同路径 II

代码随想录算法训练营第三十九天 | LeetCode 62. 不同路径、63. 不同路径 II 文章链接&#xff1a;不同路径 不同路径II 视频链接&#xff1a;不同路径 不同路径II 1. LeetCode 62. 不同路径 1.1 思路 本题是个二维矩阵&#xff0c;因此 dp 数组也定义为二维的&…

select...for update 锁表了?

在MySQL中&#xff0c;事务A中使用select...for update where id1锁住了&#xff0c;某一条数据&#xff0c;事务还没提交&#xff0c;此时&#xff0c;事务B中去用select ... where id1查询那条数据&#xff0c;会阻塞等待吗&#xff1f; select...for update在MySQL中&#…

chatgpt 安卓版本提供google play商店版本太旧更新方法

多击play商店版本&#xff0c;开启开发者模式&#xff0c;再点击更新play商店。会自动下载最新版安装。记得开梯子。

太极培训机构展示服务预约小程序的作用如何

太极是适合男女老幼的&#xff0c;很多地方也有相关的学校或培训机构&#xff0c;由于受众广且不太受地域影响&#xff0c;因此对培训机构来说&#xff0c;除了线下经营外&#xff0c;线上宣传、学员获取和发展也不可少。 接下来让我们看下通过【雨科】平台制作太极教培服务预…

面试算法45:二叉树最低层最左边的值

题目 如何在一棵二叉树中找出它最低层最左边节点的值&#xff1f;假设二叉树中最少有一个节点。例如&#xff0c;在如图7.5所示的二叉树中最低层最左边一个节点的值是5。 分析 可以用一个变量bottomLeft来保存每一层最左边的节点的值。在遍历二叉树时&#xff0c;每当遇到新…

Apollo上车实践:打造安全、高效、舒适的出行体验

上车实践 概述自动驾驶车辆适配线控标准协议开环验证车辆 自动驾驶车辆集成了解传感器布置与连接了解车辆标定了解传感器标定循迹实践 自动驾驶测试与调车了解车辆安全操作流程了解实车控制调试了解实车定位调试 福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 通过…

C++设计模式_18_State 状态模式

State和Memento被归为“状态变化”模式。 文章目录 1. “状态变化”模式1.1 典型模式 2. 动机 (Motivation)3. 代码演示State 状态模式3.1 常规方式3.2 State 状态模式 4. 模式定义5. 结构( Structure )6. 要点总结7. 其他参考 1. “状态变化”模式 在组件构建过程中&#xf…

Apache ActiveMQ (版本 < 5.18.3) (CNVD-2023-69477)RCE修复方案/缓解方案

一、漏洞描述 Apache ActiveMQ 是美国阿帕奇&#xff08;Apache&#xff09;基金会的一套开源的消息中间件&#xff0c;它支持 Java 消息服务、集群、Spring Framework 等。 二、漏洞成因 ActiveMQ 默认开放了 61616 端口用于接收 OpenWire 协议消息&#xff0c;由于针对异常…

sqlite3 关系型数据库语言 SQL 语言

SQL(Structured Query Language)语言是一种结构化查询语言,是一个通用的,功能强大的关系型数据库操作语言. 包含 6 个部分: 1.数据查询语言(DQL:Data Query Language) 从数据库的二维表格中查询数据,保留字 SELECT 是 DQL 中用的最多的语句 2.数据操作语言(DML) 最主要的关…

视频下载工具Downie4 mac中文支持格式

Downie4 mac是一款视频下载工具。它支持下载各种视频网站上的视频&#xff0c;并且具有快速、稳定、易于使用的特点。 Downie支持下载各种视频网站上的视频&#xff0c;包括YouTube、Vimeo、Netflix、Hulu、Amazon等等。它具有快速、稳定的下载速度&#xff0c;可以帮助用户轻松…

HDFS架构介绍

数新网络_让每个人享受数据的价值浙江数新网络有限公司是一家开源开放、专注于云数据智能操作系统和数据价值流通的服务商。公司自主研发的DataCyber云数据智能操作系统&#xff0c;主要包括数据平台CyberData、人工智能平台CyberAI、数据智能引擎CyberEngine、数据安全平台Cyb…

手机app爬虫配置 (苹果手机)

近期在做某个项目,涉及到需要对手机app的进行数据爬取。在上一篇博文中,讲述了以模拟机为例的配置操作流程,这里将以苹果手机为例进行描述。 下面将讲述具体配置步骤 1、安装 抓包软件 fiddler (Fiddler | Web Debugging Proxy and Troubleshooting Solutions) ​ 下载后…

navicat15 恢复试用方法

1.运行&#xff0c;输入regedit&#xff0c;打开注册表 2.注册表中搜索 HKEY_CURRENT_USER\Software\PremiumSoft\NavicatPremium&#xff0c;删除下面的Registration15XCS文件夹 3.注册表中再搜索 HKEY_CURRENT_USER\Software\Classes\CLSID 然后拉到文件夹目录的最后&#x…

实时视频混合和映射:Resolume Arena 6(专业的VJ)中文

Resolume Arena 6是一款专业的实时视频混合和映射软件&#xff0c;广泛应用于音乐表演、舞台演出、俱乐部活动等场合&#xff0c;打造令人惊叹的视觉效果和图像投影。它支持实时混合多个视频源&#xff0c;拥有视频映射功能以及提供多样实时效果和过渡效果&#xff0c;让用户能…

MySQL的MSI安装

MySQL的MSI安装 文章目录&#xff1a; MySQL的MSI安装材料准备&#xff1a;一、MySQL安装的准备工作二、MySQL的配置三、MySQL安装验证1、CMD命名验证2、MySQL 8.0 Command Line Client验证 材料准备&#xff1a; 1、x64或x86电脑 2、MySQL安装包 一、MySQL安装的准备工作 M…

Unity 粒子特效-第一集-五角星发射特效

一、基础理解 1.粒子特效的意思是&#xff0c;发射很多小的东西&#xff0c;组成一个效果 2.主要可以分成两种 a.一直循环&#xff08;如上图&#xff09; b.发射状 二、案例视频 今天我们做一个发射的五角星 三、案例分析 我们仔细来分析一下这个五角星的功能 1.每次显示1秒…

Android体育场馆预约系统+全套手把手视频教程

【项目功能介绍】 功能列表: 本系统包含后台管理和前端app双端系统, 本系统包含三个角色: 管理员,员工,app用户。 后台管理员的功能包含: 登录, 退出, 场馆管理,添加场馆,修改场馆,禁用启用场馆; 场馆场地管理,添加场馆场地,修改场馆场地,启用禁用场馆场地; 订单管理,确定订单…

Python自动化运维监控——批量监听页面发邮件(自由配置ini文件+smtplib)

一、程序样式 1.listen.ini配置文件 2.监控页面 3.日志 二、核心点 smtplib库&#xff1a;这里使用了smtp.qq.com与smtp.163.com两个发送邮件的地址&#xff0c;使用邮箱用户名与授权码来实现登录&#xff0c;端口都使用465&#xff0c;最后抛出异常&#xff0c;finally里…

分享一下微信小程序抽奖链接怎么做

标题&#xff1a;微信小程序抽奖链接制作全攻略&#xff0c;轻松玩转营销抽奖活动 一、引言 在当今的数字化时代&#xff0c;抽奖活动已经成为一种高效的市场营销策略&#xff0c;而微信小程序作为一个功能强大的移动端平台&#xff0c;为企业和个人提供了制作抽奖链接的便捷…