单片机从硬件上来说,只有两种空间:
ROM和RAM!
再说一遍,只有ROM和RAM!
再说一遍,只有ROM和RAM!
也就是说,你程序里的所有东西,不是放在RAM里,就是放在ROM里。
ROM的属性是read only(只读),只能用来读取,无法修改,其实也可以修改,只是需要特殊方法,这里暂时不谈!
RAM的属性是read+write(可读可写)
ROM和RAM区域有可能是间断的,分段的。其中RAM主要有数据段+堆+栈+通用寄存器+特殊功能寄存器等
所以编译器(你可以认为是keil)根据只读或者读写的属性将程序划分为
1、ROM区(也就是单片机的FLASH区)
我们都了解,rom是只读的,所以里面的内容也是只读的,这里面包括
1.1、软件的代码段(code)
void main(void)
{
;
}
1.2、数据常量(被const修饰的数据常量)就是放在这里的。
const unsigned int a[100] =
{
1,2....
};
1.3、数据段,定义的数据(这个理解起来有点困难,因为涉及运行视图和加载视图)
2、RAM区
RAM区域读写的,掉电易失的,再说一遍,掉电易失!
那么问题来了,刚上电复位时,ram区肯定是空的,那么访问全局变量时,数是怎么找到的?
如果我们仔细看一下ARM启动过程(从上电到main),就是main之前东西,我们就能知道了。这里我们首先要明白两个概念。程序的运行视图和加载视图。
其中RAM区域主要包含以下内容:
2.1、数据段(data)
BSS(未初始化的全局变量+未初始化的静态变量)
Data初始化的全局变量+初始化的静态变量
2.2、STATCK(栈)
(1)、函数传递参数较多时,参数会入栈;
(2)、中断发生时,用于保存和恢复中断前的现场。
2.3、HEAP(堆)
Malloc函数申请的空间(需要了解操作系统内核和链表)
2.4、SFR(通用寄存器,R1,R2。。。。。R15等)
(1)传递函数参数(个数较少时,一般为3个)使用
(2)中间变量使用
(3)寻址等等(查看汇编的寻址方式等)
2.5、SFR特殊功能寄存器(AD,UART,PWM等)
(1)设置芯片工作状态,操作外设。