乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Big endian and Little endian

       @IT小小鳥@ 2012-03-17
      談到字節(jié)排序的問(wèn)題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列
      CPU。PowerPC系列采用big endian方式存儲(chǔ)數(shù)據(jù),而x86系列則采用little
      endian方式存儲(chǔ)數(shù)據(jù)。ARM同時(shí)支持 big和little,實(shí)際應(yīng)用中通常使用little
      endian。那么究竟什么是big endian,什么又是little endian呢?

      其實(shí)big endian是指低地址存放最高有效字節(jié)(MSB),而little
      endian則是低地址存放最低有效字節(jié)(LSB)。用文字說(shuō)明可能比較抽象,下面用圖像加以說(shuō)明。比如數(shù)字0x12345678在兩種不同字節(jié)序CPU中的存儲(chǔ)順序如下所示:

      Big Endian
      一個(gè)Word中的高位的Byte放在內(nèi)存中這個(gè)Word區(qū)域的低地址處

      低地址 高地址
      ----------------------------------------->
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      | 12 | 34 | 56 | 78 |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      Little Endian
      一個(gè)Word中的低位的Byte放在內(nèi)存中這個(gè)Word區(qū)域的低地址處

      低地址 高地址
      ----------------------------------------->
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      | 78 | 56 | 34 | 12 |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      從上面兩圖可以看出,采用big
      endian方式存儲(chǔ)數(shù)據(jù)是符合我們?nèi)祟惖乃季S習(xí)慣的。必須注意的是:一個(gè)Word的長(zhǎng)度是16位,一個(gè)Byte的長(zhǎng)度是8位。如果一個(gè)數(shù)超過(guò)一個(gè)
      Word的長(zhǎng)度,必須先按Word分成若干部分,然后每一部分(即每個(gè)Word內(nèi)部)按Big-Endian或者Little-Endian的不同操作來(lái)
      處理字節(jié)。
      一個(gè)例子:
      如果我們將0x1234abcd寫入到以0x0000開始的內(nèi)存中,則結(jié)果為
      big-endian little-endian
      0x0000 0x12 0xcd
      0x0001 0x34 0xab
      0x0002 0xab 0x34
      0x0003 0xcd 0x12

      需要特別說(shuō)明的是,以上假設(shè)機(jī)器是每個(gè)內(nèi)存單元以8位即一個(gè)字節(jié)為單位的.簡(jiǎn)單的說(shuō),little
      endian把低位存放到高位,而big endian把低位存放到低位.
      現(xiàn)在主流的CPU,intel系列的是采用的little
      endian的格式存放數(shù)據(jù),而motorola系列的CPU采用的是big endian.
      以下是判斷字節(jié)存儲(chǔ)順序的可移植的C語(yǔ)言代碼:
      /*可移植的用于判斷存儲(chǔ)格式是
      little endian還是big ednian的C代碼*/
      #include < stdio.h >
      union
      {
      long Long;
      char Char[ sizeof ( long )];
      } u;

      int main()
      {
      u.Long = 1 ;
      if (u.Char[ 0 ] == 1 )
      {
      printf( " Little Endian!\n " );
      }
      else if (u.Char[ sizeof ( long ) - 1 ] == 1 )
      {
      printf( " Big Endian!\n " );
      }
      else
      {
      printf( " Unknown Addressing!\n " );
      }

      printf( " Now, Let's look at every byte in the memory!\n " );
      for ( int i = 0 ; i < sizeof ( long ); ++ i)
      {
      printf( " [%x] = %x\n " , & u.Char[i], u.Char[i]);
      }
      return 0 ;
      }
      在 網(wǎng)絡(luò)編程中,TCP/IP統(tǒng)一采用big
      endian方式傳送數(shù)據(jù),也就是說(shuō),假設(shè)現(xiàn)在是在一個(gè)字節(jié)順序是little
      endian的機(jī)器上傳送數(shù)據(jù),要求傳送的數(shù)據(jù)是0XCEFABOBO,那么你就要以0XBOBOFACE的順序在unsigned
      int中存放這個(gè)數(shù)據(jù),只有這樣才能保證存放的順序滿足TCP/IP的字節(jié)順序要求.很多時(shí)候,需要自己編寫應(yīng)用層的協(xié)議,字節(jié)順序的概念在這個(gè)時(shí)候就顯
      得及其的重要了.
      下面給出的是在big endian和little
      endian中相互轉(zhuǎn)換的代碼,C語(yǔ)言強(qiáng)大的位操作的能力在這里顯示了出來(lái):
      /*在little endian和big ednian之間相互轉(zhuǎn)化數(shù)據(jù)的演示代碼*/
      #include < stdio.h >
      const unsigned char SIZE_OF_UNSIGNEDINT = sizeof (unsigned int );
      const unsigned char SIZE_OF_UNSIGNEDCHAR = sizeof (unsigned char );

      void put_32(unsigned char * cmd, unsigned int data)
      {
      int i;
      for (i = SIZE_OF_UNSIGNEDINT - 1 ; i >= 0 ; -- i)
      {
      cmd[i] = data % 256 ;
      // 或者可以:
      // cmd[i] = data & 0xFF;
      data = data >> 8 ;
      }
      }

      unsigned int get_32(unsigned char * cmd)
      {
      unsigned int ret;
      int i;
      for (ret = 0 , i = SIZE_OF_UNSIGNEDINT - 1 ; i >= 0 ; -- i)
      {
      ret = ret << 8 ;
      ret |= cmd[i];
      }
      return ret;
      }

      int main( void )
      {
      unsigned char cmd[SIZE_OF_UNSIGNEDINT];
      unsigned int data, ret;
      unsigned char * p;
      int i;
      data = 0x12345678 ;
      printf( " data = %x\n " , data);
      // 以字節(jié)為單位打印出數(shù)據(jù)
      p = (unsigned char * )( & data);
      for(i = 0 ; i < SIZE_OF_UNSIGNEDINT; ++ i)
      {
      printf( " %x " , * p ++ );
      }
      printf( " \n " );
      //以相反的順序存放到cmd之中
      put_32(cmd, data);
      for (i = 0 ; i < SIZE_OF_UNSIGNEDINT; ++ i)
      {
      printf( " cmd[%d] = %x\n " , i, cmd[i]);
      }
      // 再以相反的順序保存數(shù)據(jù)到ret中
      // 保存之后的ret數(shù)值應(yīng)該與data相同
      ret = get_32(cmd);
      printf( " ret = %x\n " , ret);
      p = (unsigned char * )( & ret);
      for(i = 0 ; i < SIZE_OF_UNSIGNEDINT; ++ i)
      {
      printf( " %x " , * p ++ );
      }
      printf( " \n " );
      return 0 ;
      }

      為什么要注意字節(jié)序的問(wèn)題呢?你可能這么問(wèn)。當(dāng)然,如果你寫的程序只在單機(jī)環(huán)境下面運(yùn)行,并且不和別人的程序打交道,那么你完全可以忽略字節(jié)序的存在。但
      是,如果你的程序要跟別人的程序產(chǎn)生交互呢?在這里我想說(shuō)說(shuō)兩種語(yǔ)言。C/C++語(yǔ)言編寫的程序里數(shù)據(jù)存儲(chǔ)順序是跟編譯平臺(tái)所在的CPU相關(guān)的,而
      JAVA編寫的程序則唯一采用big
      endian方式來(lái)存儲(chǔ)數(shù)據(jù)。試想,如果你用C/C++語(yǔ)言在x86平臺(tái)下編寫的程序跟別人的JAVA程序互通時(shí)會(huì)產(chǎn)生什么結(jié)果?就拿上面的
      0x12345678來(lái)說(shuō),你的程序傳遞給別人的一個(gè)數(shù)據(jù),將指向0x12345678的指針傳給了JAVA程序,由于JAVA采取big
      endian方式存儲(chǔ)數(shù)據(jù),很自然的它會(huì)將你的數(shù)據(jù)翻譯為0x78563412。什么?竟然變成另外一個(gè)數(shù)字了?是的,就是這種后果。因此,在你的C程序
      傳給JAVA程序之前有必要進(jìn)行字節(jié)序的轉(zhuǎn)換工作。

      所有網(wǎng)絡(luò)協(xié)議也都是采用big endian的方式來(lái)傳輸數(shù)據(jù)的。所以有時(shí)我們也會(huì)把big
      endian方式稱之為網(wǎng)絡(luò)字節(jié)序。當(dāng)兩臺(tái)采用不同字節(jié)序的主機(jī)通信時(shí),在發(fā)送數(shù)據(jù)之前都必須經(jīng)過(guò)字節(jié)序的轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序后再進(jìn)行傳輸。ANSI
      C中提供了下面四個(gè)轉(zhuǎn)換字節(jié)序的宏。

      當(dāng)前的存儲(chǔ)器,多以byte為訪問(wèn)的最小單元,當(dāng)一個(gè)邏輯上的整理必須分割為物理
      上的若干單元時(shí)就存在了先放誰(shuí)后放誰(shuí)的問(wèn)題,于是endian的問(wèn)題應(yīng)運(yùn)而生了,對(duì)于不同的存儲(chǔ)方法,就有Big-endian和Little-
      endian兩個(gè)描述.(這兩個(gè)術(shù)語(yǔ)來(lái)自于 Jonathan Swift
      的《《格利佛游記》其中交戰(zhàn)的兩個(gè)派別無(wú)法就應(yīng)該從哪一端--小端還是大端--打開一個(gè)半熟的雞蛋達(dá)成一致。在那個(gè)時(shí)代,Swift是在諷刺英國(guó)和法國(guó)之
      間的持續(xù)沖突,Danny
      Cohen,一位網(wǎng)絡(luò)協(xié)議的早期開創(chuàng)者,第一次使用這兩個(gè)術(shù)語(yǔ)來(lái)指代字節(jié)順序,后來(lái)這個(gè)術(shù)語(yǔ)被廣泛接納了。)
      存在"如果說(shuō)"跟word或者說(shuō)字長(zhǎng)根本就沒(méi)關(guān)系",假設(shè)有一數(shù)據(jù)文件里面有N多數(shù)順序排布,如果想以Little-Endian
      format
      讀入內(nèi)存某區(qū)域,那么應(yīng)該怎么讀?怎么排?"這樣的問(wèn)題是由于對(duì)于endian的實(shí)質(zhì)理解的偏差,endian指的是當(dāng)物理上的最小單元比邏輯上的最小單
      元小時(shí),邏輯到物理的單元排布關(guān)系。這里的"有一數(shù)據(jù)文件里面有N多數(shù)順序排布",這個(gè)"有一數(shù)據(jù)"顯然不是邏輯上的最小單元,而其中的"N多數(shù)"的一個(gè)
      才是邏輯最小單元,于是可應(yīng)用樓主表格中的原則排列,而"N多數(shù)"之間的順序則是由這"N多數(shù)"的宿主決定的,比如是你寫的程序,這個(gè)順序由你決定.

      剛才談到了,endian指的是當(dāng)物理上的最小單元比邏輯上的最小單元小時(shí),邏輯到物理的單元排布關(guān)系。咱們接觸到的物理單元最小都是byte,在通信領(lǐng)域中,這里往往是bit,不過(guò)原理也是類似的。

      實(shí)踐可以給你更多的經(jīng)驗(yàn),比如在一個(gè)嵌入式系統(tǒng)的通信協(xié)議中,從底層射頻驅(qū)動(dòng)到上層的協(xié)議棧全部需要實(shí)現(xiàn),那么很可能遇到多個(gè)endian的問(wèn)題,底層的bit序、協(xié)議層的byte序、應(yīng)用層的byte序,這些都是不同的概念.

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多