堆和栈
1. 局部变量¶
1.1 单个局部变量栈空间分配¶
① STM32芯片的基地址:0x20000000---->0x20010000
② 栈空间从0x20010000开始分配
③ 分配r3
给变量b
占坑
④ 赋值给r0
寄存器0x1c8
,即 456
⑤ 将r0
寄存器的值写入到sp
所指向的地址,即r3
寄存器
这便是局部变量b=456;
分配栈空间的过程。
实际汇编码展示(基于keil5调试)
1.2 局部数组栈空间分配¶
继续创建一个volatile char name[100];
,观察栈空间分配:
当我们的char name[100]
为使用时,是不会为其分配内存的,当我们在后面使用了赋值操作,就会通过SUB
减指令,分配0x68
即十进制的 104 字节空间,其中包括 100 的char name[100]
和 4 的 int b
。同时可以看到b
变量的赋值是将r0
寄存器的值写入到SP
偏移0x64
的位置。
1.3 局部变量的释放¶
局部变量的释放,主要是使用POP
指令,每回收一个寄存器SP
指针上移一位。
2. 全局变量¶
全局变量和静态变量的初始化如下图所示:
- 有初始值的全局变量和静态变量是通过
copy
函数,将Flash里面的数据复制到全局变量和静态变量的内存里面。 - 没有初始值和初始值为0的全局变量和静态变量,调用memset函数将这些变量的存储空间清零,然后再调用
main
函数。
其中全局变量与静态变量存放的起始地址可以自定义,在keil5中的连接器配置:
3. 堆和栈简述¶
堆是堆,栈是栈,不能混讲。
栈:
- 向下增长
- 估计栈大小
- 选出空闲的空间
- 栈的初始地址由程序员自己决定(一般为最上方开始)
- 一个程序可能有多个线程,一个线程就有一个栈
堆:
堆就是一块用malloc()
和free()
管理的空闲内存。栈我们只能控制起始地址,但是堆我们可以完全由自己控制内存开辟、释放等。