好记性不如铅笔头

ARM, 操作系统, 编程

ARM学习随手笔记:最简单的内存分析

作者最近在学习keil和ARM,哎,只能感叹自己老了,这里简单的记录下学习笔记吧。

以【 ARM学习随手笔记:使用ITM方式启用printf 】为基本工程,这里打开HEAP内存,如下图:

然后修改mainfunc.c,修改后如下:

#include <stdio.h>
#include <stdlib.h>

#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))

#define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA          0x01000000

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;

int fputc(int ch, FILE *f) {
  if (DEMCR & TRCENA) {
    while (ITM_Port32(0) == 0);
    ITM_Port8(0) = ch;
  }
  return(ch);
}

int g_int = 100;

int main(void)
{
	int local_int = 10;
	int *p_local_int = (int *)malloc(sizeof(int));
	
	printf("g_int address: %x\n", (unsigned int)(&g_int) );
	printf("local_int address: %x\n", (unsigned int)(&local_int) );
	printf("p_local_int address: %x\n", (unsigned int)(p_local_int) );
	printf("main address: %x\n", (unsigned int)(&main) );

	while(1)
		;
}

使用模拟器编译,执行,结果如下:

g_int address: 20000008
local_int address: 20001068
p_local_int address: 20000088
main address: 18b

查看map文件,这里有两种方式,可以在文件目录中查找【 HelloM3\Listings\HelloM3.map 】,或者如下图右键快捷打开:

map部分内容如下:

Image Symbol Table

    Local Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)
    。。。。。。。
    。。。。。。。
    HEAP                                     0x20000070   Section     3072  startup_armcm3.o(HEAP)
    Heap_Mem                                 0x20000070   Data        3072  startup_armcm3.o(HEAP)
    STACK                                    0x20000c70   Section     1024  startup_armcm3.o(STACK)
    Stack_Mem                                0x20000c70   Data        1024  startup_armcm3.o(STACK)
    __initial_sp                             0x20001070   Data           0  startup_armcm3.o(STACK)

    Global Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)
    。。。。。。。
    。。。。。。。
    main                                     0x0000018b   Thumb Code    52  mainfunc.o(.text)
    。。。。。。。
    g_int                                    0x20000008   Data           4  mainfunc.o(.data)
    。。。。。。。



==============================================================================

Memory Map of the image

    Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00001070, Max: 0x00020000, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   0x0000000c   Data   RW            2    .data               mainfunc.o
    0x2000000c   0x00000004   Data   RW           37    .data               system_armcm3.o
    0x20000010   0x00000060   Zero   RW          281    .bss                c_w.l(libspace.o)
    0x20000070   0x00000c00   Zero   RW           26    HEAP                startup_armcm3.o
    0x20000c70   0x00000400   Zero   RW           25    STACK               startup_armcm3.o

这里最简单的分析下:
1 g_int是全局变量,属于全局变量区。
2 local_int是局部变量,因此在栈上。
3 p_local_int是malloc出来的,因此在堆上。
4 RAM上的内存分布简图如下:

由此可见,栈的大小在实际工作中需要仔细计算,以免内存越界,不过在实际工作中,一般不会使用堆内存,也不会使用malloc等函数。

Leave a Reply

2 × 2 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据