大端与小端
来源:互联网 发布:特蕾莎修女知乎 编辑:程序博客网 时间:2024/04/19 16:34
简单测试大端机器与小端机器
用例:
#include <iostream>bool isBigEnd(){ int a = 0x1234; char b = *(char *)&a; if (b == 0x12) return true; else return false;}bool isBigEnding(){ union { int a; char b; }obj; obj.a = 0x1234; if (obj.b == 0x12) return true; else return false;}int main(){ std::cout<<isBigEnd()<<std::endl; std::cout<<isBigEnding()<<std::endl; return 0;}
分析:
union 是利用了它的性质:
所有成员从低地址开始存放小端:0x0000 010x0001 000x0002 000x0003 00大端:0x0000 000x0001 000x0002 000x0003 01
详解大端与小端:
大端小端优劣:
大端与小端没有优劣之分,表示不同而已
小端在计算机内进行数值转换时候不需要移位。
而大端的符号位判定总是访问第一个字节就可以了。
数组在大端和小端机下的存储:
unsigned int value = 0x12345678;unsigned char buf[4];小端:buf[0] = 0x78 低位buf[1] = 0x56buf[2] = 0x34buf[3] = 0x12 高位大端:buf[0] = 0x12 高位buf[1] = 0x34buf[2] = 0x56buf[3] = 0x78 低位
常见的字节序:
一般的操作系统为小端, 而通信协议通常为大端。
常见CPU的字节序
Big Endian : PowerPC、IBM、SunLittle Endian : x86、DECARM既可以工作在大端模式,也可以工作在小端模式。
常见文件的字节序
Adobe PS – Big EndianBMP – Little EndianDXF(AutoCAD) – VariableGIF – Little EndianJPEG – Big EndianMacPaint – Big EndianRTF – Little Endian另外,Java和所有的网络通讯协议都是使用Big-Endian的编码。
如何进行大端与小端的转换呢?
16位字数据
#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8) | \ (( (uint16)(A) & 0x00ff) << 8))
32位双字数据
#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000) >> 24) | \ (( (uint32)(A) & 0x00ff0000) >> 8) | \ (( (uint32)(A) & 0x0000ff00) << 8) | \ (( (uint32)(A) & 0x000000ff) << 24) )
从软件的角度上,不同端模式的处理器进行数据传递时必须要考虑端模式的不同。如进行网络数据传递时,必须要考虑端模式的转换。在Socket接口编程中,以下几个函数用于大小端字节序的转换。
#include <arpa/inet.h>#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这类函数。
在对普通文件进行处理也需要考虑端模式问题。在大端模式的处理器下对文件的32,16位读写操作所得到的结果与小端模式的处理器不同。单纯从软件的角度理解上远远不能真正理解大小端模式的区别。事实上,真正的理解大小端模式的区别,必须要从系统的角度,从指令集,寄存器和数据总线上深入理解,大小端模式的区别。
转载自:
详解大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端 与 小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 大端与小端
- 动态规划初识
- WEB前端开发规范
- 自己常去的php试题网站
- react:undefined is not a function(this.State({flag:true,}))
- Android系统启动过程详解
- 大端与小端
- Getting this error message: dbModel read resource does not implement Zend_Db_Adapter_Abstract
- __thread
- Sping MVC 入门
- Html5 css reset
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- MFC写入文件的尴尬——让ofstream流行起来
- pthread_key_create函数
- servlet是线程安全的吗