嵌入式之详解:text段,data段,bss段


前言

我们在实际嵌入式软件开发过程中,编译完代码之后会出现下图的样式,那这到底是指啥呢?
在这里插入图片描述
不必担心,走你~
在这里插入图片描述

一、text段(代码段)

1、详细介绍

a)功能

text段主要存储程序的可执行代码,即经过编译后的机器指令。这些指令是程序运行时处理器实际执行的操作,包括函数调用、算术运算、逻辑判断等。

b)特点

只读性: 一般情况下,text段是只读的,因为程序在运行过程中不应该修改自身的指令代码,以确保程序的稳定性和安全性。
共享性:多个进程可以共享同一个text段。由于代码在执行过程中不会被修改,所以多个进程可以同时运行相同的代码,而无需为每个进程都复制一份代码,从而节省内存空间。

c)代码示例

在一个简单的 C 语言程序中,函数的定义部分最终会被编译到text段中。例如:

#include <stdio.h>
 
// 这个函数的机器指令会存放在text段
int add(int a, int b) {
    return a + b;
}
 
int main() {
    int result = add(3, 5);
    printf("The result is: %d\n", result);
    return 0;
}

2、存储位置

在大多数嵌入式系统中,text段通常存储在非易失性存储器(如 Flash)中。这是因为 Flash 具有掉电不丢失数据的特性,适合存储程序代码。在程序运行时,text段会从 Flash 加载到内存(如 SRAM)中,以便处理器能够快速访问和执行。

二、data段(数据段)

1、详细介绍

a)功能

data段用于存储已初始化的全局变量和静态变量。这些变量在程序编译时就已经被赋予了初始值,并且在程序运行过程中需要保留这些初始值。

b)特点

可读写性: 与text段不同,data段是可读写的,因为程序在运行过程中可能需要修改这些变量的值。
占用存储空间: data段在程序加载时会占用一定的内存空间,因为需要将编译时确定的初始值从存储介质(如 Flash)复制到内存(如 SRAM)中。

c)代码示例

以下是一个包含已初始化全局变量的 C 语言程序示例:

#include <stdio.h>
 
// 这个全局变量会被存放在data段
int global_variable = 10;
 
int main() {
    // 修改全局变量的值
    global_variable = 20;
    printf("The value of global_variable is: %d\n", global_variable);
    return 0;
}

2、存储位置

data段的初始值通常存储在非易失性存储器(如 Flash)中,而在程序运行时,这些初始值会被复制到内存(如 SRAM)的可读写区域。这是因为 SRAM 具有更快的读写速度,适合程序在运行过程中对变量进行读写操作。

三、bss段(未初始化数据段)

1、详细介绍

a)功能

bss段用于存储未初始化的全局变量和静态变量。这些变量在程序编译时没有被赋予初始值,编译器只是为它们预留了内存空间。

b)特点

零初始化: 在程序加载时,bss段中的变量会被自动初始化为零值。这是因为在程序开始运行之前,系统会将bss段的内存区域全部清零。
不占用存储介质空间: bss段在存储介质(如 Flash)中不占用实际的存储空间,因为这些变量没有初始值,只需要在内存中预留空间即可。在程序加载时,系统会根据链接脚本中指定的bss段大小,在内存中分配相应的空间并清零。

c)代码示例

以下是一个包含未初始化全局变量的 C 语言程序示例:

#include <stdio.h>
 
// 这个全局变量会被存放在bss段
int uninitialized_global_variable;
 
int main() {
    // 输出未初始化全局变量的值,应该为0
    printf("The value of uninitialized_global_variable is: %d\n", uninitialized_global_variable);
    return 0;
}

2、存储位置

bss段只存在于内存(如 SRAM)中,在存储介质(如 Flash)中没有对应的存储空间。因为这些变量的初始值都是零,所以不需要在 Flash 中存储初始值,只需要在内存中分配空间并清零即可。

四、内存布局及初始化过程

在程序启动时,会有一个内存初始化的过程,具体步骤如下:

1.加载text段:将text段从存储介质(如 Flash)加载到内存的指定位置,通常是只读区域。
2.复制data段:将data段从存储介质复制到内存的可读写区域,因为这些变量在程序运行过程中可能会被修改。
3.清零bss段:将bss段对应的内存区域全部清零,以确保未初始化的全局变量和静态变量初始值为零。

在链接脚本中,通常会对这些段进行明确的定义和分配,例如:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

SECTIONS
{
    .text :
    {
        *(.text)
        *(.rodata)
    } > FLASH

    .data :
    {
        _sdata = . ; 数据段起始地址
        *(.data)
        _edata = . ; 数据段结束地址
    } > SRAM AT > FLASH

    .bss :
    {
        _sbss = . ; BSS段起始地址
        *(.bss)
        _ebss = . ; BSS段结束地址
    } > SRAM
}

在这个链接脚本中,.text段被分配到 Flash 中,.data段和.bss段被分配到 SRAM 中,同时.data段的初始值存储在 Flash 中,在程序启动时会被复制到 SRAM 中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&春风有信

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值