大端

大端

大端,指主要的部分;重要的端緒;大概。語出《禮記·禮運》:“故欲惡者,心之大端也。” 孔穎達 疏:“端謂頭緒。”

基本介紹

  • 中文名:大端
  • 外文名:important part
  • 拼音:dà duān
  • 注音:ㄉㄚˋ ㄉㄨㄢ
漢語詞語,基本字義,基本解釋,引證解釋,計算機用語,函式定義,文章一,文章二,

漢語詞語

基本字義

詞目:大端
拼音:dà duān
注音:ㄉㄚˋ ㄉㄨㄢ
英文:important part

基本解釋

[important part] 主要的部分;重要的端緒;大概。
故稱惡者,心之大端也。——《禮記·禮運》
今略舉大端,以喻吏民。——《後漢書·隗囂傳》

引證解釋

  1. 主要的端緒。
    禮記·禮運》:“故欲惡者,心之大端也。” 孔穎達 疏:“端謂頭緒。”
    毛澤東 《論持久戰》三五:“依目前條件來看,戰爭趨勢中的某些大端是可以指出的。”
  2. 謂事情的主要方面。
    後漢書·隗囂傳》:“ 新都侯 王莽 ,慢侮天地、悖道逆理……今略舉大端,以喻吏民。”
    白居易《三教論衡》:“略錄大端,不可具載。”
    梁啓超 《中國積弱溯源記》第二節:“以上六者,僅舉大端,自餘惡風,更仆難盡。”
  3. 本原。
    唐 陳子昂 《諫政理書》:“元氣,天地之始,萬物之祖,王政之大端也。”
  4. 大抵,大約。
    西遊記》第三五回:“那怪雖也能騰雲駕霧,不過是些法術,大端是凡胎未脫,到於寳貝里就化了。”
    《中國歌謠資料·小曲》:“河那邊一隻鳳,我怎么叫他不應?大端是我親人少緣分。”
  5. 舊指統治者認為正統的思想、理論,一般指儒家學說。在中國古代,儒家稱其他學說、學派為異端
    清劉智編撰《天方典禮》:“婚姻為人道之大端,古今聖凡,皆不能越其禮而廢其事也”。

計算機用語

端模式(Endian)的這個詞出自JonathanSwift書寫的《格列佛遊記》。這本書根據將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為BigEndian,從尖頭開始將雞蛋敲開的人被歸為LittileEndian。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開。在計算機業BigEndian和LittleEndian也幾乎引起一場戰爭。在計算機業界,Endian表示數據在存儲器中的存放順序。下文舉例說明在計算機中大小端模式的區別。
如果將一個32位的整數0x12345678存放到一個整型變數(int)中,這個整型變數採用大端或者小端模式在記憶體中的存儲由下表所示。為簡單起見,本書使用OP0表示一個32位數據的最高位元組MSB(Most Significant Byte),使用OP3表示一個32位數據最低位元組LSB(Least Significant Byte)。
;地址偏移
;大端模式
;小端模式
0x00
12(OP0)
78(OP3)
0x01
34(OP1)
56(OP2)
0x02
56(OP2)
34(OP1)
0x03
78(OP3)
12(OP0)
如果將一個16位的整數0x1234存放到一個短整型變數(short)中。這個短整型變數在記憶體中的存儲在大小端模式由下表所示。
;地址偏移
;大端模式
;小端模式
0x00
12(OP0)
34(OP1)
0x01
34(OP1)
12(OP0)
由上表所知,採用大小模式對數據進行存放的主要區別在於在存放的位元組順序,大端方式將高位存放在低地址,小端方式將高位存放在高地址。採用大端方式進行數據存放符合人類的正常思維,而採用小端方式進行數據存放利於計算機處理。到目前為止,採用大端或者小端進行數據存放,其孰優孰劣也沒有定論。
有的處理器系統採用了小端方式進行數據存放,如Intel的奔騰。有的處理器系統採用了大端方式進行數據存放,如IBM半導體和Freescale的PowerPC處理器。不僅對於處理器,一些外設的設計中也存在著使用大端或者小端進行數據存放的選擇。
因此在一個處理器系統中,有可能存在大端和小端模式同時存在的現象。這一現象為系統的軟硬體設計帶來了不小的麻煩,這要求系統設計工程師,必須深入理解大端和小端模式的差別。大端與小端模式的差別體現在一個處理器的暫存器,指令集,系統匯流排等各個層次中。
1.1.1 ;從軟體的角度理解端模式
從軟體的角度上,不同端模式的處理器進行數據傳遞時必須要考慮端模式的不同。如進行網路數據傳遞時,必須要考慮端模式的轉換。有過Socket接口編程經驗的程式設計師一定使用過以下幾個函式用於大小端位元組序的轉換。
¨ #define ntohs(n) //16位數據類型網路位元組順序主機位元組順序的轉換
¨ #define htons(n) //16位數據類型主機位元組順序到網路位元組順序的轉換
¨ #define ntohl(n) //32位數據類型網路位元組順序到主機位元組順序的轉換
¨ #define htonl(n) //32位數據類型主機位元組順序到網路位元組順序的轉換
其中網際網路使用的網路位元組順序採用大端模式進行編址,而主機位元組順序根據處理器的不同而不同,如PowerPC處理器使用大端模式,而Pentuim處理器使用小端模式。
大端模式處理器的位元組序到網路位元組序不需要轉換,此時ntohs(n)=n,ntohl =n;而小端模式處理器的位元組序到網路位元組必須要進行轉換,此時ntohs(n) = __swab16(n),ntohl =__swab32(n)。__swab16與__swab32

