堆和栈
概念
堆:程序员手动分配(malloc/new)和释放(free/java不用手动释放,由GC回收),在堆上分配内存叫动态分配,一般硬件内存有多大堆内存就有多大
栈:系统自动分配和释放,保存全局、静态、局部变量,在栈上分配内存叫静态分配,大小一般是固定的。
堆
这里是才cubeMX模板上采用 韦东山 老师的demo,这里需要把MX_GPIO_Init()和HAL_Init()先屏蔽,要不然会一直进入硬件中断中。
/* USER CODE BEGIN 0 */
char heap_buf[1024];
int pos=0;
void *my_malloc(int size)
{
int pre_pos=pos;
pos += size;
return &heap_buf[pre_pos];
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
char context = 'a';
int size = 100;
char *buf = my_malloc(size);
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
//HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
//SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
//MX_GPIO_Init();
/* USER CODE BEGIN 2 */
for(int i=0; i<size; i++)
{
buf[i] = context;
}
/* USER CODE END 2 */
return 0;
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
先设置为仿真环境,然后点击仿真的按钮,在对应的代码行加上断点就可以进行调试了
在调试过程中可以把对应变量添加到watch或者memory窗口进行查看
然后在单步运行的时候就可以看到对应的内存的变化,或者变量的变化了
栈
使用下面的代码来看栈的过程
int a_func()
{
int a=0;
a++;
return a;
}
int b_func()
{
int b=0;
b++;
return b;
}
int c_func(int val)
{
int c;
c += val;
a_func();
b_func();
return c;
}
int main(void)
{
/* USER CODE BEGIN 1 */
char context = 'a';
int size = 100;
char *buf = my_malloc(size);
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
//HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
//SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
//MX_GPIO_Init();
/* USER CODE BEGIN 2 */
//for(int i=0; i<size; i++)
{
// buf[i] = context;
}
c_func(10);
/* USER CODE END 2 */
return 0;
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在使用代码的时候,有可能无法打断点,这是因为编译器对代码进行了优化,可以在设置里面调整优化等级,这里设置为0(不做优化)就可以了。
这里借用韦东山老师的课堂笔记
每个函数在运行的时候都有自己的栈空间,来存储局部变量、LR(Link Register),LR用于保存子程序的返回地址,在调用函数的时候,会先lr压栈,在调用结束后根据lr在跳到对应的地址处(也就是调用子函数的下一句代码)
lr就是连接寄存器(Link Register, LR),在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。
对应代码在这里 cubeMx heap-stck