上節計算機組成原理課講到了大端編址和小端編址。
首先,大端編址(Big-Endian)和小端編址(Little-Endian)是兩種字節存儲機制,兩種字節序。標准的Big-Endian和Little-Endian的定義如下:
a) Little-Endian就是低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。
b) Big-Endian就是高位字節排放在內存的低地址端,低位字節排放在內存的高地址端。
一.什么是高低地址端
----------------------- 最高內存地址 0xffffffff
棧底
棧
棧頂
-----------------------
NULL (空洞)
-----------------------
堆
-----------------------
未初始 化的數據
----------------------- 統稱數據段
初始化的數據
-----------------------
正 文段(代碼段)
----------------------- 最低內存地址 0x00000000
由圖可以看出,在內存分布中,棧是向下增長的,而堆是向上增長的。
在棧 上分配一個unsigned char buf[4],那么這個數組變量在棧上是如何布局的呢?看下圖:
棧底 (高地址)
----------
buf[3]
buf[2]
buf[1]
buf[0]
----------
棧頂 (低地址)
二.什么是高低字節。
拿0x12345678來說,從高位到低位的字節依次是0x12、0x34、0x56和0x78。
Big-Endian: 低地址存放高位,如下圖:
棧底 (高地址)
---------------
buf[3] (0x78) -- 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -- 高位
---------------
棧頂 (低地址)
Little-Endian: 低地址存放低位,如下圖:
棧底 (高地址)
---------------
buf[3] (0x12) -- 高位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -- 低位
--------------
棧 頂 (低地址)
三.編寫程序測試CPU是大端編址還是小端編址。
方法一:利用union的成員共享內存而且存放順序是所有成員都從低地址開始存放,可以編寫下面的程序:

1 #include<stdio.h> 2 #include<iostream> 3 4 using namespace std; 5 int main() 6 { 7 union 8 { 9 int a; 10 char b; 11 }c; 12 c.a=1; 13 if(c.b==1) 14 { 15 printf("Little Endian.\n"); 16 } 17 else 18 { 19 printf("Big Endian.\n"); 20 } 21 return 0; 22 }
方法二:通過指針類型強制轉換並對整型數據首字節賦值,判斷該賦值賦給了高位還是低位。

1 #include<stdio.h> 2 3 int main() 4 { 5 short int a=0x1234; 6 char * p=(char*)&a; 7 if(*p==0x12) 8 { 9 printf("Big Endian.\n"); 10 } 11 else 12 { 13 printf("Little Endian.\n"); 14 } 15 return 0; 16 }
經過測試,我的電腦是小端編址,這與上課所學的X86是小端編址,MIPS是大端編址相符。