C语言 百分网手机站

C言语KEIL的ARM编译器对RW和ZI段的处理

时间:2020-09-02 20:04:28 C语言 我要投稿

C言语KEIL的ARM编译器对RW和ZI段的处理

  按照C编译器编译的结果,一般会产生RO段,RW段,ZI段。RO是程序中的指令和常量,RW是程序中的已初始化全局变量,ZI是程序中的未初始化或初始化为零的全局变量。下面是小编为大家带来的C言语KEIL的ARM编译器对RW和ZI段的处理的'知识,欢迎阅读。

  C言语KEIL的ARM编译器对RW和ZI段的处理

  按照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。

  当然全局变量太多也不是一个有素质的程序员应该写出的代码。


【C言语KEIL的ARM编译器对RW和ZI段的处理】相关文章:

C语言程序的段10-06

C语言编译器gcc命令如何操作步骤11-24

C语言位段的介绍10-03

有趣的C语言预处理10-04

C语言的预处理代码09-28

C语言预处理的相关知识09-28

c语言编译预处理10-06

c#中预处理指令#if的使用09-23

浅谈c语言和c++和VB的区别11-24

C语言的字符串处理函数strlen()10-03