国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

查看: 2183|回復: 0
打印 上一主題 下一主題

嵌入式基礎(chǔ)知識硬件篇之字節(jié)序

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2017-9-8 10:15:10 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
很多人討厭碰到字節(jié)序問題,跟它打交道就像走迷宮,每次都要犧牲不少腦細胞。即使這一次似乎搞清楚了,下次碰到還是要重新在大腦里構(gòu)建和模擬。這里盡量做一個字節(jié)序問的完整備忘記錄。

主機字節(jié)序
多字節(jié)數(shù)據(jù)在內(nèi)存中的字節(jié)排列順序稱為主機字節(jié)序,主機字節(jié)序基本由CPU硬件決定,某些CPU如X86、Z80等為little-endian;有些如moto6800、sparc等為big-endian;而有些CPU可通過寄存器設(shè)置支持不同字節(jié)序,如ARMMIPS等,這類平臺上不同OS可能配置了不同字節(jié)序。

理解字節(jié)序需要知道兩個名詞:MSB (Most Significant Byte),代表一個數(shù)中權(quán)值最大的字節(jié);LSB(Least Significant Byte),代表一個數(shù)中權(quán)值最小的字節(jié)。比如十進制數(shù)1234,1權(quán)值為千位,最大,相當于MSB;4為個位,權(quán)值最小,相當于LSB。那么真正以字節(jié)為單位考慮, 4字節(jié)數(shù)0x12345678里那個是MSB/LSB呢?

主機字節(jié)序分Big-Endian和Little-Endian兩種,定義為:

a. Little-Endian,又稱低字節(jié)優(yōu)先,是把LSB放在內(nèi)存低地址端,MSB在內(nèi)存高地址端。舉例,4字節(jié)數(shù)0x12345678在little-endian體系的內(nèi)存中存放(從地址0x1000開始)為:

b. Big-Endian,又稱高字節(jié)優(yōu)先,把MSB放在內(nèi)存低地址端,LSB放在內(nèi)存高地址端。0x12345678此時存放為:

big-endian沿地址增長方向先放高權(quán)位數(shù)字的方式恰好符合一般習慣(按照千,百,十,個位來書寫數(shù)字)。這也是為什么初學者變換endian時總覺得big-endian比較正常。

字節(jié)序問題有時會被擴大化,有人一碰到奇怪問題就懷疑字節(jié)序。其實它只存在于多字節(jié)數(shù)據(jù)在內(nèi)存中的解析,注意:1)多字節(jié)數(shù)據(jù);2)內(nèi)存中的排列。

    a. 多字節(jié)數(shù)據(jù)是指諸如long int short等需要多個字節(jié)存儲的數(shù)據(jù)類型,而象char等用一個字節(jié)表示的類型永遠不會有字節(jié)序問題。

    b. CPU通用寄存器都是整體操作,不存在單字節(jié)地址以及地址增長方向的概念,因此也沒有MSB/LSB在前或在后的問題,只有內(nèi)存中的多字節(jié)數(shù)據(jù)存儲才會有這兩種差異。從硬件角度看,CPU是直接通過數(shù)據(jù)總線連接內(nèi)存和CPU寄存器,這中間沒有額外字節(jié)序轉(zhuǎn)換的硬件開銷,只是不同總線連接方式導致了不同字節(jié)序,如下圖(from wiki):

信息交換中的字節(jié)序
當不同類型平臺通過某種媒介交換信息時需要考慮字節(jié)序問題,常見介質(zhì)主要指文件和網(wǎng)絡(luò)。通過文件或網(wǎng)絡(luò)讀取來自其它主機的多字節(jié)數(shù)據(jù)時,要警惕字節(jié)序問題。如x86和moto6800主機通過文件交換信息時,如果不轉(zhuǎn)換,數(shù)據(jù)處理就不匹配。在x86 VC下運行如下代碼:

  void main( )
    {
      FILE* fp;
      short a = 0x3132;   //為ASIIC碼’12’
      fp = fopen ("c:test.txt", "wb")
      fwrite(&a, sizeof(short), 1, fp);
      fclose(fp);
    }

代碼中a的值0x3132即'12’,由于x86為little endian體系,內(nèi)存中多字節(jié)LSB(這里即0x32)在前,所以運行后打開test.txt文件,內(nèi)容是'21'。把test.txt文件復制到moto6800機器上,再用fread把文件內(nèi)容讀到short變量里,得到的就不是0x3132而是0x3231了,數(shù)據(jù)就此被顛倒,后續(xù)處理完全錯誤。

假設(shè)我們制定了介質(zhì)層字節(jié)序標準(如big-endian),要通過軟件屏蔽不同endian體系的差異,需要兩步操作,一判斷endian類型:
typedef union {
      u16 a;
      u8 b[2];
    }ENDIAN;
    /* judge cpu is big endian(0) or small endian(1) */
    bool judge_endian(void)
    {
      ENDIAN t;
      t.a = 0x0001U;
      return (bool)(t.b[0] == 1);
    }

