• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 模擬技術(shù) > 設(shè)計(jì)應(yīng)用 > ARM存儲(chǔ)格式之大端小端

    ARM存儲(chǔ)格式之大端小端

    作者: 時(shí)間:2018-08-06 來源:網(wǎng)絡(luò) 收藏

    開頭講個(gè)有關(guān) 大端小端的故事:

    本文引用地址:http://www.czjhyjcfj.com/article/201808/385422.htm

    端模式(Endian)的這個(gè)詞出自Jonathan Swift書寫的《格列佛游記》。這本書根據(jù)將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為Big Endian,從尖頭開始將雞蛋敲開的人被歸為L(zhǎng)ittile Endian。小人國(guó)的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開。在計(jì)算機(jī)業(yè)Big Endian和Little Endian也幾乎引起一場(chǎng)戰(zhàn)爭(zhēng)。

    我們知道在內(nèi)存中數(shù)據(jù)是以字節(jié)為單位進(jìn)行存儲(chǔ)的,每個(gè)地址單元對(duì)應(yīng)著一個(gè)字節(jié)(byte),一個(gè)字節(jié)為8位(bite)。但是很多時(shí)候數(shù)據(jù)除了8bit額char外,還有16bit的short,32位的long型(要看具體的編譯器),必然存在多字節(jié)安排的問題。不同的計(jì)算機(jī)存放多字節(jié)值的順序不同,有些機(jī)器在起始地址存放低位字節(jié)(低位先存),即小端模式;有的機(jī)器在起始地址存放高位字節(jié)(高位先存),即大端模式。基于Intel的CPU,采用的是低位先存。而KEIL C51則為大端模式。大端小端對(duì)應(yīng)著數(shù)據(jù)在存儲(chǔ)器中的存放順序。

    同時(shí),在網(wǎng)絡(luò)傳輸中,網(wǎng)絡(luò)協(xié)議需要指定網(wǎng)絡(luò)字節(jié)順序,TCP/IP協(xié)議中使用16位整數(shù)和32位整數(shù)的高位先存模式,對(duì)應(yīng)我們的大端模式。

    下面是兩個(gè)具體例子:

    16bit寬的數(shù)0x1234在Little-endian模式(以及Big-endian模式)CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開始存放)為:

    32bit寬的數(shù)0x12345678在Little-endian模式以及Big-endian模式)CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開始存放)為:

    聯(lián)合體union的存放順序是所有成員都從低地址開始存放,利用該特性可以輕松地獲得了CPU對(duì)內(nèi)存采用Little-endian還是Big-endian模式讀寫。

    寫程序判斷處理器是Little-endian模式,還是Big-endian模式,可以通過以下程序:

    1、通過將int強(qiáng)制類型轉(zhuǎn)換成char單字節(jié),通過判斷起始存儲(chǔ)位置。

    1 void main(int argc, char **argv)

    2 {

    3 int i = 1;

    4 char *cp = (char *)i; //前面是指針運(yùn)算符*,前值類型轉(zhuǎn)換。后面是取地址符號(hào)。

    5 if (*cp) //如果此時(shí)cp指向的內(nèi)存為1的話,則為小端,否則為大端。

    6 printf(Little Endiann);

    7 else

    8 printf(Big Endiann);

    9

    10 exit(EXIT_SUCCESS);

    11 }

    注釋:如果小端方式中(i占至少兩個(gè)字節(jié)的長(zhǎng)度)則i所分配的內(nèi)存最小地址那個(gè)字節(jié)中就存著1,其他字節(jié)是0.大端的話則1在i的最高地址字節(jié)處存放,char是一個(gè)字節(jié),所以強(qiáng)制將char型量p指向i則p指向的一定是i的最低地址,那么就可以判斷p中的值是不是1(或者為0,也即是假)來確定是不是小端。

    或者如下程序:

    void main()

    {

    short int x;

    char x0,x1;

    x=0x1122;

    x0=((char*)x)[0]; //低地址單元

    x1=((char*)x)[1]; //高地址單元

    if (0x11 == x0 0x22 == x1)

    {

    cout Big_endian endl;

    }

    else

    {

    cout Little_endian endl;

    }

    }

    2、利用聯(lián)合體union的存放順序是所有成員都從低地址開始存放,判斷處理器模式。

    bool checkCPU( )

    {

    {

    union w

    {

    int a;

    char b;

    } c;

    c.a = 1;

    return(c.b ==1);

    }

    }

    以及如下程序:

    bool isLittleEndian()

    {

    union _dword

    {

    int all;

    struct _bytes

    {

    char byte0;

    char pad[3];

    }bytes;

    }dword;

    dword.all=0x87654321;

    return (0x21==dword.bytes.byte0);

    }

    分析:如果你的處理器調(diào)用函數(shù)isLittleEndian返回1,那么說明你的處理器為little endian,否則為big endian.注意,如果在little endian處理器上,byte0和pad按內(nèi)存從低到高的存放順序:LOW->byte0 pad[0] pad[1] pad[2] ->HIGH;0x87654321按內(nèi)存從低到高的存放順序: 0x21 0x43 0x65 0x87, 可見byte0對(duì)應(yīng)到0x21。所以通過判斷dword中第一個(gè)字節(jié)dword.bytes.byte0是否與0x21相等就可以看出是否是little endian。



    關(guān)鍵詞:

    評(píng)論


    相關(guān)推薦

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 阜平县| 哈巴河县| 丹东市| 福建省| 得荣县| 鹤峰县| 平昌县| 张家界市| 台东县| 南京市| 合阳县| 读书| 正蓝旗| 禄丰县| 措美县| 英吉沙县| 新巴尔虎右旗| 兴山县| 延庆县| 华蓥市| 天长市| 玛纳斯县| 广丰县| 安丘市| 麻阳| 武安市| 沈阳市| 金门县| 和龙市| 兰西县| 永嘉县| 大洼县| 博野县| 荔波县| 通辽市| 香港 | 大关县| 景洪市| 玉山县| 舟曲县| 盱眙县|