Assembly Big和Little Endian表示法

2018-10-28 11:13 更新
在前面的章節(jié)本教程介紹了多字節(jié)數(shù)據(jù)的big和little endian表示法的概念。這一節(jié)將詳細(xì)介紹這一主題。讀者可能會回憶起endian表示法指的是一個多字節(jié)數(shù)據(jù)的單個字節(jié)元素儲存在內(nèi)存中的順序。Big endian是最直接的方法。它首先儲存的是最高有效字節(jié),然后是第二個有效字節(jié),以些類推。換句話說就是,大的位被首先儲存。Little endian以一個相反的順序來儲存字節(jié)(最小的有效字節(jié)最先被儲存)。x86家族的處理器使用的就是little endian表示法。


看一個例子:考慮雙字的表示。如果是big endian表示法,這些字節(jié)將像這樣儲存:12 34 56 78。如果是little endian表示法,這些字節(jié)就像這樣儲存:78 56 34 12。


現(xiàn)在讀者可能會這樣問自己:一個理智的芯片設(shè)計者怎么會使用little endian表示法?在Intel公司里的工程師是不是虐待狂?因為他們使廣大的程序員承受了這種混亂的表示法。像這樣,CPU看起來會因為在內(nèi)存中向后儲存字節(jié)而做額外的工作(而且從內(nèi)存中讀出時又要顛倒它們)。答案是CPU使用little endian格式讀寫內(nèi)存是不需要做額外的工作的。你必須認(rèn)識到CPU是由許多電子電路組成,簡單地工作在位值上。位(和字節(jié))在CPU中不需要有任何的順序的。


考慮2個字節(jié)的寄存器AX。這可以分解成單個字節(jié)的寄存器:AH和AL。在CPU中的電路保留了AH 和AL的值。在一個CPU中,電路是沒有任何順序的。也就是說,儲存AH的電路可以在儲存AL的電路前面或后面。mov指令復(fù)
制AX的值到內(nèi)存中,首先復(fù)制AL的值,接著是AH。CPU做這件事一點也沒有比先儲存AH難。


同樣的討論還可以用到一個字節(jié)的單個比特位上。它們在CPU電路(或就此而言,內(nèi)存)里并不真的有一定順序。但是,因為在CPU或內(nèi)存中單個的比特位并沒有編址,所以沒有辦法知道(或關(guān)心)CPU在內(nèi)部對它們是如

何排序的。


在圖3.4中的C代碼展示了如何確定CPU的Endian格式。p指針把word變量當(dāng)作兩個元素的字符數(shù)組來看待。因此,word在內(nèi)存里的第一個字節(jié)賦值給了p[0],而這取決于CPU的Endian格式。


確定Ending


什么時候需要在乎Little和Big Endian

對于典型的編程,CPU的Endian格式并不是很重要。它很重要的大多數(shù)時刻是在不同的計算機系統(tǒng)間傳輸二進制數(shù)據(jù)時。此時使用的要么是某種類型的物理數(shù)據(jù)媒介(例如一塊硬盤)要么是網(wǎng)絡(luò)。因為ASCII數(shù)據(jù)是單個字節(jié)的,Endian格式對它來說是沒有問題的。

所有的內(nèi)部的TCP/IP消息頭都以big endian的格式來儲存整形。(稱為網(wǎng)絡(luò)字節(jié)續(xù)). TCP/IP 庫提供了可移植處理Endian格式問題的方法的C函數(shù)。例如:htonl () 函數(shù)把一個雙字(或長整形)從主機格式轉(zhuǎn)換成了網(wǎng)絡(luò)格式。ntohl ()函數(shù)執(zhí)行一個相反的交換。對于一個big endian系統(tǒng),這兩個函數(shù)僅僅是無修改地返回它們的輸入。這就允許你寫出的網(wǎng)絡(luò)程序可以在任何的Endian格式系統(tǒng)上成功編譯和運行。

invert endian Function

圖3.5展示了一個轉(zhuǎn)換雙字Endian格式的C函數(shù)。486處理器提供了一個名為BSWAP的新的指令來交換任意32位寄存器中的字節(jié)。例如:

bswap      edx              ; 交換edx中的字節(jié)

這條指令不可以使用在16位的寄存器上。但是XCHG 指令可以用來交換可以分解成8位寄存器的16寄存器中的字節(jié)。例如:

xchg        ah,al             ; 交換ax中的字節(jié)

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號