网络字节序和主机字节序

谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。那么究竟什么是big endian,什么又是little endian呢?

    其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)。 
    用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示:

Big Endian

 低地址                              高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     12     |      34    |     56      |     78    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

低地址                                    高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     78     |      56    |     34      |     12    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    从上面两图可以看出,采用big endian方式存储数据是符合我们人类的思维习惯的。而little endian,!@#$%^&*,见鬼去吧 -_-|||

    为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。

    无独有偶,所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了下面四个转换字节序的宏。

    Intel 8080 和 Motorola 6800还有一个有趣的不同点:在两种微处理器中,LDA指令都是从一个特定的地址处装载到累加器。例如,在8080中,下列字节序列:

网络字节序和主机字节序_第1张图片

    将把存储在地址347Bh处的字节装载到累加器。现在把上述指令与6800的LDA指令相比较,后者采用称作6800的扩展地址模式:

网络字节序和主机字节序_第2张图片

    该字节序列把存储在地址7B34h处的字节装载到累加器A中。

    这种不同点是很微妙的。当然,你也可能认为它们的操作码不同:对8080来说是3Ah,对6800来说是B6h。但主要是这两种微处理器处理紧随操作码后的地址是不同的,8080认为低位在前,高位在后;6800则认为高位在前,低位在后。这种Intel和Motorola微处理器保存多字节数时的根本不同从没有得到解决。直到现在,Intel微处理器在保存多字节数时,仍是最低有效字节在前(即在最低存储地址处);而Motorola微处理器在保存多字节数时,仍是最高有效字节在前。

    这两种方法分别叫作little-endian(Intel方式)和big-endian(Motorola方式)。辩论这两种方式的优劣可能是很有趣的,不过在此之前,要知道术语big-endian来自于JonathanSwift的《Gulliver’sTravels》,指的是Lilliput和Blefuscu在每次吃鸡蛋前都要互相碰一下。这种辩论可能是无目的的。先不说哪种方法在本质上说是不是正确的,但这种差别的确当在基于little-endian和big-endian机器的系统之间共享信息时会带来附加的兼容性问题。
 

你可能感兴趣的:(网络字节序和主机字节序)