写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,
目录
- 一、Keil C51编译器
- 二、Keil MDK-Arm编译器
- 三、IAR For STM8(EWSTM8)编译器
- 四、Keil下的 .map文件
- 五、优化
- Small:变量默认分配到内部存储空间中,通过普通的 MOV指令寻址,只用低于 2K的程序空间。
- Compact:变量默认分配到外部页存储空间中,单个函数的代码量不能超过 2K,整个程序可以使用 64K的程序空间,通过 MOVX, @Ri之类指令寻址,在不切换页的前提下,最大支持 256字节外部扩展 RAM。
- Large:变量默认分配到外部存储空间中,通过 MOVX, @DPTR之类指令寻址,最大支持 64kB外部扩展 RAM(实际上配合硬件设计以及软件调整,还可以支持更大的扩展空间)。
2、程序中,如果在变量声明时未声明变量的存储器类型,则该变量的存储器类型,由程序的存储模式来决定,也就是说编译器会根据我们在上面 Memory Model 里所选的模式默认储存在那个区域。
bdata:片内 RAM的可位寻址区(20H~2FH),允许字节和位混合访问
idata:单片机间接访问的片内 RAM区,允许访问全部片内 RAM(前面 0x00-0xff的 256个 RAM),其中前 128和 data的 128完全相同,只是因为访问的方式不同。idata是用类似 C中的指针方式访问的。汇编中的语句为:mox ACC,@Rx.(不重要的补充:C中 idata做指针式的访问效果很好)
pdata:Ri间接访问的片外 RAM的低 256B(00H~FFH)
xdata:外部扩展 RAM,用 DPTR间接访问片外 RAM,允许访问全部 64KB片外 RAM(0000H~FFFFH)
code:单片机的 64KB程序存储区 ROM,即代码域,它指的是编译器生成的机器指令,这些内容被存储到 ROM区,写入后就不能再更改,一般当你定义数组不用更改时可以加上这个关键词,对应的 data是存入 RAM的意思

- Flash = Code + data + xdata
- RAM = data + xdata


RO-data:Read Only data,即只读数据域,它指程序中用到的只读数据,这些数据被存储在 ROM区,因而程序不能修改其内容。例如 C语言中 const关键字定义的变量就是典型的 RO-data。
RW-data:Read Write data,即可读写数据域,它指初始化为 “ 非 0值 ” 的可读写数据,程序刚运行时,这些数据具有非 0的初始值,且运行的时候它们会常驻在 RAM区,因而应用程序可以修改其内容。例如 C语言中使用定义的全局变量,且定义时赋予“非0值”给该变量进行初始化。
ZI-data:Zero Initialie data,即 0初始化数据,它指初始化为 “0值” 的可读写数据域,它与 RW-data的区别是程序刚运行时这些数据初始值全都为 0,而后续运行过程与 RW-data的性质一样,它们也常驻在 RAM区,因而应用程序可以更改其内容。例如C语言中使用定义的全局变量,且定义时赋予 “0值” 给该变量进行初始化(若定义该变量时没有赋予初始值,编译器会把它当 ZI-data来对待,初始化为 0);
ZI-data的栈空间(Stack)及堆空间(Heap):在 C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候从向栈空间申请内存给局部变量,退出时释放局部变量,归还内存空间。而使用 malloc动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于 ZI-data区域的,这些空间都会被初始值化为 0值。编译器给出的 ZI-data占用的空间值中包含了堆栈的大小(经实际测试,若程序中完全没有使用 malloc动态申请堆空间,编译器会优化,不把堆空间计算在内)。
3、对比 C51的,显示的数据类型多了那么几项;那么,根据上面的数据理解,就可以得到:
- Flash = Code + RO-data + RW-data
- RAM = RW-data + ZI-data


- Flash = readonly code memory + readonly data memory
- RAM = readwrite data memory
括号内的,表示内存的绝对使用量,对应你设的全局变量大小;对应生成的 bin文件大小 = 5590 + 168

一般每个编译器都有优化选项,对应选择不同的优化等级,你会发现同样的代码,编译出来的占用内存大小是不同的,再细心一点同样可以发现存放在 RAM区域的内存大小是不会怎么变化的,变化较大的是存在 Flash区域的内存,所以一般的不会定义全局变量(除非真的要用到),并且全局变量处理起来比较麻烦;另外,开了优化后,如果进入调试,可能有些地方会放不了小红点(打断点),因为编译器根据你所选的优化等级,把对应的代码给优化了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/206872.html