目录
Ubuntu下的C程序中堆、栈、全局、局部等变量的分配地址
?
二、c语言
全局变量:
栈:
局部变量:
三、stm32下的C程序中堆、栈、全局、局部等变量的分配地址
1、下载代码
2、改写代码
三、Clion编辑器
?四、配置CLion 工程文件
准备工作
添加代码
结果
?参考资料
Ubuntu下的C程序中堆、栈、全局、局部等变量的分配地址
代码
#include <stdio.h>
#include <stdlib.h>
//定义全局变量
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\n");
}
int main( )
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
output(a);
char *p;
char str[10] = "lyy";
//定义常量字符串
char *var1 = "1234567890";
char *var2 = "qwertyuiop";
//动态分配
int *p1=malloc(4);
int *p2=malloc(4);
//释放
free(p1);
free(p2);
printf("栈区-变量地址\n");
printf(" a:%p\n", &a);
printf(" init_local_d:%p\n", &init_local_d);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf("\n堆区-动态申请地址\n");
printf(" %p\n", p1);
printf(" %p\n", p2);
printf("\n全局区-全局变量和静态变量\n");
printf("\n.bss段\n");
printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
printf("\n.data段\n");
printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
printf("\n文字常量区\n");
printf("文字常量地址 :%p\n",var1);
printf("文字常量地址 :%p\n",var2);
printf("\n代码区\n");
printf("程序区地址 :%p\n",&main);
?在这里的栈区可以看出来地址从上到下逐步变小,在堆区可以看出地址值从上到下逐步增大
二、c语言
全局变量:
C语言允许在所有函数的外部定义变量,这样的变量称为 全局变量(Global Variable) 。 全局变量的默认作用域是整个程序,也就是所有的代码文件,包括源文件( .c 文件)和头文件( .h 文件)。 如果给全局变量加上 static 关键字,它的作用域就变成了当前文件,在其它文件中就无效了。
栈:
-
先进后出 - 编译器自动分配和释放的,主要存储的是函数的参数值,局部变量等值。相对较高的地址,地址值从高往低分配?例如:声明 int test 变量就是自动分配的空间
- 由于是自动分配,速度比堆快
- 次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址
局部变量:
局部变量是指在程序中,只在特定过程或函数中可以访问的变量,是相对于全局变量而言的。 在C语言中,局部变量可以和全局变量重名,但是局部变量会屏蔽全局变量。
三、stm32下的C程序中堆、栈、全局、局部等变量的分配地址
1、下载代码
链接:百度网盘 请输入提取码 提取码:9teg
2、改写代码
?bsp_ustart.h文件,添加头文件
#include <stdio.h>
#include <stdlib.h>
?bsp_ustart.c文件,改写fputc函数
int fputc(int ch, FILE *f)
{
USART_SendData(DEBUG_USARTx, (uint8_t)ch);
while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
改写main.c
#include "stm32f10x.h"
#include "bsp_usart.h" //添加 bsp_usart.h 头文件
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\n");
}
int main(void)
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
char *p;
char str[10] = "lyy";
//定义常量字符串
char *var1 = "123456";
char *var2 = "yushu";
//动态分配
int *p1=malloc(4);
int *p2=malloc(4);
USART_Config();//串口初始化
output(a);
//释放
free(p1);
free(p2);
printf("栈区-变量地址\n");
printf(" a:%p\n", &a);
printf(" init_local_d:%p\n", &init_local_d);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf("\n堆区-动态申请地址\n");
printf(" %p\n", p1);
printf(" %p\n", p2);
printf("\n全局区-全局变量和静态变量\n");
printf("\n.bss段\n");
printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
printf("\n.data段\n");
printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
printf("\n文字常量区\n");
printf("文字常量地址 :%p\n",var1);
printf("文字常量地址 :%p\n",var2);
printf("\n代码区\n");
printf("程序区地址 :%p\n",&main);
printf("函数地址 :%p\n",&output);
return 0;
}
?运行,未报错?
将生成的hex文件烧录进开发板,烧录成功之后打开串口调试助手,结果显示如下
?
三、Clion编辑器
点击左上角的STM32F030F4Px ,选择STM32F103C8 芯片,点击Start Porject ?
?点击System Core 中的SYS ,在Debug 处选择Serial Wire
?修改RCC,勾选Crystal....
?设置引脚,设置 PC13 引脚为 GPIO_Output 来点亮 LED 灯。
配置串口 USART1
工程文件的设置:Project Name 要重新填写一下(因为换芯片的过程,其实是 Cube 新建了一个 ioc 文件),建议填写之前的工程名和文件目录,这样就可以把之前不想要的那个 .ioc 文件覆盖掉。 然后" Toolchain/IDE "那里,选择?SW4STM32
如何点击生成工程就行。
?四、配置CLion 工程文件
准备工作
回到CLion,出现如下界面,点击USE
?
寻找 st_nucleo_f103rb.cfg 文件位置
?
在自己的电脑中找到上面显示的文件并使用CLion打开即可
添加代码
打开?main.c ?文件,在 while 循环里添加使 PC13 引脚 LED 闪烁的代码
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}
点击?File-Settings-CMake ,选择下图中的选项,最后点击?OK
?
?然后点击这个锤子,运行代码就行
结果
烧录 生成的hex文件
?
?参考资料
用clion自带的嵌入式开发功能和stm32cubeMX开发stm32!!! - 知乎
?CLion安装破解教程 - 诸葛借剑 - 博客园
(6条消息) CLion2021 的详细安装并基于 CLion 实现 stm32F103 点亮 LED_L-GRAZY的博客-CSDN博客
基于ubuntu,树莓派和stm32的C程序的内存分配问题_Harriet的博客-CSDN博客
【IoT】STM32 内存分配详解_简一商业-CSDN博客_stm32内存分配
基于STM32分析栈、堆、全局区、常量区、代码区、RAM、ROM - 学以解忧的个人空间 - OSCHINA - 中文开源技术交流社区
?
?
|