想想指針怎么做?

判斷完兩端主機的endian之后,要根據(jù)情況做相應(yīng)endian交換,即發(fā)送和接收任何一方只要不符合媒介層標準(big-endian),就要通過移位和位操作,在主機序和媒介序之間轉(zhuǎn)換。一方發(fā)送數(shù)據(jù)前要先將內(nèi)存數(shù)據(jù)由主機字節(jié)序轉(zhuǎn)換為傳輸介質(zhì)層的字節(jié)序,再發(fā)送出去,接收方收到數(shù)據(jù)后,要轉(zhuǎn)換為本地的主機字節(jié)序,再做后續(xù)處理。

比如TCP/IP協(xié)議的socket通信,基于socket通訊的雙方一般選擇Big-Endian為標準,又稱網(wǎng)絡(luò)字節(jié)序。socket定義了一組轉(zhuǎn)換函數(shù),用于多字節(jié)數(shù)在網(wǎng)絡(luò)字節(jié)序和主機字節(jié)序之間的轉(zhuǎn)換。htonl,htons用于主機序轉(zhuǎn)換到網(wǎng)絡(luò)序(如主機本身big endian,函數(shù)實際啥也不做);ntohl,ntohs把網(wǎng)絡(luò)序轉(zhuǎn)換到本機序(同樣)。因此傻瓜式做法,無論發(fā)送方主機字節(jié)序是什么,發(fā)送前都用htons或htonl將多字節(jié)數(shù)據(jù)轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序;同樣無論接收方主機字節(jié)序是什么,都用ntohs或ntohl把接收的網(wǎng)絡(luò)數(shù)據(jù)轉(zhuǎn)換為本地主機字節(jié)序。這樣有了網(wǎng)絡(luò)字節(jié)序標準,socket通信時,只需套用這幾個函數(shù)就能方便地抹平主機間的字節(jié)序差異。

問題在于如果雙方主機都與網(wǎng)絡(luò)字節(jié)序相反,本來是可以直接通信的,卻用htonl/ntohl等轉(zhuǎn)過去又轉(zhuǎn)回來,有點自找麻煩。這就要看軟件的預(yù)期運行環(huán)境,以及怎樣平衡軟件效率和多平臺通用性。

補充SOC內(nèi)部的字節(jié)序

soc中除主CPU外,一些外設(shè)中(如硬件媒體編解碼器)還包含內(nèi)部MCU,它們之間一般通過高速總線共享外部DDR,通過低速總線共享外設(shè)寄存器。這時如果雙方的endian屬性不匹配,對host cpu驅(qū)動及MCU上的固件編寫會造成一定困擾。

總結(jié)

真正理解大小端的本質(zhì)可能要從硬件系統(tǒng)角度,涉及CPU指令集、寄存器、總線以及硬件外設(shè)等。但對程序員來說,能夠了解字節(jié)序問題的存在范圍以及如何實現(xiàn)移植性更高的代碼,這就足夠了。

Tip:對于ARM等可配置的CPU,其編譯工具中會有big/little endian的選項,程序移植時也需要注意,如果跟系統(tǒng)設(shè)置不匹配,編譯得到的目標程序就無法運行。




以下課程可免費試聽C語言、電子PCB、STM32、LinuxFPGA、JAVA、安卓等。
想學習的你和我聯(lián)系預(yù)約就可以免費聽課了。
宋工企鵝號:3524-6590-88   Tel/WX:173--1795--1908



您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 可以免费在线看黄的网站 | 亚洲福利在线播放 | 色婷婷久久合月综 | 日本精品中文字幕 | 四虎影视2022入口网址 | 久久精品男人影院 | 九九热热九九 | 亚洲福利片 | 欧美不卡视频在线 | 91香蕉视频在线播放 | 狠狠综合久久久综合 | 韩国福利视频一区二区 | 欧美开嫩苞实拍视频在线观看 | 伊人婷婷在线 | 青青影视| 精品五夜婷香蕉国产线看观看 | 男女性高爱麻豆 | 六月婷婷在线观看 | 日韩精品免费一线在线观看 | 欧美日韩在线网站 | 青草久久伊人 | 一卡二卡四卡无人区免费 | 久久青草精品免费资源站 | 亚洲综合成人在线 | 婷婷综合网站 | 欧美日韩在线免费看 | 亚洲成年网站在线观看 | 麻豆视频免费网站 | 亚洲天堂999 | 免费特黄级夫费生活片 | 国产精品精品 | 免费观看四虎精品国产永久 | 一级特级女人18毛片免费视频 | 四虎永久在线观看 | 4虎影院在线观看 | 亚洲情区| 日本视频在线播放 | 日本中文字幕在线视频 | 两个人日本免费完整版在线观看1 | 色丁香婷婷 | 亚洲视频在线一区二区三区 |