所謂的大端模式,是指資料的低位(就是權值較小的後面那幾位)儲存在記憶體的高位址中,而資料的高位,儲存在記憶體的低位址中,這樣的儲存模式有點兒類似於把資料當作字串順序處理:位址由小向大增加,而資料從高位往低位放;
所謂的小端模式,是指資料的低位儲存在記憶體的低位址中,而資料的高位儲存在記憶體的高位址中,這種儲存模式將位址的高低和資料位權有效地結合起來,高位址部分權值高,低位址部分權值低,和我們的邏輯方法一致。
為什麼會有大小端模式之分呢?這是因為在計算機系統中,我們是以位元組為單位的也是以位元組為單位來定址的,每個位址單元都對應著乙個位元組,乙個位元組為 8bit。但是在c語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對於位數大於8位的處理器,例如16位或者32位的處理器,由於暫存器寬度大於乙個位元組,那麼必然存在著乙個如果將多個位元組安排的問題。因此就導致了大端儲存模式和小端儲存模式。例如乙個16bit的short型x,在記憶體中的位址為0x0010,x的值為0x1122,那麼0x11為高位元組,0x22為低位元組。對於大端模式,就將0x11放在低位址中,即0x0010中,0x22放在高位址中,即0x0011中。小端模式,剛好相反。我們常用的x86結構是小端模式,而keil c51則為大端模式。很多的arm,dsp都為小端模式。有些arm處理器還可以由硬體來選擇是大端模式還是小端模式。
大小端的問題,主要是由於字長大於8bit的處理器,在處理乙個字的時候,將其拆分成多個位元組的表示方法。對於大端處理器,高位在低位址,低位在高位址。如0x12345678,在記憶體中這樣表示:
位址 78 79 7a 7b
資料 12 34 56 78
對於這個32位的整數在記憶體中的存放位置,在x86中由於是32位的處理器所以在記憶體中定址的位址也為32位,每個32位的位址定址乙個位元組,假設存放這32位整數的起始位址為0x0012ff78,則在x86這樣的小端模式中存放順序依次為78,56,34,12,為什麼不是直接反序(87,65,43,21),我們知道在記憶體中都是以位元組為單位來定址的,所以存放資料的最小單位也就是位元組。一般,arm/mips/ppc都是大端處理器。
而對於小端處理器,低位在低位址,高位在高位址。0x12345678這樣排列:
位址 00 01 02 03
資料 78 56 34 12
x86屬於小端。
這兩種排列方法沒有好壞之分,但是,對於不同體系結構的處理器之間通訊的時候,有可能產生問題。如mips機器傳送0x12345678,到了x86接收的時候,就成了0x78563412。
試想,如果通訊中發生這種錯誤,多可怕啊——
「呼叫021,呼叫021」
那邊,120收到了:「收到呼叫,收到呼叫」
「炮轟3309地區!」
「明白,炮火覆蓋9033地區」~
於是,無數我方戰士被自己人的炮火……
因此,人們制定了網路位元組序——和大端位元組序一致,高位元組先發,低位元組後發。這樣,對於x86和mips/arm/ppc處理器,對資料的處理流程就不一樣了。x86需要將收到的資料按位元組序顛倒以後處理,而mips/arm/ppc可以直接處理。編寫程式的工程師們為了讓**可移植,定義了以下的巨集:
htonl /× 主機序轉網路序,long int型別 ×/
ntohl /× 網路序轉主機序,long int型別 ×/
htons /× 主機序轉網路序,short int型別 ×/
ntohs /× 網路序轉主機序,short int型別 ×/
對於小端處理器,這個巨集返回顛倒位元組序後的值,而對於大端處理器什麼都不做。
通過乙個聯合體的例子來在各個不同平台下來做做實驗:
有這樣乙個聯合體資料結構:
typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef union foo_u_ foo_u;
那麼,當這個聯合體中,member1的值為0x12345678的時候,member2[0]和member3[0]各為多少呢?
因為不同體系結構的處理器,不同的編譯器對各種型別所佔的位元組數也有不同,現假設上面的unsigned long佔4個位元組也就是32位,unsigned short佔2個位元組也就是16位,unsigned char佔1個位元組也就是8位。
我們知道聯合體變數的儲存方式,它會按照聯合體中佔位元組數最大的那個型別來開闢記憶體,不是像結構體中為每個成員變數都分配一定的記憶體空間。在聯合體中其他的成員變數都會重複的存放在大型別成員變數的記憶體上。所以乙個成員變數值的改變會影響到其他成員變數。
上面的聯合體變數中的成員變數,所佔記憶體最大的就是佔32位的member1(其實另外兩個成員變數也是32位)所以這裡就會給這個聯合體變數分配4個位元組也就是32位的儲存空間,假如首位址為0x0012ff78,則按照小端模式,在記憶體中排放的順序為:
資料:78 56 34 12
而對於第二個成員變數陣列,含有兩個陣列元素,每個陣列元素佔16位,而且位址也是從第乙個成員變數起始位址開始,所以member2[0]就是0x5678,而member2[1]也就是0x1234,而對於第三個成員變數陣列含有4個陣列元素,member3[0]就是0x78,代表的字元為x
member3[1]也就是0x56,代表字元為v,member3[2]也就是0x34,代表字元為4,member3[3]是0x12代表著乙個小黑塊。
而對於大端模式,聯合體中第二,第三個成員變數的值就會變化。
CmakeLists檢測處理器體系結構
cmake的cmake sizeof void p變數會告訴我們cpu是32位還是64位。我們通過狀態訊息讓使用者知道檢測到的大小,並設定預處理器定義 if cmake sizeof void p equal 8 target compile definitions arch dependent p...
ARM系列處理器的體系結構 1
關於arm系列處理器的體系結構問題,arm的體系結構本來涉及的知識點就比較多和複雜,筆者盡量在此處把知道的一步步的梳理一下 1 關於s3c2440的啟動方式 s3c2440的啟動方式有兩種 1 nand flash啟動 2 nor flash啟動 就是痛撥動開關s2來決定,s2接到nor flash...
CSAPP 第4章 處理器體系結構
4.2 邏輯設計和硬體控制語言hcl 4.3 y86 64的順序實現 seq 4.4 流水線的通用原理 4.5 y86 64的流水線實現 4.5.8 流水線控制邏輯 4.5.9 效能分析 4.5.10 未完成的工作 y86 84指令集體系結構 4.1.1 程式設計師可見狀態 4.1.2 y86 64...