Skip to content

堆和栈

1. 局部变量

1.1 单个局部变量栈空间分配

① STM32芯片的基地址:0x20000000---->0x20010000
② 栈空间从0x20010000开始分配
③ 分配r3给变量b占坑
④ 赋值给r0寄存器0x1c8,即 456
⑤ 将r0寄存器的值写入到sp所指向的地址,即r3寄存器

这便是局部变量b=456;分配栈空间的过程。

image-20250110142605126

实际汇编码展示(基于keil5调试)

image-20250110141855045

1.2 局部数组栈空间分配

继续创建一个volatile char name[100];,观察栈空间分配:

image-20250110142553964

当我们的char name[100]为使用时,是不会为其分配内存的,当我们在后面使用了赋值操作,就会通过SUB减指令,分配0x68即十进制的 104 字节空间,其中包括 100 的char name[100]和 4 的 int b。同时可以看到b变量的赋值是将r0寄存器的值写入到SP偏移0x64的位置。

image-20250110142836821

1.3 局部变量的释放

局部变量的释放,主要是使用POP指令,每回收一个寄存器SP指针上移一位。

image-20250110144528827

2. 全局变量

全局变量和静态变量的初始化如下图所示:

  • 有初始值的全局变量和静态变量是通过copy函数,将Flash里面的数据复制到全局变量和静态变量的内存里面。
  • 没有初始值和初始值为0的全局变量和静态变量,调用memset函数将这些变量的存储空间清零,然后再调用main函数。

image-20250110160445202

其中全局变量与静态变量存放的起始地址可以自定义,在keil5中的连接器配置:

image-20250110160647466

3. 堆和栈简述

堆是堆,栈是栈,不能混讲。

栈:

  1. 向下增长
  2. 估计栈大小
  3. 选出空闲的空间
  4. 栈的初始地址由程序员自己决定(一般为最上方开始)
  5. 一个程序可能有多个线程,一个线程就有一个栈

堆:

C
char* str;
str = malloc(100);
strcpy(str, "OpenHarmony");

free(str);

堆就是一块用malloc()free()管理的空闲内存。栈我们只能控制起始地址,但是堆我们可以完全由自己控制内存开辟、释放等。

3. 堆

4. 栈