0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在标准C语言中编译出来的可执行程序

嵌入式应用开发 来源:嵌入式应用开发 作者:嵌入式应用开发 2022-06-16 09:01 次阅读

在标准C语言中,编译出来的可执行程序分为代码区(text)、数据区(data)和未初始化数据区(bss)3个部分。如下代码

#include 
int a = 0;    //a在全局已初始化数据区 
char *p1;    //p1在BSS区(未初始化全局变量) 
void main() 
{
    int b; //b在栈区
    int c; //C为全局(静态)数据,存在于已初始化数据区
    char s[] = "abc"; //s为数组变量,存储在栈区,
    char *p2,*p3;  //p2、p3在栈区
    p2 = (char *)malloc(10);//分配得来的10个字节的区域在堆区
    p3 = (char *)malloc(20);//分配得来的20个字节的区域在堆区
    free(p2);
    free(p3);
}

使用linux编译之后得到的可执行文件如下

pYYBAGKqgI-Abh5MAAFxhFyS5SM700.png

​可以看到代码区(text)、数据区(data)和未初始化数据区(bss)。

代码段(text):存放代码的地方。只能访问,不能修改,代码段就是程序中的可执行部分,直观理解代码段就是函数堆叠组成的。

数据段(data):全局变量和静态局部变量存放的地方。也被称为数据区、静态数据区、静态区:数据段就是程序中的数据,直观理解就是C语言程序中的全局变量。注意是全局变量或静态局部变量,局部变量不算。

未初始化数据区(bss):bss段的特点就是被初始化为0,bss段本质上也是属于数据段。

那么问题来了,为什么要区分data段和bss段呢?

以下面代码为例,a.c和b.c的差异只是有没有给arr数组赋值。

pYYBAGKqgKCACr-tAAJxZrCdoE4429.png

​可以看到a.out的bss段大,b.out的data段大。但是b.out的文件大小明显比a.out的大很多。data段会增大可执行文件的大小,而bss段不会。

data段是全局变量,但是需要初始化值,上面我的例子是全部初始全部为1,但也可能是1024*1024个不同的数据,而这些数据需要保存起来,表现出来也就是需要保存在可执行文件中。

bss段也是全局变量,但不需要初始化值,只需要保存一下这个全部变量的保存的数据类型和大小即可。即使它的数组容量是1024*1024,也不会占用很多可执行文件的大小。

如果一个全部变量初始化为0,那么它也是bss段,不是data段,即使你代码中把它初始化为0了。

关于数据段,也就是data段,也会分为RO data(只读数据段)和RW data(读写数据段)。

  1. 只读数据段:程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可。
  2. 读写数据段:程序中是可以被更改的数据,且初始化过的,所以需要放置在RAM中,且初始化的内容放在存储器中(表现为放入可执行文件中)。

​上面说到“编译出来的可执行程序分为代码区(text)、数据区(data)和未初始化数据区(bss)3个部分”,那运行中就会多出来一些区域,这就是我们常说的堆栈,注意堆栈是两个区域堆和栈。

栈:局部变量、函数一般在栈空间中。运行时自动分配&自动回收:栈是自动管理的,程序员不需要手工干预。方便简单。是提前分配好的连续的地址空间。栈的增长方向是向下的,即向着内存地址减小的方向。

堆:堆内存管理者总量很大的操作系统内存块,各进程可以按需申请使用,使用完释放。程序手动申请&释放:手工意思是需要写代码去申请malloc和释放free。可以是不连续的地址空间。堆的增长方向是向上的,即向着内存地址增加的方向。

​下面是简单的演示代码

#include 
#include 

int bss_var;                                //未初始化全局数据存储在BSS区
int data_var=42;                            //初始化全局数据存储在数据区

int main(int argc,char *argv[])
{
  char *p ,*b;
  printf("Adr bss_var:0x%x\n",&bss_var);
  printf("Adr data_var:0x%x\n",&data_var);
  printf("the %s is at adr:0x%x\n","main",&main);
  p=(char *)alloca(32);              //从栈中分配空间
  if(p!=NULL)
  {
    printf("the p start is at adr:0x%x\n",p);
    printf("the p end is at adr:0x%x\n",p+31);
  }
  b=(char *)malloc(32*sizeof(char));   //从堆中分配空间
  if(b!=NULL)
  {
    printf("the b start is at adr:0x%x\n",b);
    printf("the b end is at adr:0x%x\n",b+31);
  }
  free(b);         //释放申请的空间,以避免内存泄漏
  while(1);
}

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7605

    浏览量

    136887
  • 程序
    +关注

    关注

    117

    文章

    3787

    浏览量

    81066
  • 代码
    +关注

    关注

    30

    文章

    4789

    浏览量

    68639
  • 内存分配
    +关注

    关注

    0

    文章

    16

    浏览量

    8307
