分享
 
 
 

Little Endian & Big Endian

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这个标题中的Endian是什么意思呢?还是让我们先来看看下面的情况,这是内存中一个WORD值中的内容,那么这个WORD中的值是0x1234呢,还是0x3412 ?

low byte high byte

0x12 0x34

熟悉x86汇编的人立刻就知道这个值应为0x3412,很对,但在一些情况下,比如说你在SGI的机器上看到这种情况,则正好相反,0x1234才是正确答案,这与CPU内部处理数据的方式有关。这两种处理方式都存在于不同厂商生产的CPU之中,在上例中若此WORD值为0x3412的,我们称之为little-endian, 若为0x1234的,我们称之为big-endian,这是两种不同的byte orders。MSDN中有比较精确的定义如下:

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.

一般来说我们不用关心byte ordering的问题,但若要涉及跨平台之间的通信和资源共享,则不得不考虑这个问题了。也许你会说,我永远不会去用其它非x86的CPU,也许是这样,你甚至可以不必知道我们最常用的Intel,AMD等生产的x86的byte ordering是little-endian的,而且按现在的装机数量来看,可以说世界上绝大多数CPU是little-endian的,但多了解一些没有什么坏处,也许有用上的一天,实际若您要涉及到网络编程,了解一些还是有所帮助的,看完本文后您就应该知道为何socket编程中为何要用到如 ntohl, htonl, ntohs, htons这几个看起来名字似乎怪怪的API了,也很容易理解这些函数名的意义了。

假设我们要在不同byte ordering的机器之间传输和交换数据,那该怎么办呢,有两个方法,一是全部转换成文本来传输(如XML使用的),另一个方法两方都按照某一方的byte order,这时就涉及到了不同byte order之间相互转换的问题(网络传输标准如TCP/IP采用第二种方法并且由于历史的原因,byte ordering是big-endian的)。两种之间该如何转换呢?方法有很多,我们可以先看看MFC中在处理serialize的代码中所用的方法(List), 虽然代码应该是高效易读的, 但我个人并不喜欢它, 原因是我觉得这不是一种通用优美的方法.下面列出的是我自己写的转换的代码:

template

F3D_INLINE T ConvertEndian(T t)

{

T tResult = 0;

for (int I = 0; I < sizeof(T); ++ I)

{

tResult <<= 8;

tResult |= (t & 0xFF) ;

t >>= 8;

}

return tResult;

}

原理非常简单,交换字节顺序,我就不多说了,当然这个写法并不是快速的, 只是通用的(我没条件试, 若有不对之处请指出), 若要快速的代码,可以在不同platform上用与platform相关的代码, 如在PowerPC上有 "load word byte-reversed indexed" (lwbrx) 和 "load halfword byte-reversed indexed" (lhbrx) 指令, 在x86上还可用BSWAP单个汇编指令等,在类型上专为int16, int32写的通用的代码也可以比这快得多.

当然如果在byte ordering相同的情况下,应该不必用这个转换函数,所以我们可以定义一个宏来处理不同的byte ordering,也可以在运行时测试byte ordering, 下面的代码给出了一个简单的测试方法。

// Test for endianness.

F3D_INLINE bool IsLittleEndian(void)

{

DWORD dwTestValue = 0x12345678L;

return (*((BYTE*)&dwTestValue) == 0x78);

}

但是float比较怪,有可能所涉及到不仅仅是byte order的问题,因为有些平台如Alpha不使用IEEE的浮点格式,还得自己转换。当然同上,其它的方法一是将所用的float用文本方式输入输出,另一个办法是在某些情况下可将其转换成定点数再处理,这里我不再深入。

如果是读写第三方已经指定byte order的文件或数据流,比如说读SGI的位图文件格式,则可以直接自行按指定的byte order拼起来,不必考虑host机是何种byte ordering。下面我给出相应的代码:

// Read a little-endian TYPE from address

template

F3D_INLINE T GetLittleEndian(const BYTE* pBuf)

{

T tResult = 0;

pBuf += sizeof(T) - 1;

for (int I = 0; I < sizeof(T); ++ I)

{

tResult <<= 8;

tResult |= *pBuf --;

}

return tResult;

}

// Read a big-endian TYPE from address

template

F3D_INLINE T GetBigEndian(const BYTE* pBuf)

{

T tResult = 0;

for (int I = 0; I < sizeof(T); ++ I)

{

tResult <<= 8;

tResult |= *pBuf ++;

}

return tResult;

}

// Set a little-endian TYPE on a address

template

F3D_INLINE void SetLittleEndian(BYTE* pBuf, T t)

{

for (int I = 0; I < sizeof(T); ++ I)

{

*pBuf ++ = BYTE(t & 0xFF);

t >>= 8;

}

}

// Set a big-endian T on a address

template

F3D_INLINE void SetBigEndian(BYTE* pBuf, T t)

{

pBuf += sizeof(T) - 1;

for (int I = 0; I < sizeof(T); ++ I)

{

*pBuf -- = BYTE(t & 0xFF);

t >>= 8;

}

}

从上文可以看出,byte order挺简单的,一般应用中可能也用不上,但若您对写跨平台的程序有兴趣,则一定要了解的比较清楚才行。以上代码都是从实际使用的源码中取下来的。

附:常见Processor, OS的byte ordering情况

Processor OS Order

x86 (Intel, AMD, … ) All little-endian

DEC Alpha All little-endian

HP-PA NT little-endian

HP-PA UNIX big-endian

SUN SPARC All? big-endian

MIPS NT little-endian

MIPS UNIX big-endian

PowerPC NT little-endian

PowerPC non-NT big-endian

RS/6000 UNIX big-endian

Motorola m68k All big-endian

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有