C語言是一種高級語言,在大多數情況下C語言的代碼是和具體的處理器體系結構無關的。然而,在嵌入式系統的編程中,有可能涉及對內存的具體操作。在大小端和內存對齊問題上,C語言就不能屏蔽不同體系結構處理器的差別,也就是說同樣的C語言代碼在不同的體系結構的處理器上,有可能產生不同的結果。
大小端問題又叫字節序的問題。在各種體系結構的處理器中,對多字節數據的內存操作有著不同的定義。處理器對內存數據的操作有讀寫兩種,這就涉及處理器在讀寫一個多字節的內存的時候,高字節是在內存的高地址還是低地址。一般在32位或者16位的處理器中,都具有將32位數據和16位數據讀寫到內存中的指令,這時不同的大小端模式將有不同的結果。
如果讀寫指令針對的數據長度和類型是一致的,無論數據在內存中存放的形式如何,處理器整體讀寫都沒有問題。這種整內存協調的讀寫操作問題,一般不會涉及處理器的大小端。
當處理器讀寫指令針對的數據長度不一致的時候就會涉及大小端的問題,例如:
將0x76543210整體放入內存,然后在內存的首地址用單字節讀取的命令讀出。
如果不知道大小端模式的情況下,讀取的值是多少你能確定嗎?
這時就涉及處理器是大端還是小端的問題。
對于小端處理器,寫內存的時候會將內存低地址處放入源數據的低字節,在內存的高地址處放入源數據的高字節;讀內存的時候,將內存中低地址的數據就視為目標數據的低字節,對應的高地址數據是目標數據的高字節。
對于大端處理器,跟小端就相反的。內存低地址存放數據的高字節,高地址存放數據的低字節。
上面的示例只是處理器自身讀取和寫入內存的情況,在更多的情況下,內存中的數據可能來自外界的輸入,例如:來自網絡的數據包;處理器在寫內存的時候,這塊內存也可能是給系統中別的設備使用的,例如:處理器寫顯示內存的情況。這時,就更需要注意處理器的大小端問題,只有大小端處理協調匹配,才能獲得正確的結果。
在C語言中,使用指針就可以操作內存,指針的基本類型long和short分別代表了32位和16位的數據。使用16位或32位指針操作內存的時候,同樣涉及內存的大小端問題。
上面我們說了一下內存讀寫的模式不同,一個地址存的數據不同。
接下來我們說一下內存對齊的問題,有人會說了內存對齊不對齊還需要你來管嗎?這個在寫程序的時候也是有講究的,那么到底什么是內存對齊?為什么要有這個概念呢,我們來一起學習一下吧。
內存對齊操作的含義是:對于一個4字節的數據,要求其內存是4字節對齊的(地址為4字節的整數倍)。32位對齊的含義是其內存的地址的最低位是:0x0,0x4,0x8,0xC
16位對齊的含義是其內存的地址的最低位是:0x0,0x2,0x4,0x6,0x8,0xA,0xC,0xE
顯然,對于單字節的內存讀寫操作,沒有內存對齊的問題。從處理器硬件的角度,處理器更適合處理對齊的內存操作。對于非對齊的內存操作,不同的處理器則有不同的結果。
局部變量建立在棧空間上的,由編譯器分配,一般保證它們都是對齊的。但是在程序中可能出現不對齊的內存操作。對于嵌入式系統中常用的ARM體系結構,并不支持不對齊的地址操作,當進行不對齊的地址訪問的時候,處理器將引發異常。
在嵌入式程序的編寫過程中,更需要注意內存對齊的問題。對于內存操作,使用字節操作(8bit)不會有內存對齊的問題,但是效率比較低。在32位系統中,應該盡量使用32位的數據操作,但這將帶來內存對齊的問題,因此需要根據系統的具體情況選擇合適的內存操作。
我們再來說說常糾結或者容易迷惑的結構體成員的對齊問題。
結構體是一個基本的語法單元。在32位系統中,編譯器一般會對結構體的成員變量作一定的對齊處理。例如,在程序中定義如下結構體:
typedef struct _S1
{
char m1;
int m2;
char m3;
short m4;
}S1;
在結構體的定義上,結構體的大小應該是各個結構體成員的大小之和。但是,對于上面這個結構體S1,它的大小并不等于4個成員變量之和。在這種定義中,三個成員變量之和是1+4+2+2=8,但是結構體的大小并不是8字節。
編譯器在處理結構體的時候,默認將結構體內部各個變量的內存都是對齊的,由此在結構體的內部可能出現一些空的字節。
一般情況下,在結構體含有4字節長整型成員的時候,結構體的大小將是4字節的倍數。為了對齊可能需要在結構體的最后補充1~3個字節。
如果結構體中含有2字節短整型成員的時候,結構體的大小將是2字節的倍數。為了對齊可能需要在結構體的最后補充一個字節。
這個算字節數的一般出現在找工作中的筆試題的概率還是很高的,其實就是考察的對這個內存對齊的掌握。
責任編輯:haq
-
嵌入式
+關注
關注
5068文章
19017瀏覽量
303241 -
C語言
+關注
關注
180文章
7598瀏覽量
136184
原文標題:在嵌入式系統中大小端和對齊問題
文章出處:【微信號:CanaanTech,微信公眾號:嘉楠科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論