5. Linux应用程序地址布局

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5. Linux应用程序地址布局相关的知识,希望对你有一定的参考价值。

5. Linux应用程序地址布局

程序构成:

在学习Linux应用程序开发时,经常会遇到如下概念:代码段、数据段、BSS段(Block Started by Symbol,又名:未初始化数据段) 、堆(heap)和栈(stack)。而这些部分也是构成Linux应用程序的重要组成部分。

内存布局:

当Linux应用程序在内存中运行的时候,以上组成部分在内存中布局:

技术分享

  1. 从低地址到高地址分别为:代码段、数据段、BSS段、堆、栈。
  2. 堆向高内存地址生长。
  3. 栈向低内存地址生长。

下面测试下面的程序:

技术分享

查看系统的线程:

技术分享

技术分享

下面我们看这代码的地址分配:

技术分享

数据存放的地址:

  1. 代码段:代码,全局常量(const)、字符串常量。
  2. 数据段:全局变量(初始化以及未初始化的)、静态变量(全局的和局部的、初始化的以及未初始化的)。
  3. 堆:动态分配的区域
  4. 栈:局部变量(初始化以及未初始化的,但是不包括静态变量)、局部只读变量(const)。

?

?

?

从上面的得知:代码段的起始地址是8048000.数据段起始地址8049000,堆的开始地址b77a5000,栈的起始地址bfb47000.

?

?

分析数据存放位置:

例子代码:

#include <stdio.h>

#include <stdlib.h>

int global_init_a=1; //global init variable

int global_uninit_a; //global uninit variable

static int static_global_init_a=1;

static int static_global_uninit_a;

const int const_global_a=12;

?

int global_init_b=2; //global init variable

int global_uninit_b; //global uninit variable

static int static_global_init_b=12;

static int static_global_uninit_b;

const int const_global_b=12;

?

int main()

{

????int local_init_a=1;

????int local_uninit_a;

????static int static_local_init_a=1;

????static int static_local_uninit_a;

????const int const_local_a=12;

?

????int local_init_b=1;

????int local_uninit_b;

????static int static_local_init_b=1;

????static int static_local_uninit_b;

????const int const_local_b=12;

????int * malloc_p_a;

????malloc_p_a=malloc(sizeof(int)); //

?

?

????printf("&global_init_a =%p\n", &global_init_a);

????printf("&global_uninit_a =%p\n", &global_uninit_a);

????printf("&static_global_init_a =%p\n", &static_global_init_a);

????printf("&static_global_uninit_a =%p\n", &static_global_uninit_a);

????printf("&const_global_a =%p\n", &const_global_a);

?

????printf("&global_init_b =%p\n", &global_init_b);

????printf("&global_uninit_b =%p\n", &global_uninit_b);

????printf("&static_global_init_b =%p\n", &static_global_init_b);

????printf("&static_global_uninit_b =%p\n", &static_global_uninit_b);

????printf("&const_global_b =%p\n", &const_global_b);

?

????printf("&local_init_a =%p\n", &local_init_a);

????printf("&local_uninit_a =%p\n", &local_uninit_a);

????printf("&static_local_init_a =%p\n", &static_local_init_a);

????printf("&static_local_uninit_a =%p\n", &static_local_uninit_a);

????printf("&const_local_a =%p\n", &const_local_a);

?

????printf("&local_init_b =%p\n", &local_init_b);

????printf("&local_uninit_b =%p\n", &local_uninit_b);

????printf("&static_local_init_b =%p\n", &static_local_init_b);

????printf("&static_local_uninit_b =%p\n", &static_local_uninit_b);

????printf("&const_local_b =%p\n", &const_local_b);

?

????printf("&malloc_p_a =%p\n", &malloc_p_a);

?

?

????return 0;

}

?

技术分享

?

分析BSS段:

技术分享

技术分享

Bss段是数据段的一个子段。

以上是关于5. Linux应用程序地址布局的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式:ARM符号定义伪操作详解

ARM 汇编指令 ADR 与 LDR 使用

ARM伪指令,王明学learn

ARM汇编程序中的伪指令

arm汇编—ldr加载指令,ldr伪指令

ARM的伪指令