当前位置:首页 > > Mculover666
[导读]程序烧到什么地方?程序加载到内存什么地方?程序如何执行?

学习目的

  • 程序烧到什么地方?
  • 程序加载到内存什么地方?
  • 程序如何执行?

一、编译环境搭建

ubuntu 20.04 使用 arm-linux-gnueabihf-gcc 7.5.0。

二、程序源码

main.c:

#include  #include "calc.h" int main(int argc, char *argv[]) { int a, b; static int local_val = 2; static int uninit_local_val;

    a = add(2, 3);
    b = sub(5, 4); printf("a = %d\n", a); printf("b = %d\n", b); return 0;
}

calc.h:

#ifndef _CALC_H_ #define _CALC_H_ int add(int a, int b); int sub(int a, int b); #endif 

calc.c:

#include "calc.h" int add(int a, int b) { return a + b;
} int sub(int a, int b) { return a - b;
}

编译:

arm-linux-gnueabihf-gcc main.c calc.c

交叉编译生成 a.out 可执行文件,文件类型是 32 位 ARM 平台可执行文件。

三、readelf 工具

readelf 工具由编译器提供,用来列出关于可执行文件的内容的相关信息

使用格式如下:

Usage: readelf  elf-file(s)

(1)查看可执行文件的头部 信息

  • -h:用于列出 ELF 文件的头部信息,包括可执行文件运行的平台、软件版本、程序入口地址,以及 program headers、section header 等信息;

(2)查看 section header

  • -S:用于列出程序中 section 的头部信息

四、可执行文件的组成结构

一个可执行文件由一系列 section 构成,section 称为段,包括:代码段 text、只读数据段 rodata、数据段 data、bss 段等。

每个 section 用一个section header描述,包括段名、段的类型、段的起始地址、段的偏移、段的大小等。

将可执行文件的所有 section header 集合到一起就是 section header table,使用 readelf 的-S参数查看的就是该表。

在程序编译的时候,对 C 语言代码中定义的函数、变量、未初始化的全局变量进行编译分类,放置在不同的段中:

  • 普通代码翻译成二进制放到代码段(text)中
  • 常量放在只读数据段(rodata)中
  • 初始化的全局变量和静态局部变量放在数据段(data)中

BSS 段比较特殊,未初始化的全局变量和静态变量都会放置到 bss 段中,但因为这些变量的值都是 0,没有必要再开辟空间存储,所以在可执行文件中 bss 段是不占用空间的。

但是 BSS 段的大小、起始地址、各个变量的地址信息都会分别保存在 section header table 和符号表 symtab 中,当程序运行的时候,加载器会根据这些信息在内存中紧挨着数据段之后的空间,为 BSS 段开辟一片存储空间,为各个变量分配存储空间。

总而言之:BSS 段在可执行文件中不占用空间,在程序运行的时候才分配对应的空间

如果在编译时开启了调试选项,则可执行文件中还会有 .debug section,用来保存可执行文件中每一条二进制指令对应的源码位置信息,根据这些信息,GDB 调试器就可以支持源码级的单步调试。

在最后环节,编译器还会在可执行文件中添加一些其它的 section,比如 .init section,这些代码来自 C 语言运行库的一些汇编代码,用来初始化 C 程序所依赖的环境。

参考资料

  • 嵌入式 C 语言自我修养 从芯片、编译器到操作系统

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