SylixOS ARM平台下記憶體對齊訪問

2021-08-14 14:14:09 字數 1260 閱讀 9692

現代計算機中記憶體空間都是按照byte劃分的,從理論上講對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。

各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台的要求對資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為 32位)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出,而如果存放在奇位址開始的地方,就可能會需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該int資料。顯然在讀取效率上下降很多。這也是空間和時間的博弈。

在arm中,有arm和thumb兩種指令。arm指令:每執行一條指令,pc的值加4個位元組(32bits),一次訪問4位元組內容,該位元組的起始位址必須是4位元組對齊的位置上,即位址的低兩位為bits[0b00],也就是說位址必須是4的倍數。thumb指令:每執行一條指令,pc的值加2個位元組(16bits),一次訪問2位元組內容,該位元組的起始位址必須是2位元組對齊的位置上,即位址的低兩位為bits[0b0],也就是說位址必須是2的倍數。

遵循以上方式叫對齊(aligned)儲存訪問操作,不遵守這樣方式稱為非對齊(unaligned)儲存訪問操作。sylixos下的arm平台遵守對齊方式。

arm平台下由於記憶體對齊產生的問題,如程式清單 2.1,是一段由於arm平台下遵守記憶體對齊訪問產生問題的**,**是乙個簡單的巨集定義將val值賦值到data位址上。在程式中我們無法保證傳進的引數data是4的整數倍,所以導致了會出現記憶體訪問異常的現象。程式在執行中出現位址訪問錯誤後退出。

程式清單2.1 平台下問題**

#define ec_write_u32(data, val) \

do while (0)      

上述問題可以修改應用層**去避免此類問題。如程式清單3.1,我們定義巨集如果不是x86平台,直接將uint32_t記憶體位址強制轉換成uint8_t位址,再將資料val強制拆分成4個uint8_t型資料分別賦值到對應的uint8_t記憶體位址上。

程式清單3.1 arm平台下避免位元組對齊訪問

#ifdef x86_platform

#define ec_write_u32(data, val) \

do while (0)

#else

#define ec_write_u32(data, val) \

do while (0)…

Linux平台下程式記憶體的分配

程式記憶體分配 1.棧區 stack 由編譯器自動分配釋放,存放為執行函式而分配的區域性變數,函式引數,返回引數,返回位址。其操作方式類似於資料結構中的棧。2.堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 分配方式類似於鍊錶。3.全域性資料區 存放全域性變數,靜...

Android平台下sax,dom,pull解析

1.android中三種xml的解析方式,分別為dom,sax,pull,其中pull的解析方式最優 2.dom,sax,pull解析方式的區別 1 dom解析方式 首先一下子載入整個文件然後再挨個節點解析,費流量 優點 對於處理大文件,以及能力強的cpu效能比較快 缺點 對於處理能力不夠強的cpu...

Android平台下sax,dom,pull解析

1.android中三種xml的解析方式,分別為dom,sax,pull,其中pull的解析方式最優 2.dom,sax,pull解析方式的區別 1 dom解析方式 首先一下子載入整個文件然後再挨個節點解析,費流量 優點 對於處理大文件,以及能力強的cpu效能比較快 缺點 對於處理能力不夠強的cpu...