函式定義

如下所示。
#define ___swab16(x)
{
__u16 __x = (x);
((__u16)(
(((__u16)(__x) & (__u16)0x00ffU) << 8) |
(((__u16)(__x) & (__u16)0xff00U) >> 8)));
}
#define ___swab32(x)
{
__u32 __x = (x);
((__u32)(
(((__u32)(__x) & (__u32)0x000000ffUL) << 24) |
(((__u32)(__x) & (__u32)0x0000ff00UL) << 8) |
(((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) |
(((__u32)(__x) & (__u32)0xff000000UL) >> 24)));
}
PowerPC處理器提供了lwbrx,lhbrx,stwbrx,sthbrx四條指令用於處理位元組序的轉換以最佳化__swab16和__swap32這類函式。此外PowerPC處理器中的rlwimi指令也可以用來實現__swab16和__swap32這類函式。在LinuxPowerPC中,定義了一系列有關位元組序轉換的函式,其詳細定義在./include/asm-powerpc/byteorder.h檔案中。
程式設計師在對普通檔案進行處理也需要考慮端模式問題。在大端模式的處理器下對檔案的32,16位讀寫操作所得到的結果與小端模式的處理器不同。讀者單純從軟體的角度理解上遠遠不能真正理解大小端模式的區別。事實上,真正的理解大小端模式的區別,必須要從系統的角度,從指令集,暫存器和數據匯流排上深入理解,大小端模式的區別。

文章一

1.1.2 ;從系統的角度理解端模式
除了4.2.1節中,軟體上對不同端模式編程上的差異,處理器在硬體上也由於端模式問題在設計中有所不同。從系統的角度上看,端模式問題對軟體和硬體的設計帶來了不同的影響,當一個處理器系統中大小端模式同時存在時,必須要對這些不同端模式的訪問進行特殊的處理。
PowerPC處理器主導網路市場,可以說絕大多數的通信設備都使用PowerPC處理器進行協定處理和其他控制信息的處理,這也可能也是在網路上的絕大多數協定都採用大端編址方式的原因。因此在有關網路協定的軟體設計中,使用小端方式的處理器需要在軟體中處理端模式的轉變。而Pentium主導個人機市場,因此多數用於個人機的外設都採用小端模式,包括一些在網路設備中使用的PCI匯流排,Flash等設備,這也要求硬體工程師在硬體設計中注意端模式的轉換。
本書中的小端外設是指這種外設中的暫存器以小端方式進行存儲,如PCI設備的配置空間,NOR FLASH中的暫存器等等。
對於有些設備,如DDR顆粒,沒有以小端方式存儲的暫存器,因此從邏輯上講並不需要對端模式進行轉換。在設計中,只需要將雙方數據匯流排進行一一對應的互連,而不需要進行數據匯流排的轉換。
如果從實際套用的角度說,採用小端模式的處理器需要在軟體中處理端模式的轉換,因為採用小端模式的處理器在與小端外設互連時,不需要任何轉換。
而採用大端模式的處理器需要在硬體設計時處理端模式的轉換。大端模式處理器需要在暫存器,指令集,數據匯流排及數據匯流排與小端外設的連線等等多個方面進行處理,以解決與小端外設連線時的端模式轉換問題。
在暫存器和數據匯流排的位序定義上,基於大小端模式的處理器有所不同。
一個採用大端模式的32位處理器,如基於E500核心的MPC8541,將其暫存器的最高位msb(mostsignificant bit)定義為0,最低位lsb(lease significantbit)定義為31;而小端模式的32位處理器,將其暫存器的最高位定義為31,低位地址定義為0。
與此向對應,採用大端模式的32位處理器數據匯流排的最高位為0,最高位為31;採用小端模式的32位處理器的數據匯流排的最高位為31,最低位為0。如圖4.5所示。
OP0
OP1
OP2
OP3
OP0
OP1
OP2
OP3
31
0
31
0
;圖4.5大小端模式處理器的暫存器的定義
;大端模式處理器暫存器位序定義
;小端模式處理器暫存器位序定義
大小端模式處理器外部匯流排的位序也遵循著同樣的規律,根據所採用的數據匯流排是32位,16位和8位,大小端處理器外部匯流排的位序有所不同。
¨ 大端模式下32位數據匯流排的msb是第0位,MSB是數據匯流排的第0~7的欄位;而lsb是第31位,LSB是第24~31欄位。小端模式下32位匯流排的msb是第31位,MSB是數據匯流排的第31~24位,lsb是第0位,LSB是7~0欄位。
¨ 大端模式下16位數據匯流排的msb是第0位,MSB是數據匯流排的第0~7的欄位;而lsb是第15位,LSB是第8~15欄位。小端模式下16位匯流排的msb是第15位,MSB是數據匯流排的第15~7位,lsb是第0位,LSB是7~0欄位。
¨ 大端模式下8位數據匯流排的msb是第0位,MSB是數據匯流排的第0~7的欄位;而lsb是第7位,LSB是第0~7欄位。小端模式下8位匯流排的msb是第7位,MSB是數據匯流排的第7~0位,lsb是第0位,LSB是7~0欄位。
由上分析,我們可以得知對於8位,16位和32位寬度的數據匯流排,採用大端模式時數據匯流排的msb和MSB的位置都不會發生變化,而採用小端模式時數據匯流排的lsb和LSB位置也不會發生變化。
為此,大端模式的處理器對8位,16位和32位的記憶體訪問(包括外設的訪問)一般都包含第0~7欄位,即MSB。小端模式的處理器對8位,16位和32位的記憶體訪問都包含第7~0位,小端方式的第7~0欄位,即LSB。
由於大小端處理器的數據匯流排其8位,16位和32位寬度的數據匯流排的定義不同,因此需要分別進行討論在系統級別上如何處理端模式轉換。
在一個大端處理器系統中,需要處理大端處理器對小端外設的訪問。
1.1.2.1 大端處理器對32位小端外設進行訪問大端處理器採用32位匯流排與小端外設進行訪問時,大端處理器的32位數據匯流排的第0~7位用來處理OP0,第8~15位用來處理OP1,第16~23位用來處理OP2,第24~31位用來處理OP3。而32位的小端設備使用數據匯流排的第31~24位用來處理OP0,第23~16位用來處理OP1,第15~8位用來處理OP2,第7~0位用來處理OP3。
大端處理器,如MPC8541,使用stw,sth,stb和lwz,lhz,lbz指令對32位的外部設備進行訪問。在這些指令結束後,存放在外部設備的數據將被讀入MPC8541的通用暫存器中。為保證軟體的一致性,當訪問結束後,存放在通用暫存器的位元組序,即OP0,OP1,OP2和OP3必須要和存放在小端外設的位元組序一致。此時在使用大端處理器的數據匯流排連線小端外設時必須要進行一定的處理,按照某種拓撲結構連線以保證軟體的一致性。大端處理器數據匯流排與小端外設進行連線的拓撲結構如圖4.6所示。
OP0
OP1
OP2
OP3
31
31
0
7
8
15
16
23
24
24
23
16
15
8
7
0
;大端處理器的32位數據匯流排
;小端設備的32位匯流排接口
;圖4.6 大端處理器與小端外設的32位連線
OP0
OP1
OP2
OP3
如圖4.6所示,採用大端處理器訪問小端設備時,將各自的OP0~OP3欄位直接相連。在大端處理器的32位數據匯流排的最高位為0,最低位為31;而小端設備的最高位為31,最低位為0。因此硬體工程師在進行信號連線時需要將採用大端處理器的0~31位分別與小端設備的31~0位一一對應,進行互連。
1.1.2.2 大端處理器對8,16位小端外設進行訪問大端處理器使用8位,16位數據匯流排對8位,16位的小端外設進行連線。對於32位處理器,用來連線外設的匯流排一般是32位。因此體系結構工程師在進行大端處理器匯流排設計時有兩種選擇,是採用32位匯流排的高端部分(第0~15欄位)還是低端部分(第16~31欄位)連線小端設備。PowerPC處理器使用32位匯流排的高端部分,即數據匯流排的第0~15位連線16位的小端設備,使用0~7位連線8位的小端設備。
PowerPC處理器採用16位匯流排與16位的小端外設進行訪問時,PowerPC處理器的16位數據匯流排的第0~7位用來處理OP0,第8~15位用來處理OP1。而16位的小端設備使用數據匯流排的第15~8位用來處理OP0,第7~0位用來處理OP1。
PowerPC處理器採用8位匯流排與8位的小端外設進行訪問時,PowerPC處理器的8位數據匯流排的第0~7欄位用來處理OP0。而8位的小端設備使用數據匯流排的第7~0位用來處理OP1。大端處理器與小端外設的連線關係如圖4.7所示。
OP0
OP1
OP0
OP1
15
0
7
8
15
8
7
0
;大端處理器的8/16位數據匯流排
;小端設備的8/16位匯流排接口
;圖4.7 大端處理器與小端外設的8/16位連線
OP0
OP0
7
0
7
0
與32位匯流排接口類似,PowerPC處理器可以使用stw,sth,stb和lwz,lhz,lbz指令對32位的外部設備進行訪問,並將數據存放在相應的通用暫存器中。當訪問結束後,存放在通用暫存器的位元組序,即OP0,OP1必須要和存放在小端外設的位元組序一致。
PowerPC處理器對8位的小端外設進行訪問時,一個匯流排周期只能訪問8位數據,如果處理器使用stw或者lwz指令訪問8位的小端設備內的32位數據時,在數據匯流排上將OP0,OP1,OP2和OP3依次傳遞到PowerPC的通用暫存器中。
PowerPC處理器對16位的小端外設進行訪問時,一個匯流排周期只能訪問16位數據,如果處理器使用stw或者lwz指令訪問16位的小端設備內的32位數據時,在數據匯流排上將OP0~1和OP2~3依次傳遞到PowerPC的通用暫存器中。
PowerPC處理器使用sth或者lhz指令訪問16位的小端設備時,16位的小端設備將數據的第15~0位,傳遞到PowerPC處理器的匯流排的第0~15位,然後再將數據最終傳遞給相應的通用暫存器。這裡有許多讀者會感到困惑,因為為了保證軟體的一致性,PowerPC處理器使用lhz指令訪問16位的小端設備的16位暫存器時,需要將結果保存在通用暫存器的第16~31位,而不是0~15位。究竟PowerPC處理器是如何將系統匯流排中0~15位的數據搬移到暫存器的第16~31位中的呢?為此我們需要對lhz指令進行分析。
lhz rD,d(rA)
if rA = 0 then b ← 0
else b ← (rA)
EA ← b + EXTS(d)
rD ← (24)0 || MEM(EA,1)
由lhz指令的以上描述得知lhz指令將來自數據匯流排上的OP0與OP1直接存入暫存器的第16~31位,而將第0~15位直接清零。
PowerPC處理器使用stb或者lbz指令訪問8位的小端設備時,8位的小端設備將數據的第7~0位,傳遞到PowerPC處理器的匯流排的第0~7位,然後再將數據最終傳遞給相應的通用暫存器,lbz指令的描述如下所示。
lbz rD,d(rA)
if rA = 0 then b ← 0
else b ← (rA)
EA ← b + EXTS(d)
rD ← (24)0 || MEM(EA,1)
由lhz指令的以上描述得知lhz指令將來自數據匯流排上的OP0直接存入暫存器的第24~31位,而將第0~23位清零。

文章二

大端(big-endian)和小端(little-endian)<;轉>
2007-12-07 20:36
;補:x86機是小端(修改分區表時要注意),單片機一般為大端 今天碰一個關於位元組順序的問題,雖然看起來很簡單,但一直都沒怎么完全明白這個東西,索性就找了下資料,把它弄清楚. 因為現行的計算機都是以八位一個位元組為存儲單位,那么一個16位的整數,也就是C語言中的short,在記憶體中可能有兩種存儲順序big-endian和 litte-endian.考慮一個short整數0x3132(0x32是低位,0x31是高位),把它賦值給一個short變數,那么它在記憶體中的存 ;儲可能有如下兩種情況:
大端位元組(Big-endian):
----------------->>>>>>>>;記憶體地址增大方向
short變數地址
0x1000 0x1001
_____________________________| || 0x31 | 0x32|_______________ | ________________
高位位元組在低位位元組的前面,也就是高位在記憶體地址低的一端.可以這樣記住(大端->;高位->;在前->;正常的邏輯順序)
小端位元組(little-endian):
----------------->>>>>>>>;記憶體地址增大方向
short變數地址
0x1000 0x1001
_____________________________| || 0x32 | 0x31|________________ | ________________低位位元組在高位位元組的前面,也就是低位在記憶體地址低的一端.可以這樣記住(小端->;低位->;在前->;與正常邏輯順序相反)
可以做個實驗
在windows上下如下程式
#include <stdio.h>
#include <assert.h>
void main(void)
{ short test; FILE* fp; test = 0x3132; //(31ASⅡC碼的’1’,32ASⅡC碼的’2’)
if ((fp = fopen ("c:\\test.txt","wb")) == NULL)
assert(0); fwrite(&test,sizeof(short),1,fp); fclose(fp);
}
然後在C糟下打開test.txt檔案,可以看見內容是21,而test等於0x3132,可以明顯的看出來x86的位元組順序是低位在前.如果我們把這段 ;同樣的代碼放到(big-endian)的機器上執行,那么打出來的檔案就是12.這在本機中使用是沒有問題的.但當你把這個檔案從一個big- endian機器複製到一個little-endian機器上時就出現問題了.
如上述例子,我們在big-endian的機器上創建了這個test檔案,把其複製到little-endian的機器上再用fread讀到一個 short裡面,我們得到的就不再是0x3132而是0x3231了,這樣讀到的數據就是錯誤的,所以在兩個位元組順序不一樣的機器上傳輸數據時需要特別小 ;心位元組順序,理解了位元組順序在可以幫助我們寫出移植行更高的代碼.
正因為有位元組順序的差別,所以在網路傳輸的時候定義了所有位元組順序相關的數據都使用big-endian,BSD的代碼中定義了四個宏來處理:
#define ntohs(n) //網路位元組順序到主機位元組順序 n代表net,h代表host,s代表short
#define htons(n) //主機位元組順序到網路位元組順序 n代表net,h代表host,s代表short
#define ntohl(n) //網路位元組順序到主機位元組順序 n代表net,h代表host,l代表 long
#define htonl(n) //主機位元組順序到網路位元組順序 n代表net,h代表host,l代表 long
舉例說明下這其中一個宏的實現:#define sw16(x) \ ((short)(\ (((short)(x) & (short)0x00ffU) << 8) | \ (((short)(x) & (short)0xff00U) >> 8)))
這裡實現的是一個交換兩個位元組順序.其他幾個宏類似.
我們改寫一下上面的程式
#include <stdio.h>
#include <assert.h>
#define sw16(x) \
((short)(\ (((short)(x) & (short)0x00ffU) << 8) | \ (((short)(x) & (short)0xff00U) >> 8)))
// 因為x86下面是低位在前,需要交換一下變成網路位元組順序
#define htons(x) sw16(x)
void main(void)
{ short test; FILE* fp;
test = htons(0x3132); //(31ASⅡC碼的’1’,32ASⅡC碼的’2’) if ((fp = fopen ("c:\\test.txt","wb")) == NULL)
assert(0); fwrite(&test,sizeof(short),1,fp); fclose(fp);
}
如果在高位元組在前的機器上,由於與網路位元組順序一致,所以我們什麼都不乾就可以了,只需要把#define htons(x) sw16(x)宏替換為 #define htons(x) (x).
一開始我在理解這個問題時,總在想為什麼其他數據不用交換位元組順序?比如說我們write一塊buffer到檔案,最後終於想明白了,因為都是unsigned char類型一個位元組一個位元組的寫進去,這個順序是固定的,不存在位元組順序的問題,夠笨啊..
文章三:
big-endian和little-endian這兩個術語來自Jonathan Swift在十八世紀的嘲諷作品Gulliver’s Travels。Blefuscu帝國的國民被根據吃雞蛋的方式劃分為兩個部分:一部分在吃雞蛋的時候從雞蛋的大端(bigend)開始,而另一部分則從雞蛋的小端(little end)開始。
x86的CPU使用的是LE(Windows中稱為“主機位元組序”),而SocksAddr中使用的則是BE(就是“網路位元組序”),所以在使用網路編程時需要使用htns,htnl,nths,nthl來倒位元組序。
其實對彙編熟了就清楚了,慘,我的彙編很慘的LE little-endian 最符合人的思維的位元組序 地址低位存儲值的低位 地址高位存儲值的高位 怎么講是最符合人的思維的位元組序,是因為從人的第一觀感來說 低位值小,就應該放在記憶體地址小的地方,也即記憶體地址低位 反之,高位值就應該放在記憶體地址大的地方,也即記憶體地址高位 BE big-endian 最直觀的位元組序 地址低位存儲值的高位 地址高位存儲值的低位 為什麼說直觀,不要考慮對應關係 只需要把記憶體地址從左到右按照由低到高的順序寫出 把值按照通常的高位到低位的順序寫出 兩者對照,一個位元組一個位元組的填充進去 例子:在記憶體中雙字0x01020304(DWORD)的存儲方式 記憶體地址 4000 4001 4002 4003 LE 04 03 02 01 BE 01 02 03 04 MSDN中關於LE和BE的解釋Byte Ordering Byte ordering Meaning big-endian The most significant byte is on the left end of a word. little-endian The most significant byte is on the right end of a word. 這裡這個最重要的位元組可以解釋成值的最高位,如果換成是錢的話就是最值錢的那一位 比如我有1234元人民幣,最值錢的是1000元,最不值錢的是4元,那么這個1就是最重要的位元組
Big endian machine: It thinks the first byte it reads is the biggest.Little endian machine: It thinks the first byte it reads is the littlest.舉個例子,從記憶體地址0x0000開始有以下數據0x0000 0x120x0001 0x340x0002 0xab0x0003 0xcd如果我們去讀取一個地址為0x0000的四個位元組變數,若位元組序為big-endian,則讀出結果為0x1234abcd;若位元組序位little-endian,則讀出結果為0xcdab3412.如果我們將0x1234abcd寫入到以0x0000開始的記憶體中,則結果為 big-endian little-endian0x0000 0x12 0xcd0x0001 0x23 0xab0x0002 0xab 0x340x0003 0xcd 0x12x86系列CPU都是little-endian的位元組序。

相關詞條

熱門詞條

聯絡我們