当前位置: 代码迷 >> 综合 >> ADS ADS1.2 内存字节对齐
  详细解决方案

ADS ADS1.2 内存字节对齐

热度:18   发布时间:2023-12-07 04:59:39.0

ADS环境下,有“ALIGN 、“__align(x) 、“__packed”关键字用于字节对齐处理。ALIGN用于汇编语言,__align(x)用于C语言,__packed用于不使用字节对齐。

 

 

预编译指令 #pragma pack(X)不行

可以
直接在定义前用type qualifier __align()
eg:

__align(4) struct{
       int i;
       char c;
};
4字节对齐,占8字节。

__pack关键字反而是"打包"的意思,表示不使用字节对齐
__packed struct{
       int i;
       char c;
};
仅占5字节

情参考下边文章

http://blog.21ic.com/user1/516/33973.html

http://hi.baidu.com/%CE%F7204/blog/item/0bc9e10326dea2ed08fa9308.html

http://blog.csdn.net/panqihe/archive/2007/10/13/1822807.aspx

 

 

 

ARM数据对齐 ----- ADS1.2编译

 

<!--[if !supportLists]-->一、        问题来源<!--[endif]-->

且看下面一段代码:

char    buff[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xbc, 0xcd};

int      v32, *p32;

short v16, *p16;

p32 = (int*)&( buff[1] );  

p16 = (short*)&( buff[1] );

v32 = *p32;

v16 = *p16;

我们来看看在ADS1.2编译后,执行的结果如下:

v32 = 0x12785634

v16 = 0x1234

不管数据模式是大端结构,还是小端结构,结果都不对。

 

<!--[if !supportLists]-->二、分析原因<!--[endif]-->

默认情况下,ADS编译器使用的是数据类型的自然边界对其方式。数据的自然对其方式是指:如果该数据类型是n个字节的,那么该数据类型就按n字节对齐。例如:

    1.、Usigned char 是1字节的,那么数据就按1字节对齐。

定义两个变量如下: usigned char a08,b08;

如果a08所在的地址为,0x80000002,则b08所在的地址为0x80000003,两个变量是连续分配的。

    2、Usigned short 是2字节的,那么数据就按2字节对齐。

              定义两个变量如下: usigned char   a08;

                           Usigned short a16;

            如果a08所在的地址为0x80000002,那么a16所在的地址为0x80000004,a16不会分配到0x80000003,默认情况下,编译器为usigned short类型的变量分配到2的倍数的地址处。

    2、usigned long 是4字节的,那么数据就按4字节对齐。

              定义两个变量如下: usigned char   a08;

                           Usigned long a32

            如果a08所在的地址为0x80000005,那么a16所在的地址为0x80000008,a32不会分配到0x80000006,默认情况下,编译器为usigned long类型的变量分配到4的倍数的地址处。

 

<!--[if !supportLists]-->三、解决办法<!--[endif]-->

如果我们想要让编译器不使用自然边界对齐,让任何类型的变量都紧接着上一变量的地址进行分配,可以使用__packed关键字。

       (未完)

 

 

 

<!--[if !supportLists]-->四、使用__packed的注意事项<!--[endif]-->

1、__packed 对局部变量无效。

2、声明为__packed 的变量,必须使用__packed 的指针变量来指向其地址。

   如:

      __packed u16 u16a;

      __packed u16 *pu16;

      pu16 = (u16 *)&u16a;

3、声明为__packed 的结构

      声明为__packed 的结构仅仅

4、声明为__packed 的结构变量

 

<!--[if !supportLists]-->五、后记<!--[endif]-->

以上内容未经测试,由ADS编译器手册及相关资料理解总结所得。

不建议使用__packed 来节省数据大小,因为这需要付出减低执行效率和浪费代码空间的代价。