ARM數據對齊 ----- ADS1.2編譯

 

ARM數據對齊  -----  ADS1.2編譯

 

一、        問題來源

且看下面一段代碼:

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

不管數據模式是大端結構,還是小端結構,結果都不對。

 

二、分析原因

默認情況下,ADS編譯器使用的是數據類型的自然邊界對其方式。數據的自然對其方式是指:如果該數據類型是n個字節的,那麼該數據類型就按n字節對齊。例如:

    1.Usigned char 1字節的,那麼數據就按1字節對齊。

定義兩個變量如下: usigned char  a08,b08;

如果a08所在的地址爲,0x80000002,則b08所在的地址爲0x80000003,兩個變量是連續分配的。

    2Usigned short 2字節的,那麼數據就按2字節對齊。

              定義兩個變量如下: usigned char   a08;

                           Usigned short  a16;

            如果a08所在的地址爲0x80000002,那麼a16所在的地址爲0x80000004a16不會分配到0x80000003,默認情況下,編譯器爲usigned short類型的變量分配到2的倍數的地址處。

    2usigned long 4字節的,那麼數據就按4字節對齊。

              定義兩個變量如下: usigned char   a08;

                           Usigned long   a32

            如果a08所在的地址爲0x80000005,那麼a16所在的地址爲0x80000008a32不會分配到0x80000006,默認情況下,編譯器爲usigned long類型的變量分配到4的倍數的地址處。

 

三、解決辦法

  如果我們想要讓編譯器不使用自然邊界對齊,讓任何類型的變量都緊接着上一變量的地址進行分配,可以使用__packed關鍵字。

       (未完)

 

 

 

四、使用__packed的注意事項

1__packed 對局部變量無效。

2、聲明爲__packed 的變量,必須使用__packed 的指針變量來指向其地址。

   如:

      __packed  u16  u16a;

      __packed  u16  *pu16;

      pu16 = (u16 *)&u16a;

3、聲明爲__packed 的結構

      聲明爲__packed 的結構僅僅

4、聲明爲__packed 的結構變量

 

五、後記

以上內容未經測試,由ADS編譯器手冊及相關資料理解總結所得。

不建議使用__packed 來節省數據大小,因爲這需要付出減低執行效率和浪費代碼空間的代價。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章