凭据C编译器编译的功效,一般会发生RO段,RW段,ZI段。RO是措施中的指令和常量,RW是措施中的已初始化全局变量,ZI是措施中的未初始化或初始化为零的全局变量。
那么如下的代码
int aaa; int bbb; int main() { aaa = 7; bbb = 8; return 0; }
应该发生的是八个字节的ZI段,但很奇怪,–bss_threshold=0
Program Size: Code=464 RO-data=268 RW-data=8 ZI-data=608
如上所示,个中的Code段,RO-data段和ZI-data段是启动代码发生的,这里不深究。
它发生了8个字节的RW段,可以阐明发生的map文件查察main汇编代码和RW段,发明简直将aaa和bbb分派在了RW段。
map文件中的标记如下:
aaa 0x20000000 Data 4 main.o(.data) bbb 0x20000004 Data 4 main.o(.data) Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00000268, Max: 0x00001000, ABSOLUTE) Base Addr Size Type Attr Idx E Section Name Object 0x20000000 0x00000008 Data RW 11 .data main.o
想想没原理,实验发明初始化了的全局变量也是放在RW段。
最后发明祸首罪魁是KEIL的armcc的“–bss_threshold=num”这个编译选项,查察手册先容如下:
This option controls the placement of small global ZI data items in sections. A small global ZI data item is an uninitialized data item that is eight bytes or less in size. --bss_threshold=num where: num is either: place small global ZI data items in ZI data sections place small global ZI data items in RW data sections. In ARM Compiler 4.1 and later, the compiler might place small global ZI data items in RW data sections as an optimization. In RVCT 2.0.1 and earlier, small global ZI data items were placed in ZI data sections by default. Use --bss_threshold=0 to emulate the behavior of RVCT 2.0.1 and earlier with respect to the placement of small global ZI data items in ZI data sections.
将较量小的全局ZI变量存放到RW段傍边作为优化手段,默认是小于8个字节的当做small global ZI data,也就是说char,int这些范例全部会放到ZI,除非是大于8个字节的数组。
知道这个之后在编译选项内里添加–bss_threshold=0就可以将其规复到正常的ZI段中了。
gcc的arm编译器编出来的就是正常的放在ZI段的,感受keil这样做没什么原理,万一少字节的全局变量许多的话就增加了很大的bin size。
虽然全局变量太多也不是一个有素质的措施员应该写出的代码。
From:cnblogs ppym