字節序問題之大小端模式講解


一、什么是大小端模式

大端模式(Big-Endian):指的是數據的低位保存在內存的高地址中,而數據的高位保存在內存的低地址中.

小端模式(Little-Endian):指的是數據的低位保存在內存的低地址中,而數據的高位保存在內存的高地址中。

上述的描述准確的說明了大小端模式的數據排列方式,但是還不夠直觀,下面我們來舉個例子:

如:數字 0x12345678 在內存中的表示形式為:

大端模式:

低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78

小端模式:

低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12

大小端模式的優劣勢比較

大端模式:強制轉換數據不需要調整字節內容。

小端模式:符號位的判斷直接看第一個字節,容易判斷正負。

基本上各自的優點就是對方的缺點,采用大端存儲模式存儲數據更符合人類的思維,采用小端存儲數據更方便計算機進行數據處理。

開發的時候必須要考慮大小端模式問題,若不考慮這些就收發數據會發生問題,因為保存順序的不同意味着對接收數據的解析順序也不同。

二、為什么有大小端模式

因為在計算系統中,我們是以字節為單位的,每個地址單元都對應着一個字節,一個字節為8bit。對於位數大於8位的處理器,例如目前大部分都32位或者64位的處理器,由於寄存器寬度大於一個字節,那么必然存在着一個如果將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。我們常用的X86結構是小端模式,而KEIL C51則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。

三、常見字節序的模式

1、常見的CPU的字節序

大端模式: PowerPC、IBM、Sun;

小端模式 : x86、DEC;

ARM既可以工作在大端模式,也可以工作在小端模式。

2、常見文件的字節序

大端模式:Adobe PS、JPEG、MacPaint;

小端模式:BMP、GIF、RTF;

另外,Java和所有的網絡通訊協議都是使用Big-Endian的編碼。在對普通文件進行處理也需要考慮端模式問題。在大端模式的處理器下對文件的32,16位讀寫操作所得到的結果與小端模式的處理器不同。單純從軟件的角度理解上遠遠不能真正理解大小端模式的區別。事實上,真正的理解大小端模式的區別,必須要從系統的角度,從指令集,寄存器和數據總線上深入理解,大小端模式的區別。從實際應用的角度說,采用小端模式的處理器需要在軟件中處理端模式的轉換,因為采用小端模式的處理器在與小端外設互連時,不需要任何轉換。而采用大端模式的處理器需要在硬件設計時處理端模式的轉換。大端模式處理器需要在寄存器,指令集,數據總線及數據總線與小端外設的連接等等多個方面進行處理,以解決與小端外設連接時的端模式轉換問題。在寄存器和數據總線的位序定義上,基於大小端模式的處理器有所不同。

四、如何判斷CPU的字節序

下面這段代碼可以用來測試一下你的編譯器是大端模式還是小端模式:

short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址單元
x1=((char*)&x)[1]; //高地址單元
若x0=0x11,則是大端; 若x0=0x22,則是小端。從上面的程序還可以看出,數據尋址時,用的是低位字節的地址。

五、如何進行大小端轉換

這里我們使用C語言大小端轉化調用庫函數:

 

在網絡傳輸中,一般要求是大端,而intel處理器是小端,network to host理解為大端轉小端,而host to network 理解為小端轉大端,本質上大端小端的轉化算法是一致的,沒有區別。

示例代碼如下:

#include<stdio.h>
#include<Winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int main(void) {
   unsigned int  ultest=0x12345678;
   unsigned short ustest=0x1234;

   printf("ultest小端:%x\n",ultest);
   printf("ustest小端:%x\n",ustest);
   ultest=htonl(ultest);/*unsigned int   大小端轉化*/
   ustest=htons(ustest);/*unsigned short 大小端轉化*/
   printf("ultest大端:%x\n",ultest);
   printf("ustest大端:%x\n",ustest);
   while(1);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM