偶尔的一次发现,看到自己界说的结构体编译出来的巨细和我幻想的不一样,所以便追溯了一下本源。做了一系列试验之后发现,ARM的结构体的内存分配上有着一些固有的做法。废话不多说,看比如。
试验一:
我界说一个结构体:
typedef struct TestStruct
{
unsinged char Test1;
unsigned int Test2;
unsigned char Test3;
unsigned int Test4;
unsigned short Test5;
}TEST_STRUCT;
TEST_STRUCT TestStruct1;
然后我分别给这些成员都赋值,以便于在Memory里边调查。
TestStruct1.Test1 = 0x11;
TestStruct1.Test2 = 0x22334455;
TestStruct1.Test3 = 0x66;
TestStruct1.Test4 = 0x778899AA;
TestStruct1.Test5 = 0xBBCC;
然后我调用了sizeof函数来核算这个结构体的巨细
sizeof(TestStruct1)
发现巨细是20个Byte。而我原先估计的巨细为1+4+1+4+2=12个Byte。
所以我使用AXD的内存监控查看了这段内存的分配(Little Endian),如下:
0x01,0x00,0x00,0x00,0x55,0x44,0x33,0x22,0x66,0x00,0x00,0x00,0xAA,0x99,0x88,0x77
0xCC,0xBB,0x00,0x00
发现ARM在编译的时分把原先缺乏Word长度的扩展成了Word长度。
试验二:
后来想到,或许ARM这么做是为了不损坏结构体的结构。所以把结构体改成了:
typedef struct TestStruct
{
unsinged char Test1;
unsigned char Test3;
unsigned short Test5;
unsigned int Test2;
unsigned int Test4;
}TEST_STRUCT;
再次调用sizeof,发现巨细变成了12个Byte,契合了原先估计的巨细。
再监控内存分配,如下:
0x01,0x06,0xCC,0xBB,0x55,0x44,0x33,0x22,0xAA,0x99,0x88,0x77
由此发现,本来松懈的内存变得如此的紧凑。
试验三:
随后,又猜测,这样是否真的能够缩小内存损耗呢?ARM会不会在结构体的中心刺进其他变量呢。
所以做了一个试验,建立了三个BYTE巨细的变量。
unsigned char TestData0 = 0xDD;
unsigned char TestData1 = 0xEE;
unsigned char TestData2 = 0xFF;
然后结构体康复成试验一的状况,监控了下内存,发现变成了:
0x01,0x00,0x00,0x00,0x55,0x44,0x33,0x22,0x66,0x00,0x00,0x00,0xAA,0x99,0x88,0x77
0xCC,0xBB,0x00,0x00,0xDD,0xEE,0xFF
看来ARM并没有在松懈的结构体中刺进其他变量。
试验四:
使用了自己的一个大的工程,200K左右的RO以及80K左右的RW+ZI,做了一下优化,发现作用显着,RW+ZI缩减了不少。
最终,想到了ADS里边的编译选项,三个级其他优化以及For time/For spce选项都不能改动这个成果。
定论:(本文根据ARM7TDMI)
ARM中结构体的成员的写法能够决议最终的耗用内存的巨细,恰当的优化能够节约很多名贵的RAM。