Lazy loaded image
🌉开发框架搭建
懂点GNU C 编译器01-编译链接过程
Words 832Read Time 3 min
2024-11-13
2024-11-26
type
date
slug
category
icon
password

GNU GCC for ARM 编译器

从我们编写的C程序到可执行文件,整个编译过程并不是一气呵成、一步完成的,而是环环相扣、多步执行的。程序的整个编译流程主要分为以下几个阶段:预处理、编译、汇编、链接,最后生成可执行文件。
notion image
一个可执行文件通常由不同的段(section)构成:代码段、数据段、BSS段、只读数据段等。比如下面这段程序。
notion image
  • .text、.data、.bss 、 .rodata,分别是代码段、数据段、BSS段、只读数据区。
    • 函数放置代码段
    • 初始化的全局变量和静态局部变量放在数据段
    • 未初始化的全局变量和静态变量会放置在BSS段
    • 程序中定义的一些字符串、printf函数打印的字符串常量则放置在只读数据段.rodata中
  • .debug 每一条二进制指令对应的源码位置信息
  • .init 放置来自C语言运行库的一些汇编代码,用来初始化C程序运行所依赖的环境,如内存堆栈的初始化等。

编译过程

一个汇编文件是以段为单位来组织程序的:代码段、数据段、BSS段等,各个段之间相互独立。我们可以使用AREA或.section伪操作来定义一个段。

函数运行试内存分布

函数运行时的内存分布
函数运行时的内存分布

ARMCC 编译器编译过程

  • 栈(stack): 由编译器进行管理,自动分配和释放,存放函数调用过程的各种参数,局部变量,返回值以及函数的返回地址。操作方式类似于数据中的栈。
  • 堆(heap): 用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则在程序结束后由系统自动回收。注意:这里的对并不是数据结构中的堆。
  • 全局(静态)存储区: 分为DATA和BSS段,DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化分区) 存放未初始化的全局变量和静态变量。程序运行结束时自动释放,其中在BSS段在程序执行之前会被系统自动清零,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
  • 文字常量区:存放常量字符串,程序结束由系统释放。
  • 程序代码区:存放程序的二进制代码。

编译工具集

readelf

通过下面命令可查看各个段大小,包括代码段,数据段等。
通过如下命令可读取节头表信息
notion image
上一篇
常用接口协议-CAN 入门书学习笔记
下一篇
懂点GNU C 编译器02- __attribute__特殊属性

Comments
Loading...