<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ARM程序由于字節對齊引起的問(wèn)題深入分析

ARM程序由于字節對齊引起的問(wèn)題深入分析

作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò ) 收藏
首先說(shuō)說(shuō),什么叫對齊。如果一個(gè)數據是從偶地址開(kāi)始的連續存儲,那么它就是半字對齊,否則就是非半字對齊;半字對齊的特征是bit0=0,其他位為任意 值。字對齊的特征是bit1=0,bit0=1,其他位為任意值。如果一個(gè)數據是以能被4 整除的地址開(kāi)始的連續存儲,那么它就是字對齊,否則就是非字對齊。舉例說(shuō)明四字節對齊: 對內存進(jìn)行操作時(shí),被訪(fǎng)問(wèn)的地址必須為4的倍數。如果分配到的地址的地址不是4的倍數時(shí),CPU實(shí)際訪(fǎng)問(wèn)的地址還是按照字對齊的方式來(lái)操作。也就是自動(dòng)屏蔽bit1和bit0.
用ADS的ARMC Complier下Optimization Level可能引起問(wèn)題,其中的一個(gè)問(wèn)題就是字節對齊的問(wèn)題。下面講講問(wèn)題的現象及實(shí)質(zhì)。
當時(shí)問(wèn)題的現象是:程序使 用一公共變量Buf創(chuàng )建隊列,如果ADS編譯優(yōu)化選項采用Minium則軟件工作正常;源碼不變,如果采用ALL優(yōu)化,則不正常,數據紊亂且無(wú)法工作。為 了發(fā)現問(wèn)題,我們分別用Minium和ALL編譯,在反匯編條件下單步跟蹤程序,觀(guān)察CPU寄存器和內存變量的變化情況。發(fā)現在Minium模式下,編譯 器把隊列內存塊Uart0TxBuf分配到的地址是0x400015cc,這個(gè)地址是一個(gè)4字節對齊的地址,而在A(yíng)LL模式下,編譯器把Buf分配的地址 是0x400015c2,這個(gè)地址是一個(gè)非4字節對齊的地址。正是由于這個(gè)非4字節對齊的地址導致了問(wèn)題的發(fā)生。
問(wèn)題發(fā)生在QueueCreate(void *Buf, uint32 SizeOfBuf, uint8 (* ReadEmpty)(), uint8 (* WriteFull)())這個(gè)函數里,問(wèn)題是如何發(fā)生的,
在了解問(wèn)題發(fā)生的機理前,先了解QueueCreate這個(gè)函數的工作原理。QueueCreate工作原理是,首先把buf指向的內存初始化為DataQueue格式的結構體。DataQueue的結構體格式如下:
typedef struct {
QUEUE_DATA_TYPE *Out; /* 指向數據輸出位置 */
QUEUE_DATA_TYPE *In; /* 指向數據輸入位置 */
QUEUE_DATA_TYPE *End; /* 指向Buf的結束位置 */
uint16 NData; /* 隊列中數據個(gè)數 */
uint16 MaxData; /* 隊列中允許存儲的數據個(gè)數 */

uint8 (* ReadEmpty)(); /* 讀空處理函數 */
uint8 (* WriteFull)(); /* 寫(xiě)滿(mǎn)處理函數 */
QUEUE_DATA_TYPE *Buf; /* 存儲數據的空間 */
} DataQueue;
從結構體可以看出,結構體字節類(lèi)型在內存分配為: 4字節指針變量(*Out)、4字節指針變量(*In)、4字節指針變量(*End)、2字節變量NData、2字節變量MaxData、4字節函數指針 變量ReadEmpty()、4字節函數指針變量 WriteFull()。
觀(guān)察結構體起始地址放在非對齊時(shí)會(huì )出現什么情況。
起始地址為0x400015c2時(shí)的由編譯器分配得到的地址 實(shí)際操作地址
*Out 0x400015c2~0x400015c5 0x40015c0~0x400015c3
*In 0x400014c6~0x400015c9 0x400014c4~0x400015c7
*End 0x400015ca~0x400015cd 0x400015c8~0x400015cb
從表中可以看出,實(shí)際操作的地址按照4字節對齊格式得到。例如,當執行*Out進(jìn)行操作時(shí),自動(dòng)屏蔽bit1和bit0,因此實(shí)際發(fā)生變化的是 0x40015c0~0x400015c3,而不是0x400015c2~0x400015c5,由于實(shí)際操作地址和編譯器分配地址互相覆蓋,當對*In 操作時(shí),會(huì )導致*Out一起變化,對*End操作時(shí),*In也跟著(zhù)變化。正是由于非對齊的原因導致創(chuàng )建隊列和對列操作完全錯誤。
當內存起始地址為4字節對齊地址的情況時(shí),編譯器分配地址和實(shí)際地址一致,因此不存在上述問(wèn)題。
結 論:
在A(yíng)RM嵌入式系統中,當把一個(gè)內存區域初始化為某個(gè)結構體時(shí),必須注意字節對齊的情況。如果該內存起始地址為非對齊地址,不僅得不到預期的結果,還可能 導致一些很奇怪的讓人無(wú)法理解表面問(wèn)題。在C層面上不太容易觀(guān)察到這些問(wèn)題的實(shí)質(zhì),只有深入到匯編一層去分析程序,才可能理解這些現象的深層原因。


關(guān)鍵詞: ARM程序字節對

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>