您的位置:首页 > 其它

字节序Big Endian和Little Endian

2011-11-14 09:25 399 查看
开发中我们需要注意硬件上的内存存放的顺序,Big Endian和Little Endian,俗称大端还是小端

比如对32位4字节的值,0x00000001,如果是Little Endian,它是从低到高的存放顺序,先存低字节,后存高字节,

也就是说,它在内存中的存放顺序是 0x01 0x00 0x00 0x00(地址里面存放的值)。

图像数据一般是UInt8的像素类型,优化时我们常用一个策略是4个字节一起处理,转换成一个DWord类型(32位)再存放。

那么在将4个UInt8类型的值串成一个Dword类型时,为了保证在内存里面与原来单像素执行保持一致,就需要注意嵌入式系统是大端或小端。

假如,4个相邻的像素值分别是0x12,0x34,0x56,0x78,它们本身在内存里面排列是 0x12 0x34 0x56 0x78

如果用位移的方式把这4个像素值串成一个Dword值,0x12345678,那么在Little-Endian模式下,它在内存里面存放的就是 0x78 0x56 0x34 0x12,

与优化之前的值不一致,所以在Little-Endian模式下,就要把4个像素值串成 0x78563412,这样才能与优化前保持一致。

如果是Big-Endian模式,情况刚好与Little-Endian对等。

那么,如何判断嵌入式系统是大端还是小端呢?简单的办法就是取一个32位的数值,然后取它的地址里面的第一个字节,检查一下这个Byte值。

比如,long i = 0x01; char *ck = (char *)&i; (编译器要确保long是32位)

如果是Little-Endian,那么取首地址的第一个字节,*pk = 1,因为它先存低字节,后存高字节,也就是第一个字节的值是0x01。

而Big-Endian下,*pk = 0。这样就可以判断系统的大端和小端。不过每次执行的时候都需要一个if语句检查,是比较繁琐的。

所以,建议优化代码最好写成独立于这种判断的。

注意,上面用强制类型转换是行不通的,比如 char ck = (char)i; 这样得到的ck值仍然是1。
强制类型转换与类型本身在内存上的存放方式无关,它是将32位的0x00000001的低16位赋值给ck,舍弃高16位。
也就是说,它是对数据本身的高低位截取,而与存放方式无关。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: