天天看點

大端和小端(Big endian and Little endian)

一、大端和小端的問題

對于整型、長整型等資料類型,Big endian 認為第一個位元組是最高位位元組(按照從低位址到高位址的順序存放資料的高位位元組到低位位元組);而 Little endian 則相反,它認為第一個位元組是最低位位元組(按照從低位址到高位址的順序存放據的低位位元組到高位位元組)。

例如,假設從記憶體位址 0x0000 開始有以下資料:  

0x0000         0x0001       0x0002       0x0003  

0x12            0x34           0xab           0xcd 

如果我們去讀取一個位址為 0x0000 的四個位元組變量,若位元組序為big-endian,則讀出結果為0x1234abcd;若位元組序為little-endian,則讀出結果為0xcdab3412。

如果我們将0x1234abcd 寫入到以 0x0000 開始的記憶體中,則Little endian 和 Big endian 模式的存放結果如下:  

位址           0x0000         0x0001        0x0002          0x0003 

big-endian   0x12           0x34            0xab            0xcd  

little-endian  0xcd           0xab            0x34            0x12

一般來說,x86 系列 CPU 都是 little-endian 的位元組序,PowerPC 通常是 big-endian,網絡位元組順序也是 big-endian還有的CPU 能通過跳線來設定 CPU 工作于 Little endian 還是 Big endian 模式。

對于0x12345678的存儲:

小端模式:(從低位元組到高位元組)

地位位址 0x78 0x56 0x34 0x12 高位位址

大端模式:(從高位元組到低位元組)

地位位址 0x12 0x34 0x56 0x78 高位位址

二、大端小端轉換方法

htonl() htons() 從主機位元組順序轉換成網絡位元組順序

ntohl() ntohs() 從網絡位元組順序轉換為主機位元組順序

Big-Endian轉換成Little-Endian

三、大端小端檢測方法

如何檢查處理器是big-endian還是little-endian?

C程式:

<a></a>

    大小端存儲問題,如果小端方式中(i占至少兩個位元組的長度)則i所配置設定的記憶體最小位址那個位元組中就存着1,其他位元組是0.大端的話則1在i的最高位址位元組處存放,char是一個位元組,是以強制将char型量p指向i則p指向的一定是i的最低位址,那麼就可以判斷p中的值是不是1來确定是不是小端。

  聯合體union的存放順序是所有成員都從低位址開始存放,利用該特性就可以輕松地獲得了CPU對記憶體采用Little-endian還是Big-endian模式讀寫。

實作同樣的功能,來看看Linux 作業系統中相關的源代碼是怎麼做的:

Linux 的核心作者們僅僅用一個union 變量和一個簡單的宏定義就實作了一大段代碼同樣的功能!(如果ENDIANNESS=’l’表示系統為little endian,為’b’表示big endian)

四、一些筆試題目

字元'0'對應的十六進制是0x30,請問在x86環境下程式輸出是多少?

假設字元串sz位址從@0開始,那麼sz在記憶體的存儲為 

@0   @1   @2   @3   @4   @5   @6   @7   @8   @9 

0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 

當你把char*強制類型轉化成int*後,因為int占四個位元組,那麼p指向@0,并且*p占有的位址是@0@1@2@3,列印的時候 先進行++p操作,那麼p指向@4,此時*p占有的位址是@4@5@6@7,根據上面地位址存地位,高位址存高位的解釋,那麼*p應該等于0x37363534

例如對于0x12345678,網絡位元組順序是這樣0x12,0x34,0x56,0x78存儲的,這種方式稱為big-endian

intel處理器是0x78 0x56 0x34 0x12這樣來存儲的,稱為小尾little-endian

在x86環境下題目中的p指向0x78,加1後指向0x56

x86下輸出答案: 266 (x86下:低位低位址,高位高位址,i記憶體裡存的值是Ox010A,十進制為266)

x86下輸出答案:

       A B   (0x41對應'A',是低位;Ox42對應'B',是高位)

       6261 (number.i和number.half共用一塊位址空間0x6261)

本文轉自莫水千流部落格園部落格,原文連結:http://www.cnblogs.com/zhoug2020/p/6407528.html,如需轉載請自行聯系原作者