收藏 人收藏

    相关推荐

    C语言编译过程

    C语言编译链接过程要把我们编写的一个C程序源代码,转换成可以硬件上运行的
    发表于 06-25 10:36 416次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>编译</b>过程

    C语言编译链接过程

      C语言编译链接过程要把我们编写的一个C程序源代码转换成可以硬件上运行的
    的头像 发表于 08-21 10:06 2609次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>编译</b>链接过程

    c语言比汇编编译出来程序大多少?

    c语言比汇编编译出来程序大多少?
    发表于 05-14 12:03

    labview生成的可执行程序的反编译

    坛子里有没有哪位大神知道关于labview生成的可执行程序的反编译问题,如何反编译exe的应用程序
    发表于 07-17 14:19

    从完成C源文件编辑后到执行程序前需要哪些步骤

    一、选择题,可多选(每题3分,共12分)1、从完成C源文件编辑后,到执行程序前,需要进过那些步骤( )A、编译,运行B、编译,链接C、链接,
    发表于 02-28 06:18

    C语言编译预处理

    将一个C程序转换为可执行程序的过程中, 编译预处理是最初的步骤. 这一步骤是由预处理器(preprocessor)来完成的.
    发表于 09-20 18:17 47次下载

    16KEY-B的可执行程序

    16KEY-B的可执行程序 /*******************************************************************/ /* */ /* 单片机开发
    发表于 11-22 18:02 14次下载

    Setup软件安装可执行程序工具免费下载

    本文档的主要内容详细介绍的是Setup软件安装可执行程序工具免费下载。 etup.exe是电脑的可执行进程文件,正常情况下setup.exe表示为系统的安装文件setup.exe,遇到系统文件
    发表于 11-13 08:00 11次下载

    了解Linux安装ARM交叉编译器的步骤

    gcc是linux环境下的asm和c语言编译器,生成的是可以x86平台上运行的可执行程序
    发表于 04-26 16:12 6489次阅读

    C语言的源代码文件和目标文件与可执行文件的详细介绍

    1、源代码文件 存放程序代码的文件,即我们编辑代码的文件,称为源代码文件。 C语言程序文件的扩展名为“.c”。源代码文件是相对目标文件
    的头像 发表于 02-18 11:52 8684次阅读

    嵌入式软件开发笔试面试知识点总结-C语言部分

    功能。C语言中,.c文件就是所谓的源文件。  源程序可执行程序的过程。在这个过程中,会发生如
    发表于 11-03 12:36 13次下载
    嵌入式软件开发笔试面试知识点总结-<b class='flag-5'>C</b><b class='flag-5'>语言</b>部分

    KEIL5中C语言编程时可以可执行语句之后定义变量

    以前看过有的程序可执行变量之后定义,当时就挺纳闷,C语言不是只能在函数的可执行语句之前定义变量
    发表于 01-13 13:05 2次下载
    KEIL5中<b class='flag-5'>C</b><b class='flag-5'>语言</b>编程时可以<b class='flag-5'>在</b><b class='flag-5'>可执行</b>语句之后定义变量

    如何编译嵌入式系统运行的程序

    汽车上使用的ECU中运行的程序,是软件工程师基于C/C++语言编写出来,然后通过编译
    的头像 发表于 02-13 14:06 1221次阅读
    如何<b class='flag-5'>编译</b>嵌入式系统运行的<b class='flag-5'>程序</b>?

    c语言程序main函数的位置

    理解C语言程序执行过程。 C语言程序
    的头像 发表于 11-24 10:23 2557次阅读

    ida反编译出来代码能直接用吗

    一些有助于人类阅读但不影响机器执行的元信息,如注释、文档字符串以及某些编译时优化的细节。因此,反编译出来的代码可能无法完全还原原始代码的意图和结构。 二、依赖性问题 即使反编译出来的代
    的头像 发表于 09-02 10:55 686次阅读