非對齊位址訪問問題

2021-04-30 00:32:01 字數 1320 閱讀 4247

arm,dsp,powerpc等不支援非對齊位址訪問,x86支援非對齊位址訪問。

為何要位元組對齊?

從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。

tcpip協議棧一直採用的uip,感覺不是很好,想採用網上的流行的lwip協議,移植中出現了個有趣的問題,找了好半天才找到,是位元組對齊問題,用下面這個例子說一下(我用的是keil)

在keil下測試結構

unsigned long * testzy;

testzy =(unsigned long *)0x0400130e;

* testzy = 0x11223344;   //0x0400130c(44 33 22 11) * testzy 真實值變成了 0x00001122

反彙編看

r0=0x11223344;

r1=0x0400130e;

str  r0,[r1]  ; 顯然由於位址0x0400130e不是4的倍數,資料向前移動了 (r0=0x00001122,而不是0x44332211)

但在iar測試下,結果又是正確的。

在ads測試下,也會有問題

在lwip出現問題的地方,是mem_malloc()分配記憶體(通過固定陣列ram)時候錯誤,

ram起始位址在keil下不是4的整數倍,在ads是(怪異)

所以即使取樣了#define mem_alignment   4 // must be 4 for arm system

上面定義只是保證了陣列ram存資料保證4的倍數開始??

這樣系統通過mem_malloc分配記憶體的位址並沒有按四個位元組的倍數來分(keil測試下),這樣往導致分配好後的位址(該位址不是4的倍數)賦值的時候出錯

arm記憶體訪問的對齊問題

按照arm文件上的描述,其訪問規則如下:

1. 一次訪問4位元組內容,該內容的起始位址必須是4位元組對齊的位置上;

2. 一次訪問2位元組內容,該內容的起始位址必須是2位元組對齊的位置上;

(單位元組的沒有這個問題,就不用考慮啦。 )

計算機主要的架構就分為兩類,複雜指令集計算機(cisc)和精簡指令集計算機(risc)。cisc最有代表性的架構就是x86,risc最有代表性的架構就是arm。不管是什麼架構,對要訪問的一定長度的資料的位址是有要求的,比如要訪問乙個32位的整數,那麼這個資料必須(最好)儲存在以4位元組(32/8=4)對齊的地方。一般來說,risc對對齊要求的更嚴格些,非對齊訪問可能會帶來效能上的損失。這對程式在不同架構間移植非常重要,因為它極有可能導致你的程式崩潰。

mips下非對齊訪問問題分析

1.問題 risc 下使用訪存指令讀取或寫入資料單元時,目標位址必須是所訪問之資料單元位元組數的整數倍,這個叫做位址對齊。計算機主要的架構就分為兩類,複雜指令集計算機 cisc 和精簡指令集計算機 risc cisc最有代表性的架構就是x86,risc最有代表性的架構就是arm。不管是什麼架構,對要...

mysql遠端訪問問題

1 進入mysql,建立乙個新使用者xuys 格式 grant 許可權 on 資料庫名.表名 使用者 登入主機 identified by 使用者密碼 grant select,update,insert,delete on to xuys 192.168.88.234 identified by ...

疑問 NSArray 訪問問題

h檔案 import import inte cehelper.h import quartzcore quartzcore.h inte ce fanweiandleixingviewcontroller uiviewcontroller property nonatomic,retain nss...