ARM中,Little endian & Big endian是何意思?

转载 2005年04月24日 19:04:00
这个标题中的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 

ARM 9:大端(Big-endian)和小端(Little-endian)区别

端模式(Endian)的这个词出自Jonathan Swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big Endian,从尖头开始将鸡...

大端序(big-edian)和 小端序(little-endian)

在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规...

架构实战经验一:架构设计中的大小端模式(little-big endian)

问题:架构设计中的大小端模式(little-big endian)        TX公司有一款有关智能手机应用的产品,该产品包括支持四个智能主流手机平台(symbian, windows mobi...

Big/Little Endian——字节存储顺序

转自:http://hi.baidu.com/qzfukwzlvgqsvzr/item/97aba6304e9d10f82784f4d9        嵌入式编程的面试或被面试的过程...
  • ustb_md
  • ustb_md
  • 2012年09月23日 23:38
  • 254

字节存储排序:大端(big endian)和小端(little)的判别及转换

当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en...

Big/Little endian

“任何你真正想得到的一定是值得坚持的!“

Big Endian &amp; Little Endian.pdf

  • 2011年10月09日 22:02
  • 52KB
  • 下载

Big-Endian, Little-Endian和字节码对齐方式(下)

bit fields(位域)指定struct,union和class(C++)中每个元素的位宽度,而不是按照该元素类型的缺省长度存储。由于位域中的元素不是缺省长度,因此在访问该元素时,不能用指针指向该...

little endian和big endian的概念解释

  • 2016年03月04日 22:30
  • 39KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ARM中,Little endian & Big endian是何意思?
举报原因:
原因补充:

(最多只允许输入30个字)