|
Felix_herro于 2019-12-08 10:13:05 發(fā)布 137 分類專欄: 基礎(chǔ)知識(shí) 大端(Big Endian)/小端(Little Endian)字節(jié)序 參考文章: 阮一峰的網(wǎng)絡(luò)日志:理解字節(jié)序(圖片取自這里) Wikipedia:Endianness How to teach endian 大端字節(jié)序 與 小端字節(jié)序 在計(jì)算機(jī)中存在這樣一個(gè)問題:如何表示各種各樣的數(shù)據(jù)? 對于圖片等文件來說,有固定的格式文檔參考。 而對于整數(shù)來說,計(jì)算機(jī)應(yīng)該如何表示? 它的定義一定包括整數(shù)的大小、是否帶符號(hào)以及符號(hào)是什么、使用什么編碼格式表示(一般都是二進(jìn)制補(bǔ)碼),還有很重要的一點(diǎn):字節(jié)順序。 字節(jié)應(yīng)該從右向左讀還是從左向右讀呢? 這種讀取的順序就稱為:字節(jié)序(Byte-order / Endianness) 字節(jié)序分為兩種:大端字節(jié)序(Big Endian,從左向右)和小端字節(jié)序(Big Endian,從右向左) 換句話說 大端字節(jié)序高位字節(jié)在前,低位字節(jié)在后 小端字節(jié)序低位字節(jié)在前,高位字節(jié)在后 從一個(gè)十六進(jìn)制數(shù)字0x1234開始: 大端字節(jié)序 大端字節(jié)序是人類處理自然語言的做法,符合人類從左向右讀的閱讀習(xí)慣。 在這種規(guī)范下,十六進(jìn)制數(shù)會(huì)先存儲(chǔ)0x12作為高字節(jié),接下來存儲(chǔ)0x34。 小端字節(jié)序 低位字節(jié)在前,高位字節(jié)在后,也就是會(huì)以0x3412的形式存儲(chǔ)。 注意! 字節(jié)序是以字節(jié)為單位定義的,在一個(gè)字節(jié)中,兩個(gè)半字節(jié)仍然是以大端的形式存在。 疑問? 為什么要區(qū)分字節(jié)序?這樣復(fù)雜的意義是什么? image image 小端字節(jié)序的意義 小端字節(jié)序?qū)τ谶壿嬰娐犯行?。邏輯電路先處理低位字?jié)更有效率,因?yàn)橛?jì)算都是從低位開始的,計(jì)算機(jī)中的內(nèi)部處理邏輯都是使用小端字節(jié)序。 但是,大多數(shù)的網(wǎng)絡(luò)協(xié)議和文件格式都是大端字節(jié)序,這樣對用戶更加友好。 既然有區(qū)分,在使用時(shí)肯定要使用一定的解析規(guī)則,下面進(jìn)行簡要介紹。 字節(jié)序的處理 對于大端字節(jié)序,計(jì)算機(jī)先讀到的是高位字節(jié),后讀到的是低位字節(jié)。而小端字節(jié)序恰好相反。 字節(jié)序的處理:只有在讀取的時(shí)候才需要區(qū)分字節(jié)序,其他情況都不需要處理。 處理器讀取外部數(shù)據(jù)時(shí),必須知道數(shù)據(jù)的字節(jié)序才可以將其轉(zhuǎn)化成正確的值。接下來就可以正常使用這個(gè)值,不需要再考慮字節(jié)序。而向外部設(shè)備寫數(shù)據(jù)的時(shí)候,也不需要考慮字節(jié)序,正常寫入一個(gè)值即可,外部設(shè)備會(huì)自己處理字節(jié)序的問題。 例如,處理器讀入一個(gè)16位整數(shù) 大端字節(jié)序會(huì)按照如下方法轉(zhuǎn)值: x = buf[offset] * 256 + buf[offset+1]; 1 其中buf是整個(gè)數(shù)據(jù)塊在內(nèi)存中的起始地址,offset表示偏移量,也就是正在讀取的位置。第一個(gè)字節(jié)乘以256,再加上第二個(gè)字節(jié),就是大端字節(jié)序的值,這個(gè)式子可以用邏輯運(yùn)算符改寫。即: x = buf[offset]<<8 | buf[offset+1]; 1 編譯器總是將乘2的冪轉(zhuǎn)換成移位指令,這樣更加方便!左移八位,即在后面添加8個(gè)0。 小端字節(jié)序會(huì)按照如下方法轉(zhuǎn)值: x = buf[offset+1] * 256 + buf[offset]; 1 32位整數(shù)的求值公式也是一樣的 /* 大端字節(jié)序 */ i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24); /* 小端字節(jié)序 */ i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24); ———————————————— 版權(quán)聲明:本文為CSDN博主「Felix_herro」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/a1219532602/article/details/103442437 |
|
|