<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
在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編譯
一、 問題來源<!--[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
不管資料模式是大端結構,還是小端結構,結果都不對。
二、分析原因<!--[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;
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
如果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的倍數的位址處。
三、解決辦法<!--[endif]-->
如果我們想要讓編譯器不使用自然邊界對齊,讓任何類型的變量都緊接着上一變量的位址進行配置設定,可以使用__packed關鍵字。
(未完)
四、使用__packed的注意事項<!--[endif]-->
1、__packed 對局部變量無效。
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
2、聲明為__packed 的變量,必須使用__packed 的指針變量來指向其位址。
如:
__packed u16 u16a;
__packed u16 *pu16;
pu16 = (u16 *)&u16a;
3、聲明為__packed 的結構
聲明為__packed 的結構僅僅
4、聲明為__packed 的結構變量
五、後記<!--[endif]-->
以上内容未經測試,由ADS編譯器手冊及相關資料了解總結所得。
不建議使用__packed 來節省資料大小,因為這需要付出減低執行效率和浪費代碼空間的代價。